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);