From 2157b1627008112e083277efb1aed5790e60ef48 Mon Sep 17 00:00:00 2001 From: Nathan Williams Date: Fri, 16 May 2014 22:48:48 -0400 Subject: [PATCH 1/2] #410 Add configuration option for filtering created items. "createFilter" option can be a RegExp, string regex or a predicate function. Option only affects user input; it does not control direct additions via API calls. Includes documentation, example and tests. --- docs/usage.md | 7 ++++ examples/createFilter.html | 65 ++++++++++++++++++++++++++++++++++++++ src/defaults.js | 1 + src/selectize.js | 14 ++++++-- test/interaction.js | 39 +++++++++++++++++++++++ 5 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 examples/createFilter.html diff --git a/docs/usage.md b/docs/usage.md index 6b5739b21..c6820767a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -48,6 +48,13 @@ $(function() { boolean false + + createFilter + + Specifies a RegExp or String containing a regular expression that the current search filter must match to be allowed to be created. May also be a predicate function that takes the filter text and returns whether it is allowed. + mixed + false + highlight Toggles match highlighting within the dropdown menu. diff --git a/examples/createFilter.html b/examples/createFilter.html new file mode 100644 index 000000000..6974f8646 --- /dev/null +++ b/examples/createFilter.html @@ -0,0 +1,65 @@ + + + + + + + + + Selectize.js Demo + + + + + + + + + + +
+

Selectize.js

+
+

Create Filter

+

Examples of how to filter created results.

+
+ + + + +
+
+ + + + +
+
+ + +
+ +
+
+ + diff --git a/src/defaults.js b/src/defaults.js index b05491429..0ad87e39a 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -6,6 +6,7 @@ Selectize.defaults = { diacritics: true, create: false, createOnBlur: false, + createFilter: null, highlight: true, openOnFocus: true, maxOptions: 1000, diff --git a/src/selectize.js b/src/selectize.js index 8ea0b6de8..4396e9f35 100644 --- a/src/selectize.js +++ b/src/selectize.js @@ -64,6 +64,16 @@ var Selectize = function($input, settings) { self.settings.hideSelected = self.settings.mode === 'multi'; } + if (self.settings.create) { + self.canCreate = function(input) { + var filter = self.settings.createFilter; + return input.length + && (typeof filter !== 'function' || filter(input)) + && (typeof filter !== 'string' || new RegExp(filter).test(input)) + && (!(filter instanceof RegExp) || filter.test(input)); + }; + } + self.initializePlugins(self.settings.plugins); self.setupCallbacks(); self.setupTemplates(); @@ -1028,7 +1038,7 @@ $.extend(Selectize.prototype, { } // add create option - has_create_option = self.settings.create && results.query.length; + has_create_option = self.settings.create && self.canCreate(results.query); if (has_create_option) { $dropdown_content.prepend(self.render('option_create', {input: query})); $create = $($dropdown_content[0].childNodes[0]); @@ -1379,7 +1389,7 @@ $.extend(Selectize.prototype, { var self = this; var input = $.trim(self.$control_input.val() || ''); var caret = self.caretPos; - if (!input.length) return false; + if (!self.canCreate(input)) return false; self.lock(); if (typeof triggerDropdown === 'undefined') { diff --git a/test/interaction.js b/test/interaction.js index 91cf097aa..9d08fc1fd 100644 --- a/test/interaction.js +++ b/test/interaction.js @@ -200,6 +200,45 @@ }); }); + describe('filtering created items', function() { + function createFilterTest(createFilter) { + return setup_test('', {create: true, createFilter: createFilter}); + } + + var text = 'abc'; + + function execFilterTest(test, done, expectation) { + var selectize = test.selectize; + Syn.click(selectize.$control).type(text, selectize.$control_input).type(selectize.settings.delimiter, selectize.$control_input).delay(0, function() { + expectation(selectize); + done(); + }); + } + + function execFilterTests(heading, filters, expectation) { + for (var i = 0; i < filters.length; i++) { + (function(filter) { + it(heading, function(done) { + execFilterTest(createFilterTest(filter), done, expectation); + }); + })(filters[i]); + } + } + + execFilterTests('should add an item normally if there is no createFilter', [undefined, null, ''], function(selectize) { + expect(selectize.getItem(text).length).to.be.equal(1); + }); + + execFilterTests('should add an item if the input matches the createFilter', ['a', /a/, function() { return true; }], function(selectize) { + expect(selectize.getItem(text).length).to.be.equal(1); + }); + + execFilterTests('should not add an item or display the create label if the input does not match the createFilter', ['foo', /foo/, function() { return false; }], function(selectize) { + expect(selectize.getItem(text).length).to.be.equal(0); + expect($(selectize.$dropdown_content).filter('.create').length).to.be.equal(0); + }); + }); + }); })(); \ No newline at end of file From 21994bcfb6d1915f909856f690aae942655902ea Mon Sep 17 00:00:00 2001 From: Nathan Williams Date: Tue, 20 May 2014 22:29:03 -0400 Subject: [PATCH 2/2] Documentation tweak. --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index c6820767a..c40019a11 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -53,7 +53,7 @@ $(function() { Specifies a RegExp or String containing a regular expression that the current search filter must match to be allowed to be created. May also be a predicate function that takes the filter text and returns whether it is allowed. mixed - false + null highlight