diff --git a/src/model.js b/src/model.js index 3253ec7d..5f834cad 100644 --- a/src/model.js +++ b/src/model.js @@ -381,6 +381,13 @@ my.FacetList = Backbone.Collection.extend({ model: my.Facet }); +// ## Object State +// +// Convenience Backbone model for storing (configuration) state of objects like Views. +my.ObjectState = Backbone.Model.extend({ +}); + + // ## Backend registry // // Backends will register themselves by id into this registry diff --git a/src/view-grid.js b/src/view-grid.js index 4334b159..02082455 100644 --- a/src/view-grid.js +++ b/src/view-grid.js @@ -20,8 +20,12 @@ my.DataGrid = Backbone.View.extend({ this.model.currentDocuments.bind('add', this.render); this.model.currentDocuments.bind('reset', this.render); this.model.currentDocuments.bind('remove', this.render); - this.state = {}; - this.hiddenFields = []; + this.tempState = {}; + var state = _.extend({ + hiddenFields: [] + }, modelEtc.state + ); + this.state = new recline.Model.ObjectState(state); }, events: { @@ -47,11 +51,11 @@ my.DataGrid = Backbone.View.extend({ // Column and row menus onColumnHeaderClick: function(e) { - this.state.currentColumn = $(e.target).closest('.column-header').attr('data-field'); + this.tempState.currentColumn = $(e.target).closest('.column-header').attr('data-field'); }, onRowHeaderClick: function(e) { - this.state.currentRow = $(e.target).parents('tr:first').attr('data-id'); + this.tempState.currentRow = $(e.target).parents('tr:first').attr('data-id'); }, onRootHeaderClick: function(e) { @@ -59,7 +63,7 @@ my.DataGrid = Backbone.View.extend({ {{#columns}} \
  • Show column: {{.}}
  • \ {{/columns}}'; - var tmp = $.mustache(tmpl, {'columns': this.hiddenFields}); + var tmp = $.mustache(tmpl, {'columns': this.state.get('hiddenFields')}); this.el.find('.root-header-menu .dropdown-menu').html(tmp); }, @@ -67,15 +71,15 @@ my.DataGrid = Backbone.View.extend({ var self = this; e.preventDefault(); var actions = { - bulkEdit: function() { self.showTransformColumnDialog('bulkEdit', {name: self.state.currentColumn}); }, + bulkEdit: function() { self.showTransformColumnDialog('bulkEdit', {name: self.tempState.currentColumn}); }, facet: function() { - self.model.queryState.addFacet(self.state.currentColumn); + self.model.queryState.addFacet(self.tempState.currentColumn); }, facet_histogram: function() { - self.model.queryState.addHistogramFacet(self.state.currentColumn); + self.model.queryState.addHistogramFacet(self.tempState.currentColumn); }, filter: function() { - self.model.queryState.addTermFilter(self.state.currentColumn, ''); + self.model.queryState.addTermFilter(self.tempState.currentColumn, ''); }, transform: function() { self.showTransformDialog('transform'); }, sortAsc: function() { self.setColumnSort('asc'); }, @@ -86,7 +90,7 @@ my.DataGrid = Backbone.View.extend({ var doc = _.find(self.model.currentDocuments.models, function(doc) { // important this is == as the currentRow will be string (as comes // from DOM) while id may be int - return doc.id == self.state.currentRow; + return doc.id == self.tempState.currentRow; }); doc.destroy().then(function() { self.model.currentDocuments.remove(doc); @@ -105,7 +109,7 @@ my.DataGrid = Backbone.View.extend({ var view = new my.ColumnTransform({ model: this.model }); - view.state = this.state; + view.state = this.tempState; view.render(); $el.empty(); $el.append(view.el); @@ -131,17 +135,20 @@ my.DataGrid = Backbone.View.extend({ setColumnSort: function(order) { var sort = [{}]; - sort[0][this.state.currentColumn] = {order: order}; + sort[0][this.tempState.currentColumn] = {order: order}; this.model.query({sort: sort}); }, hideColumn: function() { - this.hiddenFields.push(this.state.currentColumn); + var hiddenFields = this.state.get('hiddenFields'); + hiddenFields.push(this.tempState.currentColumn); + this.state.set({hiddenFields: hiddenFields}); this.render(); }, showColumn: function(e) { - this.hiddenFields = _.without(this.hiddenFields, $(e.target).data('column')); + var hiddenFields = _.without(this.state.get('hiddenFields'), $(e.target).data('column')); + this.state.set({hiddenFields: hiddenFields}); this.render(); }, @@ -197,7 +204,7 @@ my.DataGrid = Backbone.View.extend({ render: function() { var self = this; this.fields = this.model.fields.filter(function(field) { - return _.indexOf(self.hiddenFields, field.id) == -1; + return _.indexOf(self.state.get('hiddenFields'), field.id) == -1; }); var htmls = $.mustache(this.template, this.toTemplateJSON()); this.el.html(htmls); @@ -211,7 +218,7 @@ my.DataGrid = Backbone.View.extend({ }); newView.render(); }); - this.el.toggleClass('no-hidden', (self.hiddenFields.length === 0)); + this.el.toggleClass('no-hidden', (self.state.get('hiddenFields').length === 0)); return this; } }); diff --git a/src/view.js b/src/view.js index cff9b9d3..26cb51f0 100644 --- a/src/view.js +++ b/src/view.js @@ -108,12 +108,8 @@ my.DataExplorer = Backbone.View.extend({ }) }]; } - this.state = { - dataset: null, - queryState: this.model.queryState.toJSON(), - currentView: null - }; - this._setupStateManagement(); + this.state = {}; + this._setupState(); // this must be called after pageViews are created this.render(); @@ -237,15 +233,21 @@ my.DataExplorer = Backbone.View.extend({ } }, - _setupStateManagement: function() { + _setupState: function() { var self = this; + this.state = { + dataset: null, + query: this.model.queryState.toJSON(), + currentView: null + }; this.model.queryState.bind('change', function() { self.state.queryState = this.model.queryState.toJSON(); }); _.each(this.pageViews, function(pageView) { if (pageView.view.state && pageView.view.state.bind) { + self.state['view-' + pageView.id] = pageView.view.state.toJSON(); pageView.view.state.bind('change', function() { - self.state['view-' + pageView.view.id] = pageView.view.state.toJSON(); + self.state['view-' + pageView.id] = pageView.view.state.toJSON(); }); } }); diff --git a/test/view-grid.test.js b/test/view-grid.test.js index be848f22..19031458 100644 --- a/test/view-grid.test.js +++ b/test/view-grid.test.js @@ -1,6 +1,6 @@ (function ($) { -module("View - Grid"); +module("View - DataGrid"); function assertPresent(selector) { var found = $(selector); @@ -12,7 +12,7 @@ function assertNotPresent(selector) { equal(found.length, 0); } -test('DataGrid - menu - hideColumn', function () { +test('menu - hideColumn', function () { var dataset = Fixture.getDataset(); var view = new recline.View.DataGrid({ model: dataset @@ -24,6 +24,24 @@ test('DataGrid - menu - hideColumn', function () { var hideColumn = view.el.find('.column-header[data-field="x"] a[data-action="hideColumn"]'); hideColumn.trigger('click'); assertNotPresent('.column-header[data-field="x"]'); + + // also test a bit of state + deepEqual(view.state.toJSON(), {hiddenFields: ['x']}); + view.remove(); +}); + +test('state', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.DataGrid({ + model: dataset, + state: { + hiddenFields: ['z'] + } + }); + $('.fixtures .test-datatable').append(view.el); + view.render(); + assertPresent('.column-header[data-field="x"]'); + assertNotPresent('.column-header[data-field="z"]'); view.remove(); }); diff --git a/test/view.test.js b/test/view.test.js index 73aeacce..00c26267 100644 --- a/test/view.test.js +++ b/test/view.test.js @@ -24,8 +24,9 @@ test('getState', function () { el: $el }); var state = explorer.getState(); - ok(state.queryState); - equal(state.queryState.size, 100); + ok(state.query); + equal(state.query.size, 100); + deepEqual(state['view-grid'].hiddenFields, []); $el.remove(); });