[view/data-explorer][m]: (refs #14) introduce ability to change number of rows viewed.

* This also necessitated a nice refactor whereby DataExplorer subviews running off a common Backbone Collection (DocumentList) re-rendering themselves in response to changes in that Collection.
This commit is contained in:
rgrp
2011-12-15 16:13:43 +00:00
parent 6e80e20f61
commit 8b9c76fd29
3 changed files with 52 additions and 18 deletions

View File

@@ -239,3 +239,13 @@ span.tooltip-status {
right: 0px; right: 0px;
background: white; background: white;
} }
.nav-pagination {
display: inline;
float: right;
list-style-type: none;
}
.nav-pagination input {
width: 40px;
}

View File

@@ -8,6 +8,10 @@ var my = {};
// A Dataset model. // A Dataset model.
my.Dataset = Backbone.Model.extend({ my.Dataset = Backbone.Model.extend({
__type__: 'Dataset', __type__: 'Dataset',
initialize: function() {
this.currentDocuments = new my.DocumentList();
},
getLength: function() { getLength: function() {
return this.rowCount; return this.rowCount;
}, },
@@ -19,13 +23,14 @@ my.Dataset = Backbone.Model.extend({
// this does not fit very well with Backbone setup. Backbone really expects you to know the ids of objects your are fetching (which you do in classic RESTful ajax-y world). But this paradigm does not fill well with data set up we have here. // this does not fit very well with Backbone setup. Backbone really expects you to know the ids of objects your are fetching (which you do in classic RESTful ajax-y world). But this paradigm does not fill well with data set up we have here.
// This also illustrates the limitations of separating the Dataset and the Backend // This also illustrates the limitations of separating the Dataset and the Backend
getRows: function(numRows, start) { getRows: function(numRows, start) {
var self = this;
var dfd = $.Deferred(); var dfd = $.Deferred();
this.backend.getRows(this.id, numRows, start).then(function(rows) { this.backend.getRows(this.id, numRows, start).then(function(rows) {
var docs = _.map(rows, function(row) { var docs = _.map(rows, function(row) {
return new my.Document(row); return new my.Document(row);
}); });
var docList = new my.DocumentList(docs); self.currentDocuments.reset(docs);
dfd.resolve(docList); dfd.resolve(self.currentDocuments);
}); });
return dfd.promise(); return dfd.promise();
} }

View File

@@ -16,19 +16,38 @@ my.DataExplorer = Backbone.View.extend({
<input type="radio" id="nav-graph" name="nav-toggle" value="graph" /> \ <input type="radio" id="nav-graph" name="nav-toggle" value="graph" /> \
<label for="nav-graph">Graph</label> \ <label for="nav-graph">Graph</label> \
</span> \ </span> \
<ul class="nav-pagination"> \
<li><form class="display-count"><label for="per-page">Display count</label> <input name="displayCount" type="text" value="{{displayCount}}" /></form></li> \
</ul> \
</div> \ </div> \
<div class="data-view-container"></div> \ <div class="data-view-container"></div> \
', ',
events: { events: {
'change input[name="nav-toggle"]': 'navChange' 'change input[name="nav-toggle"]': 'navChange',
'submit form.display-count': 'displayCountUpdate'
}, },
initialize: function() { initialize: function(options) {
this.el = $(this.el); this.el = $(this.el);
this.config = options.config || {};
_.extend(this.config, {
displayCount: 10
});
this.draw();
},
displayCountUpdate: function(e) {
e.preventDefault();
this.config.displayCount = parseInt(this.el.find('input[name="displayCount"]').val());
this.draw();
},
draw: function() {
var self = this;
this.el.empty();
this.render(); this.render();
this.$dataViewContainer = this.el.find('.data-view-container'); this.$dataViewContainer = this.el.find('.data-view-container');
var self = this;
// retrieve basic data like headers etc // retrieve basic data like headers etc
// note this.model and dataset returned are the same // note this.model and dataset returned are the same
this.model.fetch().then(function(dataset) { this.model.fetch().then(function(dataset) {
@@ -42,11 +61,13 @@ my.DataExplorer = Backbone.View.extend({
self.flotGraph.el.hide(); self.flotGraph.el.hide();
self.$dataViewContainer.append(self.dataTable.el) self.$dataViewContainer.append(self.dataTable.el)
self.$dataViewContainer.append(self.flotGraph.el); self.$dataViewContainer.append(self.flotGraph.el);
self.model.getRows(self.config.displayCount);
}); });
}, },
render: function() { render: function() {
$(this.el).html($(this.template)); var template = $.mustache(this.template, this.config);
$(this.el).html(template);
}, },
navChange: function(e) { navChange: function(e) {
@@ -75,12 +96,11 @@ my.DataTable = Backbone.View.extend({
className: "data-table-container", className: "data-table-container",
initialize: function() { initialize: function() {
this.el = $(this.el);
var self = this; var self = this;
this.model.getRows().then(function(documentList) { this.el = $(this.el);
self._currentDocuments = documentList; _.bindAll(this, 'render');
self.render() this.model.currentDocuments.bind('add', this.render);
}); this.model.currentDocuments.bind('reset', this.render);
this.state = {}; this.state = {};
// this is nasty. Due to fact that .menu element is not inside this view but is elsewhere in DOM // this is nasty. Due to fact that .menu element is not inside this view but is elsewhere in DOM
$('.menu li a').live('click', function(e) { $('.menu li a').live('click', function(e) {
@@ -235,7 +255,7 @@ my.DataTable = Backbone.View.extend({
, htmls = $.mustache(template, this.toTemplateJSON()) , htmls = $.mustache(template, this.toTemplateJSON())
; ;
this.el.html(htmls); this.el.html(htmls);
this._currentDocuments.forEach(function(doc) { this.model.currentDocuments.forEach(function(doc) {
var tr = $('<tr />'); var tr = $('<tr />');
self.el.find('tbody').append(tr); self.el.find('tbody').append(tr);
var newView = new my.DataTableRow({ var newView = new my.DataTableRow({
@@ -342,18 +362,17 @@ my.FlotGraph = Backbone.View.extend({
', ',
initialize: function(options, chart) { initialize: function(options, chart) {
var self = this;
this.el = $(this.el); this.el = $(this.el);
_.bindAll(this, 'render');
this.model.currentDocuments.bind('add', this.render);
this.model.currentDocuments.bind('reset', this.render);
this.chart = chart; this.chart = chart;
this.chartConfig = { this.chartConfig = {
group: null, group: null,
series: [], series: [],
graphType: 'line' graphType: 'line'
}; };
var self = this;
this.model.getRows().then(function(documentList) {
self._currentDocuments = documentList;
self.render()
});
}, },
events: { events: {
@@ -412,7 +431,7 @@ my.FlotGraph = Backbone.View.extend({
if (this.chartConfig) { if (this.chartConfig) {
$.each(this.chartConfig.series, function (seriesIndex, field) { $.each(this.chartConfig.series, function (seriesIndex, field) {
var points = []; var points = [];
$.each(self._currentDocuments.models, function (index, doc) { $.each(self.model.currentDocuments.models, function (index, doc) {
var x = doc.get(self.chartConfig.group); var x = doc.get(self.chartConfig.group);
var y = doc.get(field); var y = doc.get(field);
if (typeof x === 'string') { if (typeof x === 'string') {