From 72a65213c0c06b44fb078fd1802af6ac33253ed2 Mon Sep 17 00:00:00 2001 From: John Glover Date: Tue, 2 Apr 2013 17:11:07 +0200 Subject: [PATCH 1/2] [#336] Add valuefilter widget --- _includes/recline-deps.html | 1 + css/multiview.css | 12 ++++ src/widget.valuefilter.js | 115 ++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 src/widget.valuefilter.js diff --git a/_includes/recline-deps.html b/_includes/recline-deps.html index 7cd8f7f4..4174fbfb 100644 --- a/_includes/recline-deps.html +++ b/_includes/recline-deps.html @@ -69,6 +69,7 @@ + diff --git a/css/multiview.css b/css/multiview.css index be894449..6837e7c2 100644 --- a/css/multiview.css +++ b/css/multiview.css @@ -110,6 +110,18 @@ width: 175px; } +.recline-filter-editor input { + margin-top: 0.5em; +} + +.recline-filter-editor .add-filter { + margin-top: 1em; + margin-bottom: 2em; +} + +.recline-filter-editor .update-filter { + margin-top: 1em; +} /********************************************************** * Fields Widget diff --git a/src/widget.valuefilter.js b/src/widget.valuefilter.js new file mode 100644 index 00000000..60c08e65 --- /dev/null +++ b/src/widget.valuefilter.js @@ -0,0 +1,115 @@ +/*jshint multistr:true */ + +this.recline = this.recline || {}; +this.recline.View = this.recline.View || {}; + +(function($, my) { + +my.ValueFilter = Backbone.View.extend({ + className: 'recline-filter-editor well', + template: ' \ +
\ +

Filters

\ + \ + \ +
\ + {{#filters}} \ + {{{filterRender}}} \ + {{/filters}} \ + {{#filters.length}} \ + \ + {{/filters.length}} \ +
\ +
\ + ', + filterTemplates: { + term: ' \ +
\ +
\ + {{field}} \ + × \ + \ +
\ +
\ + ' + }, + events: { + 'click .js-remove-filter': 'onRemoveFilter', + 'click .js-add-filter': 'onAddFilterShow', + 'submit form.js-edit': 'onTermFiltersUpdate', + 'submit form.js-add': 'onAddFilter' + }, + initialize: function() { + this.el = $(this.el); + _.bindAll(this, 'render'); + this.model.fields.bind('all', this.render); + this.model.queryState.bind('change', this.render); + this.model.queryState.bind('change:filters:new-blank', this.render); + this.render(); + }, + render: function() { + var self = this; + var tmplData = $.extend(true, {}, this.model.queryState.toJSON()); + // we will use idx in list as the id ... + tmplData.filters = _.map(tmplData.filters, function(filter, idx) { + filter.id = idx; + return filter; + }); + tmplData.fields = this.model.fields.toJSON(); + tmplData.filterRender = function() { + return Mustache.render(self.filterTemplates.term, this); + }; + var out = Mustache.render(this.template, tmplData); + this.el.html(out); + }, + updateFilter: function(input) { + var self = this; + var filters = self.model.queryState.get('filters'); + var $input = $(input); + var filterIndex = parseInt($input.attr('data-filter-id'), 10); + var value = $input.val(); + filters[filterIndex].term = value; + }, + onAddFilterShow: function(e) { + e.preventDefault(); + var $target = $(e.target); + $target.hide(); + this.el.find('form.js-add').show(); + }, + onAddFilter: function(e) { + e.preventDefault(); + var $target = $(e.target); + $target.hide(); + var field = $target.find('select.fields').val(); + this.model.queryState.addFilter({type: 'term', field: field}); + }, + onRemoveFilter: function(e) { + e.preventDefault(); + var $target = $(e.target); + var filterId = $target.attr('data-filter-id'); + this.model.queryState.removeFilter(filterId); + }, + onTermFiltersUpdate: function(e) { + var self = this; + e.preventDefault(); + var filters = self.model.queryState.get('filters'); + var $form = $(e.target); + _.each($form.find('input'), function(input) { + self.updateFilter(input); + }); + self.model.queryState.set({filters: filters, from: 0}); + self.model.queryState.trigger('change'); + } +}); + +})(jQuery, recline.View); From 457e39dc1e6dfcc63bf0aa044166c77b87de8531 Mon Sep 17 00:00:00 2001 From: John Glover Date: Tue, 2 Apr 2013 17:24:37 +0200 Subject: [PATCH 2/2] [#336] Add tests for valuefilter widget --- test/index.html | 1 + test/widget.valuefilter.test.js | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 test/widget.valuefilter.test.js diff --git a/test/index.html b/test/index.html index cfa1151e..31b8bb08 100644 --- a/test/index.html +++ b/test/index.html @@ -71,6 +71,7 @@ + diff --git a/test/widget.valuefilter.test.js b/test/widget.valuefilter.test.js new file mode 100644 index 00000000..6b8a86a1 --- /dev/null +++ b/test/widget.valuefilter.test.js @@ -0,0 +1,67 @@ +module("Widget - Value Filter"); + +test('basics', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.FilterEditor({ + model: dataset + }); + $('.fixtures').append(view.el); + assertPresent('.js-add-filter', view.elSidebar); + var $addForm = view.el.find('form.js-add'); + ok(!$addForm.is(":visible")); + view.el.find('.js-add-filter').click(); + ok(!view.el.find('.js-add-filter').is(":visible")); + ok($addForm.is(":visible")); + + // submit the form + $addForm.find('select.fields').val('country'); + $addForm.submit(); + + // now check we have new filter + ok(!$addForm.is(":visible")); + $editForm = view.el.find('form.js-edit'); + equal($editForm.find('.filter-term').length, 1); + equal(dataset.queryState.attributes.filters[0].field, 'country'); + + // now set filter value and apply + $editForm.find('input').val('UK'); + $editForm.submit(); + equal(dataset.queryState.attributes.filters[0].term, 'UK'); + equal(dataset.records.length, 3); + + // now remove filter + $editForm = view.el.find('form.js-edit'); + $editForm.find('.js-remove-filter').last().click(); + $editForm = view.el.find('form.js-edit'); + equal($editForm.find('.filter').length, 0); + equal(dataset.records.length, 6); + + view.remove(); +}); + +test('add 2 filters', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.FilterEditor({ + model: dataset + }); + $('.fixtures').append(view.el); + + // add 2 term filters + var $addForm = view.el.find('form.js-add'); + view.el.find('.js-add-filter').click(); + $addForm.find('select.fields').val('country'); + $addForm.submit(); + + $addForm = view.el.find('form.js-add'); + view.el.find('.js-add-filter').click(); + $addForm.find('select.fields').val('id'); + $addForm.submit(); + + var fields = []; + view.el.find('form.js-edit .filter-term input').each(function(idx, item) { + fields.push($(item).attr('data-filter-field')); + }); + deepEqual(fields, ['country', 'id']); + + view.remove(); +});