From 76eb296a945b59eba0df525197c8f88ff5b88b2f Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Fri, 18 May 2012 00:54:31 +0100 Subject: [PATCH] [build][xs]: standard build of recline.js. --- recline.js | 102 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/recline.js b/recline.js index 261de327..80a7b909 100644 --- a/recline.js +++ b/recline.js @@ -612,7 +612,7 @@ my.composeQueryString = function(queryParams) { if (typeof(value) === 'object') { value = JSON.stringify(value); } - items.push(key + '=' + value); + items.push(key + '=' + encodeURIComponent(value)); }); queryString += items.join('&'); return queryString; @@ -1177,8 +1177,9 @@ my.Grid = Backbone.View.extend({ // ====================================================== // #### Templating template: ' \ +
\ \ - \ + \ \ {{#notEmpty}} \ \ {{/notEmpty}} \ {{#fields}} \ - \ {{/fields}} \ + \ \ \ - \ + \
\ @@ -1191,7 +1192,7 @@ my.Grid = Backbone.View.extend({ \ + \
\ \
\ +
\ ', toTemplateJSON: function() { + var self = this; var modelData = this.model.toJSON(); modelData.notEmpty = ( this.fields.length > 0 ); // TODO: move this sort of thing into a toTemplateJSON method on Dataset? - modelData.fields = _.map(this.fields, function(field) { return field.toJSON(); }); + modelData.fields = _.map(this.fields, function(field) { + return field.toJSON(); + }); + // last header width = scroll bar - border (2px) */ + modelData.lastHeaderWidth = this.scrollbarDimensions.width - 2; return modelData; }, render: function() { @@ -1228,6 +1236,20 @@ my.Grid = Backbone.View.extend({ this.fields = this.model.fields.filter(function(field) { return _.indexOf(self.state.get('hiddenFields'), field.id) == -1; }); + this.scrollbarDimensions = this.scrollbarDimensions || this._scrollbarSize(); // skip measurement if already have dimensions + var numFields = this.fields.length; + // compute field widths (-20 for first menu col + 10px for padding on each col and finally 16px for the scrollbar) + var fullWidth = self.el.width() - 20 - 10 * numFields - this.scrollbarDimensions.width; + var width = parseInt(Math.max(50, fullWidth / numFields)); + var remainder = fullWidth - numFields * width; + _.each(this.fields, function(field, idx) { + // add the remainder to the first field width so we make up full col + if (idx == 0) { + field.set({width: width+remainder}); + } else { + field.set({width: width}); + } + }); var htmls = $.mustache(this.template, this.toTemplateJSON()); this.el.html(htmls); this.model.currentDocuments.forEach(function(doc) { @@ -1240,8 +1262,25 @@ my.Grid = Backbone.View.extend({ }); newView.render(); }); + // hide extra header col if no scrollbar to avoid unsightly overhang + var $tbody = this.el.find('tbody')[0]; + if ($tbody.scrollHeight <= $tbody.offsetHeight) { + this.el.find('th.last-header').hide(); + } this.el.find('.recline-grid').toggleClass('no-hidden', (self.state.get('hiddenFields').length === 0)); return this; + }, + + // ### _scrollbarSize + // + // Measure width of a vertical scrollbar and height of a horizontal scrollbar. + // + // @return: { width: pixelWidth, height: pixelHeight } + _scrollbarSize: function() { + var $c = $("
").appendTo("body"); + var dim = { width: $c.width() - $c[0].clientWidth + 1, height: $c.height() - $c[0].clientHeight }; + $c.remove(); + return dim; } }); @@ -1278,7 +1317,7 @@ my.GridRow = Backbone.View.extend({ \ \ {{#cells}} \ - \ + \
\   \
{{{value}}}
\ @@ -1298,6 +1337,7 @@ my.GridRow = Backbone.View.extend({ var cellData = this._fields.map(function(field) { return { field: field.id, + width: field.get('width'), value: doc.getFieldValue(field) }; }); @@ -1795,7 +1835,7 @@ my.Map = Backbone.View.extend({ // on [OpenStreetMap](http://openstreetmap.org). // _setupMap: function(){ - var self = this; + this.map = new L.Map(this.$map.get(0)); var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"; @@ -1835,14 +1875,6 @@ my.Map = Backbone.View.extend({ this.map.setView(new L.LatLng(0, 0), 2); - var popup = new L.Popup(); - this.map.on('click', function(e) { - var latlngStr = '(' + e.latlng.lat.toFixed(3) + ', ' + e.latlng.lng.toFixed(3) + ')'; - popup.setLatLng(e.latlng); - popup.setContent("You clicked the map at " + latlngStr); - self.map.openPopup(popup); - }); - this.mapReady = true; }, @@ -2043,10 +2075,11 @@ my.ColumnTransform = Backbone.View.extend({ // # Recline Views // -// Recline Views are Backbone Views and in keeping with normal Backbone views -// are Widgets / Components displaying something in the DOM. Like all Backbone -// views they have a pointer to a model or a collection and is bound to an -// element. +// Recline Views are instances of Backbone Views and they act as 'WUI' (web +// user interface) component displaying some model object in the DOM. Like all +// Backbone views they have a pointer to a model (or a collection) and have an +// associated DOM-style element (usually this element will be bound into the +// page at some point). // // Views provided by core Recline are crudely divided into two types: // @@ -2262,12 +2295,11 @@ my.DataExplorer = Backbone.View.extend({ } this.model.bind('query:start', function() { - self.notify({message: 'Loading data', loader: true}); + self.notify({loader: true, persist: true}); }); this.model.bind('query:done', function() { self.clearNotifications(); self.el.find('.doc-count').text(self.model.docCount || 'Unknown'); - self.notify({message: 'Data loaded', category: 'success'}); }); this.model.bind('query:fail', function(error) { self.clearNotifications(); @@ -2432,19 +2464,25 @@ my.DataExplorer = Backbone.View.extend({ // * loader: if true show loading spinner notify: function(flash) { var tmplData = _.extend({ - message: '', - category: 'warning' + message: 'Loading', + category: 'warning', + loader: false }, flash ); - var _template = ' \ -
× \ - {{message}} \ - {{#loader}} \ + if (tmplData.loader) { + var _template = ' \ +
\ + {{message}} \   \ - {{/loader}} \ -
'; - var _templated = $.mustache(_template, tmplData); +
'; + } else { + var _template = ' \ +
× \ + {{message}} \ +
'; + } + var _templated = $($.mustache(_template, tmplData)); _templated = $(_templated).appendTo($('.recline-data-explorer .alert-messages')); if (!flash.persist) { setTimeout(function() { @@ -2460,7 +2498,9 @@ my.DataExplorer = Backbone.View.extend({ // Clear all existing notifications clearNotifications: function() { var $notifications = $('.recline-data-explorer .alert-messages .alert'); - $notifications.remove(); + $notifications.fadeOut(1500, function() { + $(this).remove(); + }); } });