Merge branch '336-value-filter'
This commit is contained in:
@@ -69,6 +69,7 @@
|
|||||||
<script type="text/javascript" src="{{page.root}}src/widget.pager.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/widget.pager.js"></script>
|
||||||
<script type="text/javascript" src="{{page.root}}src/widget.queryeditor.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/widget.queryeditor.js"></script>
|
||||||
<script type="text/javascript" src="{{page.root}}src/widget.filtereditor.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/widget.filtereditor.js"></script>
|
||||||
|
<script type="text/javascript" src="{{page.root}}src/widget.valuefilter.js"></script>
|
||||||
<script type="text/javascript" src="{{page.root}}src/widget.facetviewer.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/widget.facetviewer.js"></script>
|
||||||
<script type="text/javascript" src="{{page.root}}src/widget.fields.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/widget.fields.js"></script>
|
||||||
<script type="text/javascript" src="{{page.root}}src/view.multiview.js"></script>
|
<script type="text/javascript" src="{{page.root}}src/view.multiview.js"></script>
|
||||||
|
|||||||
@@ -110,6 +110,18 @@
|
|||||||
width: 175px;
|
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
|
* Fields Widget
|
||||||
|
|||||||
115
src/widget.valuefilter.js
Normal file
115
src/widget.valuefilter.js
Normal file
@@ -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: ' \
|
||||||
|
<div class="filters"> \
|
||||||
|
<h3>Filters</h3> \
|
||||||
|
<button class="btn js-add-filter add-filter">Add filter</button> \
|
||||||
|
<form class="form-stacked js-add" style="display: none;"> \
|
||||||
|
<fieldset> \
|
||||||
|
<label>Field</label> \
|
||||||
|
<select class="fields"> \
|
||||||
|
{{#fields}} \
|
||||||
|
<option value="{{id}}">{{label}}</option> \
|
||||||
|
{{/fields}} \
|
||||||
|
</select> \
|
||||||
|
<button type="submit" class="btn">Add</button> \
|
||||||
|
</fieldset> \
|
||||||
|
</form> \
|
||||||
|
<form class="form-stacked js-edit"> \
|
||||||
|
{{#filters}} \
|
||||||
|
{{{filterRender}}} \
|
||||||
|
{{/filters}} \
|
||||||
|
{{#filters.length}} \
|
||||||
|
<button type="submit" class="btn update-filter">Update</button> \
|
||||||
|
{{/filters.length}} \
|
||||||
|
</form> \
|
||||||
|
</div> \
|
||||||
|
',
|
||||||
|
filterTemplates: {
|
||||||
|
term: ' \
|
||||||
|
<div class="filter-{{type}} filter"> \
|
||||||
|
<fieldset> \
|
||||||
|
{{field}} \
|
||||||
|
<a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">×</a> \
|
||||||
|
<input type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
|
||||||
|
</fieldset> \
|
||||||
|
</div> \
|
||||||
|
'
|
||||||
|
},
|
||||||
|
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);
|
||||||
@@ -71,6 +71,7 @@
|
|||||||
<script type="text/javascript" src="view.multiview.test.js"></script>
|
<script type="text/javascript" src="view.multiview.test.js"></script>
|
||||||
<script type="text/javascript" src="util.test.js"></script>
|
<script type="text/javascript" src="util.test.js"></script>
|
||||||
<script type="text/javascript" src="widget.filtereditor.test.js"></script>
|
<script type="text/javascript" src="widget.filtereditor.test.js"></script>
|
||||||
|
<script type="text/javascript" src="widget.valuefilter.test.js"></script>
|
||||||
|
|
||||||
<!-- data tests -->
|
<!-- data tests -->
|
||||||
<script type="text/javascript" src="../src/data.transform.js"></script>
|
<script type="text/javascript" src="../src/data.transform.js"></script>
|
||||||
|
|||||||
67
test/widget.valuefilter.test.js
Normal file
67
test/widget.valuefilter.test.js
Normal file
@@ -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();
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user