Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 1 | /* This is a demo of using xoslib with Marionette |
| 2 | |
| 3 | The main window is split into two halves. The left half has a CollectionView |
| 4 | (SliceListView) that lists all slices the user has access to. The right half |
| 5 | has an ItemView (SliceDetailView) that allows the user to edit the |
| 6 | name and description of a slice, as well as a <Save> button to save it. |
| 7 | */ |
| 8 | |
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 9 | SliceEditorApp = new Marionette.Application(); |
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 10 | |
| 11 | SliceEditorApp.addRegions({ |
| 12 | sliceList: "#sliceEditorList", |
| 13 | sliceDetail: "#sliceEditorDetail", |
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 14 | }); |
| 15 | |
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 16 | /* SliceListItemView: This is the item view that is used by SliceListView to |
| 17 | display slice names. |
| 18 | */ |
| 19 | |
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 20 | SliceEditorApp.SliceListItemView = Marionette.ItemView.extend({ |
| 21 | template: "#sliceeditor-listitem-template",
|
| 22 | tagName: 'li',
|
| 23 | className: 'sliceeditor-listitem',
|
| 24 |
|
| 25 | events: {"click": "changeSlice"},
|
| 26 |
|
| 27 | changeSlice: function(e) {
|
| 28 | e.preventDefault();
|
| 29 | e.stopPropagation();
|
| 30 |
|
| 31 | if (SliceEditorApp.sliceDetail.currentView && SliceEditorApp.sliceDetail.currentView.dirty) {
|
| 32 | if (!confirm("discard current changes?")) {
|
| 33 | return;
|
| 34 | }
|
| 35 | }
|
| 36 |
|
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 37 | /* create a new SliceDetailView and set the sliceDetail region to
|
| 38 | display it.
|
| 39 | */
|
| 40 |
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 41 | var sliceDetailView = new SliceEditorApp.SliceDetailView({
|
| 42 | model: this.model,
|
| 43 | });
|
| 44 | SliceEditorApp.sliceDetail.show(sliceDetailView);
|
| 45 | },
|
| 46 | });
|
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 47 |
|
| 48 | /* SliceListView: This displays a list of slice names.
|
| 49 | */
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 50 | |
| 51 | SliceEditorApp.SliceListView = Marionette.CollectionView.extend({ |
| 52 | tagName: "ul",
|
| 53 | childView: SliceEditorApp.SliceListItemView,
|
| 54 |
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 55 | initialize: function() {
|
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 56 | /* CollectionViews don't automatically listen for change events, but we
|
| 57 | want to, so we pick up changes from the DetailView, and we pick up
|
| 58 | changes from the server.
|
| 59 | */
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 60 | this.listenTo(this.collection, 'change', this._renderChildren);
|
| 61 | },
|
| 62 |
|
| 63 | attachHtml: function(compositeView, childView, index) {
|
| 64 | // The REST API will let admin users see everything. For the developer
|
| 65 | // view we still want to hide slices we are not members of.
|
| 66 | if (childView.model.get("sliceInfo").roles.length == 0) {
|
| 67 | return;
|
| 68 | }
|
| 69 | SliceEditorApp.SliceListView.__super__.attachHtml(compositeView, childView, index);
|
| 70 | },
|
| 71 | });
|
| 72 |
|
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 73 | /* SliceDetailView: Display the slice and allow it to be edited */
|
| 74 |
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 75 | SliceEditorApp.SliceDetailView = Marionette.ItemView.extend({
|
| 76 | template: "#sliceeditor-sliceedit-template",
|
| 77 | tagName: 'div',
|
| 78 |
|
| 79 | events: {"click button.js-submit": "submitClicked",
|
| 80 | "change input": "inputChanged"},
|
| 81 |
|
Scott Baker | ac868ac | 2014-07-15 10:29:17 -0700 | [diff] [blame^] | 82 | /* inputChanged is watching the onChange events of the input controls. We
|
| 83 | do this to track when this view is 'dirty', so we can throw up a warning
|
| 84 | if the user tries to change his slices without saving first.
|
| 85 | */
|
| 86 |
|
Scott Baker | bb4961d | 2014-07-14 18:10:53 -0700 | [diff] [blame] | 87 | inputChanged: function(e) {
|
| 88 | this.dirty = true;
|
| 89 | },
|
| 90 |
|
| 91 | submitClicked: function(e) {
|
| 92 | e.preventDefault();
|
| 93 | var data = Backbone.Syphon.serialize(this);
|
| 94 | this.model.save(data);
|
| 95 | this.dirty = false;
|
| 96 | },
|
| 97 | });
|
| 98 | |
| 99 | SliceEditorApp.on("start", function() { |
| 100 | var sliceListView = new SliceEditorApp.SliceListView({ |
| 101 | collection: xos.slicesPlus
|
| 102 | });
|
| 103 | SliceEditorApp.sliceList.show(sliceListView);
|
| 104 | xos.slicesPlus.startPolling();
|
| 105 | }); |
| 106 | |
| 107 | $(document).ready(function(){ |
| 108 | SliceEditorApp.start(); |
| 109 | }); |
| 110 | |