diff --git a/docs/usage.md b/docs/usage.md index 6b5739b21..c40019a11 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 + null + 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 c22ef8284..b531ee27e 100644 --- a/src/selectize.js +++ b/src/selectize.js @@ -65,6 +65,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(); @@ -1043,7 +1053,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]); @@ -1397,7 +1407,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