diff --git a/dist/recline.css b/dist/recline.css
index 13cd3858..b8bdd15a 100644
--- a/dist/recline.css
+++ b/dist/recline.css
@@ -24,42 +24,6 @@
opacity: 0.8 !important;
border: 1px solid #fdd !important;
}
-.recline-graph .graph {
- height: 500px;
-}
-
-.recline-graph .legend table {
- width: auto;
- margin-bottom: 0;
-}
-
-.recline-graph .legend td {
- padding: 5px;
- line-height: 13px;
-}
-
-.recline-graph .graph .alert {
- width: 450px;
-}
-
-.flotr-mouse-value {
- background-color: #FEE !important;
- color: #000000 !important;
- opacity: 0.8 !important;
- border: 1px solid #fdd !important;
-}
-
-.flotr-legend {
- border: none !important;
-}
-
-.flotr-legend-bg {
- display: none;
-}
-
-.flotr-legend-color-box {
- padding: 5px;
-}
/**********************************************************
* (Data) Grid
*********************************************************/
@@ -653,40 +617,3 @@ classes should alter those!
.recline-timeline {
position: relative;
}
-.recline-transform {
- overflow: hidden;
-}
-
-.recline-transform .script textarea {
- width: 100%;
- height: 100px;
- font-family: monospace;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-
-.recline-transform h2 {
- margin-bottom: 10px;
-}
-
-.recline-transform h2 .okButton {
- margin-left: 10px;
- margin-top: -2px;
-}
-
-.expression-preview-parsing-status {
- color: #999;
-}
-
-.expression-preview-parsing-status.error {
- color: red;
-}
-
-.recline-transform .before-after .after {
- font-style: italic;
-}
-
-.recline-transform .before-after .after.different {
- font-weight: bold;
-}
diff --git a/dist/recline.dataset.js b/dist/recline.dataset.js
index cdd33a0e..3ca6fd41 100644
--- a/dist/recline.dataset.js
+++ b/dist/recline.dataset.js
@@ -159,20 +159,6 @@ my.Dataset = Backbone.Model.extend({
return this._store.save(this._changes, this.toJSON());
},
- transform: function(editFunc) {
- var self = this;
- if (!this._store.transform) {
- alert('Transform is not supported with this backend: ' + this.get('backend'));
- return;
- }
- this.trigger('recline:flash', {message: "Updating all visible docs. This could take a while...", persist: true, loader: true});
- this._store.transform(editFunc).done(function() {
- // reload data as records have changed
- self.query();
- self.trigger('recline:flash', {message: "Records updated successfully"});
- });
- },
-
// ### query
//
// AJAX method with promise API to get records from the backend.
@@ -829,18 +815,6 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {};
});
return facetResults;
};
-
- this.transform = function(editFunc) {
- var dfd = new Deferred();
- // TODO: should we clone before mapping? Do not see the point atm.
- self.records = _.map(self.records, editFunc);
- // now deal with deletes (i.e. nulls)
- self.records = _.filter(self.records, function(record) {
- return record != null;
- });
- dfd.resolve();
- return dfd.promise();
- };
};
}(this.recline.Backend.Memory));
diff --git a/dist/recline.js b/dist/recline.js
index 70d1931b..9df9cacc 100644
--- a/dist/recline.js
+++ b/dist/recline.js
@@ -1,158 +1,5 @@
this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};
-this.recline.Backend.Ckan = this.recline.Backend.Ckan || {};
-
-(function(my) {
- // ## CKAN Backend
- //
- // This provides connection to the CKAN DataStore (v2)
- //
- // General notes
- //
- // We need 2 things to make most requests:
- //
- // 1. CKAN API endpoint
- // 2. ID of resource for which request is being made
- //
- // There are 2 ways to specify this information.
- //
- // EITHER (checked in order):
- //
- // * Every dataset must have an id equal to its resource id on the CKAN instance
- // * The dataset has an endpoint attribute pointing to the CKAN API endpoint
- //
- // OR:
- //
- // Set the url attribute of the dataset to point to the Resource on the CKAN instance. The endpoint and id will then be automatically computed.
-
- my.__type__ = 'ckan';
-
- // private - use either jQuery or Underscore Deferred depending on what is available
- var Deferred = _.isUndefined(this.jQuery) ? _.Deferred : jQuery.Deferred;
-
- // Default CKAN API endpoint used for requests (you can change this but it will affect every request!)
- //
- // DEPRECATION: this will be removed in v0.7. Please set endpoint attribute on dataset instead
- my.API_ENDPOINT = 'http://datahub.io/api';
-
- // ### fetch
- my.fetch = function(dataset) {
- var wrapper;
- if (dataset.endpoint) {
- wrapper = my.DataStore(dataset.endpoint);
- } else {
- var out = my._parseCkanResourceUrl(dataset.url);
- dataset.id = out.resource_id;
- wrapper = my.DataStore(out.endpoint);
- }
- var dfd = new Deferred();
- var jqxhr = wrapper.search({resource_id: dataset.id, limit: 0});
- jqxhr.done(function(results) {
- // map ckan types to our usual types ...
- var fields = _.map(results.result.fields, function(field) {
- field.type = field.type in CKAN_TYPES_MAP ? CKAN_TYPES_MAP[field.type] : field.type;
- return field;
- });
- var out = {
- fields: fields,
- useMemoryStore: false
- };
- dfd.resolve(out);
- });
- return dfd.promise();
- };
-
- // only put in the module namespace so we can access for tests!
- my._normalizeQuery = function(queryObj, dataset) {
- var actualQuery = {
- resource_id: dataset.id,
- q: queryObj.q,
- filters: {},
- limit: queryObj.size || 10,
- offset: queryObj.from || 0
- };
-
- if (queryObj.sort && queryObj.sort.length > 0) {
- var _tmp = _.map(queryObj.sort, function(sortObj) {
- return sortObj.field + ' ' + (sortObj.order || '');
- });
- actualQuery.sort = _tmp.join(',');
- }
-
- if (queryObj.filters && queryObj.filters.length > 0) {
- _.each(queryObj.filters, function(filter) {
- if (filter.type === "term") {
- actualQuery.filters[filter.field] = filter.term;
- }
- });
- }
- return actualQuery;
- };
-
- my.query = function(queryObj, dataset) {
- var wrapper;
- if (dataset.endpoint) {
- wrapper = my.DataStore(dataset.endpoint);
- } else {
- var out = my._parseCkanResourceUrl(dataset.url);
- dataset.id = out.resource_id;
- wrapper = my.DataStore(out.endpoint);
- }
- var actualQuery = my._normalizeQuery(queryObj, dataset);
- var dfd = new Deferred();
- var jqxhr = wrapper.search(actualQuery);
- jqxhr.done(function(results) {
- var out = {
- total: results.result.total,
- hits: results.result.records
- };
- dfd.resolve(out);
- });
- return dfd.promise();
- };
-
- // ### DataStore
- //
- // Simple wrapper around the CKAN DataStore API
- //
- // @param endpoint: CKAN api endpoint (e.g. http://datahub.io/api)
- my.DataStore = function(endpoint) {
- var that = {endpoint: endpoint || my.API_ENDPOINT};
-
- that.search = function(data) {
- var searchUrl = that.endpoint + '/3/action/datastore_search';
- var jqxhr = jQuery.ajax({
- url: searchUrl,
- type: 'POST',
- data: JSON.stringify(data)
- });
- return jqxhr;
- };
-
- return that;
- };
-
- // Parse a normal CKAN resource URL and return API endpoint etc
- //
- // Normal URL is something like http://demo.ckan.org/dataset/some-dataset/resource/eb23e809-ccbb-4ad1-820a-19586fc4bebd
- my._parseCkanResourceUrl = function(url) {
- parts = url.split('/');
- var len = parts.length;
- return {
- resource_id: parts[len-1],
- endpoint: parts.slice(0,[len-4]).join('/') + '/api'
- };
- };
-
- var CKAN_TYPES_MAP = {
- 'int4': 'integer',
- 'int8': 'integer',
- 'float8': 'float'
- };
-
-}(this.recline.Backend.Ckan));
-this.recline = this.recline || {};
-this.recline.Backend = this.recline.Backend || {};
this.recline.Backend.CSV = this.recline.Backend.CSV || {};
// Note that provision of jQuery is optional (it is **only** needed if you use fetch on a remote file)
@@ -450,7 +297,7 @@ this.recline.Backend.DataProxy = this.recline.Backend.DataProxy || {};
(function(my) {
my.__type__ = 'dataproxy';
// URL for the dataproxy
- my.dataproxy_url = 'http://jsonpdataproxy.appspot.com';
+ my.dataproxy_url = '//jsonpdataproxy.appspot.com';
// Timeout for dataproxy (after this time if no response we error)
// Needed because use JSONP so do not receive e.g. 500 errors
my.timeout = 5000;
@@ -1202,88 +1049,9 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {};
});
return facetResults;
};
-
- this.transform = function(editFunc) {
- var dfd = new Deferred();
- // TODO: should we clone before mapping? Do not see the point atm.
- self.records = _.map(self.records, editFunc);
- // now deal with deletes (i.e. nulls)
- self.records = _.filter(self.records, function(record) {
- return record != null;
- });
- dfd.resolve();
- return dfd.promise();
- };
};
}(this.recline.Backend.Memory));
-this.recline = this.recline || {};
-this.recline.Data = this.recline.Data || {};
-
-(function(my) {
-// adapted from https://github.com/harthur/costco. heather rules
-
-my.Transform = {};
-
-my.Transform.evalFunction = function(funcString) {
- try {
- eval("var editFunc = " + funcString);
- } catch(e) {
- return {errorMessage: e+""};
- }
- return editFunc;
-};
-
-my.Transform.previewTransform = function(docs, editFunc, currentColumn) {
- var preview = [];
- var updated = my.Transform.mapDocs($.extend(true, {}, docs), editFunc);
- for (var i = 0; i < updated.docs.length; i++) {
- var before = docs[i]
- , after = updated.docs[i]
- ;
- if (!after) after = {};
- if (currentColumn) {
- preview.push({before: before[currentColumn], after: after[currentColumn]});
- } else {
- preview.push({before: before, after: after});
- }
- }
- return preview;
-};
-
-my.Transform.mapDocs = function(docs, editFunc) {
- var edited = []
- , deleted = []
- , failed = []
- ;
-
- var updatedDocs = _.map(docs, function(doc) {
- try {
- var updated = editFunc(_.clone(doc));
- } catch(e) {
- failed.push(doc);
- return;
- }
- if(updated === null) {
- updated = {_deleted: true};
- edited.push(updated);
- deleted.push(doc);
- }
- else if(updated && !_.isEqual(updated, doc)) {
- edited.push(updated);
- }
- return updated;
- });
-
- return {
- updates: edited,
- docs: updatedDocs,
- deletes: deleted,
- failed: failed
- };
-};
-
-}(this.recline.Data))
// This file adds in full array method support in browsers that don't support it
// see: http://stackoverflow.com/questions/2790001/fixing-javascript-array-functions-in-internet-explorer-indexof-foreach-etc
@@ -1511,20 +1279,6 @@ my.Dataset = Backbone.Model.extend({
return this._store.save(this._changes, this.toJSON());
},
- transform: function(editFunc) {
- var self = this;
- if (!this._store.transform) {
- alert('Transform is not supported with this backend: ' + this.get('backend'));
- return;
- }
- this.trigger('recline:flash', {message: "Updating all visible docs. This could take a while...", persist: true, loader: true});
- this._store.transform(editFunc).done(function() {
- // reload data as records have changed
- self.query();
- self.trigger('recline:flash', {message: "Records updated successfully"});
- });
- },
-
// ### query
//
// AJAX method with promise API to get records from the backend.
@@ -2449,468 +2203,6 @@ my.FlotControls = Backbone.View.extend({
});
})(jQuery, recline.View);
-/*jshint multistr:true */
-
-this.recline = this.recline || {};
-this.recline.View = this.recline.View || {};
-
-(function($, my) {
-
-// ## Graph view for a Dataset using Flotr2 graphing library.
-//
-// Initialization arguments (in a hash in first parameter):
-//
-// * model: recline.Model.Dataset
-// * state: (optional) configuration hash of form:
-//
-// {
-// group: {column name for x-axis},
-// series: [{column name for series A}, {column name series B}, ... ],
-// graphType: 'line',
-// graphOptions: {custom [Flotr2 options](http://www.humblesoftware.com/flotr2/documentation#configuration)}
-// }
-//
-// NB: should *not* provide an el argument to the view but must let the view
-// generate the element itself (you can then append view.el to the DOM.
-my.Flotr2 = Backbone.View.extend({
- template: ' \
-
\
-
\
-
\
-
Hey there!
\
-
There\'s no graph here yet because we don\'t know what fields you\'d like to see plotted.
\
-
Please tell us by using the menu on the right and a graph will automatically appear.
\
-
\
-
\
-
\
-',
-
- initialize: function(options) {
- var self = this;
- this.graphColors = ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"];
-
- this.el = $(this.el);
- _.bindAll(this, 'render', 'redraw');
- this.needToRedraw = false;
- this.model.bind('change', this.render);
- this.model.fields.bind('reset', this.render);
- this.model.fields.bind('add', this.render);
- this.model.records.bind('add', this.redraw);
- this.model.records.bind('reset', this.redraw);
- var stateData = _.extend({
- group: null,
- // so that at least one series chooser box shows up
- series: [],
- graphType: 'lines-and-points'
- },
- options.state
- );
- this.state = new recline.Model.ObjectState(stateData);
- this.editor = new my.Flotr2Controls({
- model: this.model,
- state: this.state.toJSON()
- });
- this.editor.state.bind('change', function() {
- self.state.set(self.editor.state.toJSON());
- self.redraw();
- });
- this.elSidebar = this.editor.el;
- },
-
- render: function() {
- var self = this;
- var tmplData = this.model.toTemplateJSON();
- var htmls = Mustache.render(this.template, tmplData);
- $(this.el).html(htmls);
- this.$graph = this.el.find('.panel.graph');
- return this;
- },
-
- redraw: function() {
- // There appear to be issues generating a Flotr2 graph if either:
-
- // * The relevant div that graph attaches to his hidden at the moment of creating the plot -- Flotr2 will complain with
- //
- // Uncaught Invalid dimensions for plot, width = 0, height = 0
- // * There is no data for the plot -- either same error or may have issues later with errors like 'non-existent node-value'
- var areWeVisible = !jQuery.expr.filters.hidden(this.el[0]);
- if ((!areWeVisible || this.model.records.length === 0)) {
- this.needToRedraw = true;
- return;
- }
-
- // check we have something to plot
- if (this.state.get('group') && this.state.get('series')) {
- // faff around with width because flot draws axes *outside* of the element width which means graph can get push down as it hits element next to it
- this.$graph.width(this.el.width() - 20);
- var series = this.createSeries();
- var options = this.getGraphOptions(this.state.attributes.graphType);
- this.plot = Flotr.draw(this.$graph.get(0), series, options);
- }
- },
-
- show: function() {
- // because we cannot redraw when hidden we may need to when becoming visible
- if (this.needToRedraw) {
- this.redraw();
- }
- },
-
- // ### getGraphOptions
- //
- // Get options for Flotr2 Graph
- //
- // needs to be function as can depend on state
- //
- // @param typeId graphType id (lines, lines-and-points etc)
- getGraphOptions: function(typeId) {
- var self = this;
-
- var tickFormatter = function (x) {
- return getFormattedX(x);
- };
-
- // infoboxes on mouse hover on points/bars etc
- var trackFormatter = function (obj) {
- var x = obj.x;
- var y = obj.y;
- // it's horizontal so we have to flip
- if (self.state.attributes.graphType === 'bars') {
- var _tmp = x;
- x = y;
- y = _tmp;
- }
-
- x = getFormattedX(x);
-
- var content = _.template('<%= group %> = <%= x %>, <%= series %> = <%= y %>', {
- group: self.state.attributes.group,
- x: x,
- series: obj.series.label,
- y: y
- });
-
- return content;
- };
-
- var getFormattedX = function (x) {
- var xfield = self.model.fields.get(self.state.attributes.group);
-
- // time series
- var xtype = xfield.get('type');
- var isDateTime = (xtype === 'date' || xtype === 'date-time' || xtype === 'time');
-
- if (self.model.records.models[parseInt(x)]) {
- x = self.model.records.models[parseInt(x)].get(self.state.attributes.group);
- if (isDateTime) {
- x = new Date(x).toLocaleDateString();
- }
- } else if (isDateTime) {
- x = new Date(parseInt(x)).toLocaleDateString();
- }
- return x;
- }
-
- var xaxis = {};
- xaxis.tickFormatter = tickFormatter;
-
- var yaxis = {};
- yaxis.autoscale = true;
- yaxis.autoscaleMargin = 0.02;
-
- var mouse = {};
- mouse.track = true;
- mouse.relative = true;
- mouse.trackFormatter = trackFormatter;
-
- var legend = {};
- legend.position = 'ne';
-
- // mouse.lineColor is set in createSeries
- var optionsPerGraphType = {
- lines: {
- legend: legend,
- colors: this.graphColors,
- lines: { show: true },
- xaxis: xaxis,
- yaxis: yaxis,
- mouse: mouse
- },
- points: {
- legend: legend,
- colors: this.graphColors,
- points: { show: true, hitRadius: 5 },
- xaxis: xaxis,
- yaxis: yaxis,
- mouse: mouse,
- grid: { hoverable: true, clickable: true }
- },
- 'lines-and-points': {
- legend: legend,
- colors: this.graphColors,
- points: { show: true, hitRadius: 5 },
- lines: { show: true },
- xaxis: xaxis,
- yaxis: yaxis,
- mouse: mouse,
- grid: { hoverable: true, clickable: true }
- },
- bars: {
- legend: legend,
- colors: this.graphColors,
- lines: { show: false },
- xaxis: yaxis,
- yaxis: xaxis,
- mouse: {
- track: true,
- relative: true,
- trackFormatter: trackFormatter,
- fillColor: '#FFFFFF',
- fillOpacity: 0.3,
- position: 'e'
- },
- bars: {
- show: true,
- horizontal: true,
- shadowSize: 0,
- barWidth: 0.8
- }
- },
- columns: {
- legend: legend,
- colors: this.graphColors,
- lines: { show: false },
- xaxis: xaxis,
- yaxis: yaxis,
- mouse: {
- track: true,
- relative: true,
- trackFormatter: trackFormatter,
- fillColor: '#FFFFFF',
- fillOpacity: 0.3,
- position: 'n'
- },
- bars: {
- show: true,
- horizontal: false,
- shadowSize: 0,
- barWidth: 0.8
- }
- },
- grid: { hoverable: true, clickable: true }
- };
-
- if (self.state.get('graphOptions')){
- return _.extend(optionsPerGraphType[typeId],
- self.state.get('graphOptions')
- )
- }else{
- return optionsPerGraphType[typeId];
- }
- },
-
- createSeries: function() {
- var self = this;
- var series = [];
- _.each(this.state.attributes.series, function(field) {
- var points = [];
- _.each(self.model.records.models, function(doc, index) {
- var xfield = self.model.fields.get(self.state.attributes.group);
- var x = doc.getFieldValue(xfield);
-
- // time series
- var xtype = xfield.get('type');
- var isDateTime = (xtype === 'date' || xtype === 'date-time' || xtype === 'time');
-
- if (isDateTime) {
- // datetime
- if (self.state.attributes.graphType != 'bars' && self.state.attributes.graphType != 'columns') {
- // not bar or column
- x = new Date(x).getTime();
- } else {
- // bar or column
- x = index;
- }
- } else if (typeof x === 'string') {
- // string
- x = parseFloat(x);
- if (isNaN(x)) {
- x = index;
- }
- }
-
- var yfield = self.model.fields.get(field);
- var y = doc.getFieldValue(yfield);
-
- // horizontal bar chart
- if (self.state.attributes.graphType == 'bars') {
- points.push([y, x]);
- } else {
- points.push([x, y]);
- }
- });
- series.push({data: points, label: field, mouse:{lineColor: self.graphColors[series.length]}});
- });
- return series;
- }
-});
-
-my.Flotr2Controls = Backbone.View.extend({
- className: "editor",
- template: ' \
- \
-',
- templateSeriesEditor: ' \
- \
-
\
-
\
- \
-
\
-
\
- ',
- events: {
- 'change form select': 'onEditorSubmit',
- 'click .editor-add': '_onAddSeries',
- 'click .action-remove-series': 'removeSeries'
- },
-
- initialize: function(options) {
- var self = this;
- this.el = $(this.el);
- _.bindAll(this, 'render');
- this.model.fields.bind('reset', this.render);
- this.model.fields.bind('add', this.render);
- this.state = new recline.Model.ObjectState(options.state);
- this.render();
- },
-
- render: function() {
- var self = this;
- var tmplData = this.model.toTemplateJSON();
- var htmls = Mustache.render(this.template, tmplData);
- this.el.html(htmls);
-
- // set up editor from state
- if (this.state.get('graphType')) {
- this._selectOption('.editor-type', this.state.get('graphType'));
- }
- if (this.state.get('group')) {
- this._selectOption('.editor-group', this.state.get('group'));
- }
- // ensure at least one series box shows up
- var tmpSeries = [""];
- if (this.state.get('series').length > 0) {
- tmpSeries = this.state.get('series');
- }
- _.each(tmpSeries, function(series, idx) {
- self.addSeries(idx);
- self._selectOption('.editor-series.js-series-' + idx, series);
- });
- return this;
- },
-
- // Private: Helper function to select an option from a select list
- //
- _selectOption: function(id,value){
- var options = this.el.find(id + ' select > option');
- if (options) {
- options.each(function(opt){
- if (this.value == value) {
- $(this).attr('selected','selected');
- return false;
- }
- });
- }
- },
-
- onEditorSubmit: function(e) {
- var select = this.el.find('.editor-group select');
- var $editor = this;
- var $series = this.el.find('.editor-series select');
- var series = $series.map(function () {
- return $(this).val();
- });
- var updatedState = {
- series: $.makeArray(series),
- group: this.el.find('.editor-group select').val(),
- graphType: this.el.find('.editor-type select').val()
- };
- this.state.set(updatedState);
- },
-
- // Public: Adds a new empty series select box to the editor.
- //
- // @param [int] idx index of this series in the list of series
- //
- // Returns itself.
- addSeries: function (idx) {
- var data = _.extend({
- seriesIndex: idx,
- seriesName: String.fromCharCode(idx + 64 + 1)
- }, this.model.toTemplateJSON());
-
- var htmls = Mustache.render(this.templateSeriesEditor, data);
- this.el.find('.editor-series-group').append(htmls);
- return this;
- },
-
- _onAddSeries: function(e) {
- e.preventDefault();
- this.addSeries(this.state.get('series').length);
- },
-
- // Public: Removes a series list item from the editor.
- //
- // Also updates the labels of the remaining series elements.
- removeSeries: function (e) {
- e.preventDefault();
- var $el = $(e.target);
- $el.parent().parent().remove();
- this.onEditorSubmit();
- }
-});
-
-})(jQuery, recline.View);
-
this.recline = this.recline || {};
this.recline.View = this.recline.View || {};
this.recline.View.Graph = this.recline.View.Flot;
@@ -4003,12 +3295,6 @@ my.MultiView = Backbone.View.extend({
model: this.model,
state: this.state.get('view-timeline')
})
- }, {
- id: 'transform',
- label: 'Transform',
- view: new my.Transform({
- model: this.model
- })
}];
}
// Hashes of sidebar elements
@@ -4947,138 +4233,6 @@ my.Timeline = Backbone.View.extend({
this.recline = this.recline || {};
this.recline.View = this.recline.View || {};
-// Views module following classic module pattern
-(function($, my) {
-
-// ## ColumnTransform
-//
-// View (Dialog) for doing data transformations
-my.Transform = Backbone.View.extend({
- template: ' \
- \
- ',
-
- events: {
- 'click .okButton': 'onSubmit',
- 'keydown .expression-preview-code': 'onEditorKeydown'
- },
-
- initialize: function(options) {
- this.el = $(this.el);
- },
-
- render: function() {
- var htmls = Mustache.render(this.template);
- this.el.html(htmls);
- // Put in the basic (identity) transform script
- // TODO: put this into the template?
- var editor = this.el.find('.expression-preview-code');
- if (this.model.fields.length > 0) {
- var col = this.model.fields.models[0].id;
- } else {
- var col = 'unknown';
- }
- editor.val("function(doc) {\n doc['"+ col +"'] = doc['"+ col +"'];\n return doc;\n}");
- editor.keydown();
- },
-
- onSubmit: function(e) {
- var self = this;
- var funcText = this.el.find('.expression-preview-code').val();
- var editFunc = recline.Data.Transform.evalFunction(funcText);
- if (editFunc.errorMessage) {
- this.trigger('recline:flash', {message: "Error with function! " + editFunc.errorMessage});
- return;
- }
- this.model.transform(editFunc);
- },
-
- editPreviewTemplate: ' \
- \
- \
- \
- | Field | \
- Before | \
- After | \
-
\
- \
- \
- {{#row}} \
- \
- | \
- {{field}} \
- | \
- \
- {{before}} \
- | \
- \
- {{after}} \
- | \
-
\
- {{/row}} \
- \
-
\
- ',
-
- onEditorKeydown: function(e) {
- var self = this;
- // if you don't setTimeout it won't grab the latest character if you call e.target.value
- window.setTimeout( function() {
- var errors = self.el.find('.expression-preview-parsing-status');
- var editFunc = recline.Data.Transform.evalFunction(e.target.value);
- if (!editFunc.errorMessage) {
- errors.text('No syntax error.');
- var docs = self.model.records.map(function(doc) {
- return doc.toJSON();
- });
- var previewData = recline.Data.Transform.previewTransform(docs, editFunc);
- var $el = self.el.find('.expression-preview-container');
- var fields = self.model.fields.toJSON();
- var rows = _.map(previewData.slice(0,4), function(row) {
- return _.map(fields, function(field) {
- return {
- field: field.id,
- before: row.before[field.id],
- after: row.after[field.id],
- different: !_.isEqual(row.before[field.id], row.after[field.id])
- }
- });
- });
- $el.html('');
- _.each(rows, function(row) {
- var templated = Mustache.render(self.editPreviewTemplate, {
- row: row
- });
- $el.append(templated);
- });
- } else {
- errors.text(editFunc.errorMessage);
- }
- }, 1, true);
- }
-});
-
-})(jQuery, recline.View);
-/*jshint multistr:true */
-
-this.recline = this.recline || {};
-this.recline.View = this.recline.View || {};
-
(function($, my) {
// ## FacetViewer