From 1bcb163ebe2b020351f978a1ac6e716b396db249 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Thu, 4 Oct 2012 07:01:41 +0100 Subject: [PATCH] [filter,refactor][s]: remove fieldType attribute on filters as can (and should) get fieldType from model if needed. * fieldType is needed now as we parse values to specific type before doing filters * needed to correct some tests for this change --- src/backend.memory.js | 21 ++++++++++++----- src/model.js | 7 +++--- src/widget.filtereditor.js | 3 +-- test/backend.memory.test.js | 39 ++++++++++++++++++++++++-------- test/widget.filtereditor.test.js | 2 +- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/backend.memory.js b/src/backend.memory.js index 539db80c..90748d9a 100644 --- a/src/backend.memory.js +++ b/src/backend.memory.js @@ -24,7 +24,7 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {}; } else { if (data) { this.fields = _.map(data[0], function(value, key) { - return {id: key}; + return {id: key, type: 'string'}; }); } } @@ -99,10 +99,20 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {}; geo_distance : geo_distance }; var dataParsers = { - number : function (e) { return parseFloat(e, 10); }, + integer: function (e) { return parseFloat(e, 10); }, + 'float': function (e) { return parseFloat(e, 10); }, string : function (e) { return e.toString() }, - date : function (e) { return new Date(e).valueOf() } + date : function (e) { return new Date(e).valueOf() }, + datetime : function (e) { return new Date(e).valueOf() } }; + var keyedFields = {}; + _.each(self.fields, function(field) { + keyedFields[field.id] = field; + }); + function getDataParser(filter) { + var fieldType = keyedFields[filter.field].type || 'string'; + return dataParsers[fieldType]; + } // filter records return _.filter(results, function (record) { @@ -115,9 +125,8 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {}; }); // filters definitions - function term(record, filter) { - var parse = dataParsers[filter.fieldType]; + var parse = getDataParser(filter); var value = parse(record[filter.field]); var term = parse(filter.term); @@ -125,7 +134,7 @@ this.recline.Backend.Memory = this.recline.Backend.Memory || {}; } function range(record, filter) { - var parse = dataParsers[filter.fieldType]; + var parse = getDataParser(filter); var value = parse(record[filter.field]); var start = parse(filter.start); var stop = parse(filter.stop); diff --git a/src/model.js b/src/model.js index ffc33d00..583cf780 100644 --- a/src/model.js +++ b/src/model.js @@ -470,16 +470,15 @@ my.Query = Backbone.Model.extend({ } } }, - // ### addFilter + // ### addFilter(filter) // - // Add a new filter (appended to the list of filters) + // Add a new filter specified by the filter hash and append to the list of filters // // @param filter an object specifying the filter - see _filterTemplates for examples. If only type is provided will generate a filter by cloning _filterTemplates addFilter: function(filter) { // crude deep copy var ourfilter = JSON.parse(JSON.stringify(filter)); - // not full specified so use template and over-write - // 3 as for 'type', 'field' and 'fieldType' + // not fully specified so use template and over-write if (_.keys(filter).length <= 3) { ourfilter = _.extend(this._filterTemplates[filter.type], ourfilter); } diff --git a/src/widget.filtereditor.js b/src/widget.filtereditor.js index b8885d17..74a4f787 100644 --- a/src/widget.filtereditor.js +++ b/src/widget.filtereditor.js @@ -122,8 +122,7 @@ my.FilterEditor = Backbone.View.extend({ $target.hide(); var filterType = $target.find('select.filterType').val(); var field = $target.find('select.fields').val(); - var fieldType = this.model.fields.find(function (e) { return e.get('id') === field }).get('type'); - this.model.queryState.addFilter({type: filterType, field: field, fieldType: fieldType}); + this.model.queryState.addFilter({type: filterType, field: field}); // trigger render explicitly as queryState change will not be triggered (as blank value for filter) this.render(); }, diff --git a/test/backend.memory.test.js b/test/backend.memory.test.js index ee39a485..ffca17bd 100644 --- a/test/backend.memory.test.js +++ b/test/backend.memory.test.js @@ -11,9 +11,20 @@ var memoryData = [ , {id: 5, date: '2011-10-11', x: 6, y: 12, z: 18, country: 'DE', label: 'sixth'} ]; +var memoryFields = [ + {id: 'id'}, + {id: 'date', type: 'date'}, + {id: 'x', type: 'integer'}, + {id: 'y', type: 'integer'}, + {id: 'z', type: 'integer'}, + {id: 'country'}, + {id: 'label'} +]; + var _wrapData = function() { var dataCopy = $.extend(true, [], memoryData); - return new recline.Backend.Memory.Store(dataCopy); + // return new recline.Backend.Memory.Store(dataCopy, fields); + return new recline.Backend.Memory.Store(dataCopy, memoryFields); } test('basics', function () { @@ -82,21 +93,21 @@ test('query string', function () { test('filters', function () { var data = _wrapData(); var query = new recline.Model.Query(); - query.addFilter({type: 'term', fieldType: 'string', field: 'country', term: 'UK'}); + query.addFilter({type: 'term', field: 'country', term: 'UK'}); data.query(query.toJSON()).then(function(out) { equal(out.total, 3); deepEqual(_.pluck(out.hits, 'country'), ['UK','UK','UK']); }); query = new recline.Model.Query(); - query.addFilter({type: 'range', fieldType: 'date', field: 'date', start: '2011-01-01', stop: '2011-05-01'}); + query.addFilter({type: 'range', field: 'date', start: '2011-01-01', stop: '2011-05-01'}); data.query(query.toJSON()).then(function(out) { equal(out.total, 3); deepEqual(_.pluck(out.hits, 'date'), ['2011-01-01','2011-02-03','2011-04-05']); }); query = new recline.Model.Query(); - query.addFilter({type: 'range', fieldType: 'number', field: 'z', start: '0', stop: '10'}); + query.addFilter({type: 'range', field: 'z', start: '0', stop: '10'}); data.query(query.toJSON()).then(function(out) { equal(out.total, 3); deepEqual(_.pluck(out.hits, 'z'), [3,6,9]); @@ -148,13 +159,23 @@ test('update and delete', function () { module("Backend Memory - Model Integration"); +var memoryFields = [ + {id: 'id'}, + {id: 'date', type: 'date'}, + {id: 'x', type: 'integer'}, + {id: 'y', type: 'integer'}, + {id: 'z', type: 'integer'}, + {id: 'country'}, + {id: 'label'} +]; + var memoryData = { metadata: { title: 'My Test Dataset' , name: '1-my-test-dataset' , id: 'test-dataset' }, - fields: [{id: 'x'}, {id: 'y'}, {id: 'z'}, {id: 'country'}, {id: 'label'}], + fields: memoryFields, records: [ {id: 0, x: 1, y: 2, z: 3, country: 'DE', label: 'first'} , {id: 1, x: 2, y: 4, z: 6, country: 'UK', label: 'second'} @@ -170,7 +191,7 @@ function makeBackendDataset() { id: 'test-dataset', title: 'My Test Dataset', name: '1-my-test-dataset', - fields: [{id: 'date'}, {id: 'x'}, {id: 'y'}, {id: 'z'}, {id: 'country'}, {id: 'label'}], + fields: memoryFields, records: [ {id: 0, date: '2011-01-01', x: 1, y: 2, z: 3, country: 'DE', label: 'first'} , {id: 1, date: '2011-02-03', x: 2, y: 4, z: 6, country: 'UK', label: 'second'} @@ -241,21 +262,21 @@ test('query string', function () { test('filters', function () { var dataset = makeBackendDataset(); - dataset.queryState.addFilter({type: 'term', fieldType: 'string', field: 'country', term: 'UK'}); + dataset.queryState.addFilter({type: 'term', field: 'country', term: 'UK'}); dataset.query().then(function() { equal(dataset.records.length, 3); deepEqual(dataset.records.pluck('country'), ['UK', 'UK', 'UK']); }); dataset = makeBackendDataset(); - dataset.queryState.addFilter({type: 'range', fieldType: 'date', field: 'date', start: '2011-01-01', stop: '2011-05-01'}); + dataset.queryState.addFilter({type: 'range', field: 'date', start: '2011-01-01', stop: '2011-05-01'}); dataset.query().then(function() { equal(dataset.records.length, 3); deepEqual(dataset.records.pluck('date'), ['2011-01-01','2011-02-03','2011-04-05']); }); dataset = makeBackendDataset(); - dataset.queryState.addFilter({type: 'range', fieldType: 'number', field: 'z', start: '0', stop: '10'}); + dataset.queryState.addFilter({type: 'range', field: 'z', start: '0', stop: '10'}); dataset.query().then(function() { equal(dataset.records.length, 3); deepEqual(dataset.records.pluck('z'), [3,6,9]); diff --git a/test/widget.filtereditor.test.js b/test/widget.filtereditor.test.js index 0baf65c0..05f90ae7 100644 --- a/test/widget.filtereditor.test.js +++ b/test/widget.filtereditor.test.js @@ -56,7 +56,7 @@ test('geo_distance', function () { $editForm = view.el.find('form.js-edit'); equal($editForm.find('.filter-geo_distance').length, 1) deepEqual(_.sortBy(_.keys(dataset.queryState.attributes.filters[0]),_.identity), - ["distance", "field", "fieldType", "point", "type", "unit"]); + ["distance", "field", "point", "type", "unit"]); // now set filter value and apply $editForm.find('input[name="lat"]').val(10);