Skip to content

Commit 684703f

Browse files
committed
Merge commit '21994bcfb6d1915f909856f690aae942655902ea'
2 parents fcc980f + 21994bc commit 684703f

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

docs/usage.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ $(function() {
4848
<td valign="top"><code>boolean</code></td>
4949
<td valign="top"><code>false</code></td>
5050
</tr>
51+
<tr>
52+
<td valign="top"><code>createFilter</code></td>
53+
<td valign="top">
54+
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.</td>
55+
<td valign="top"><code>mixed</code></td>
56+
<td valign="top"><code>null</code></td>
57+
</tr>
5158
<tr>
5259
<td valign="top"><code>highlight</code></td>
5360
<td valign="top">Toggles match highlighting within the dropdown menu.</td>

examples/createFilter.html

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<!DOCTYPE html>
2+
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
3+
<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]-->
4+
<!--[if IE 8]><html class="no-js lt-ie9"><![endif]-->
5+
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
6+
<head>
7+
<meta charset="utf-8">
8+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
9+
<title>Selectize.js Demo</title>
10+
<meta name="description" content="">
11+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
12+
<link rel="stylesheet" href="css/normalize.css">
13+
<link rel="stylesheet" href="css/stylesheet.css">
14+
<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
15+
<script src="js/jquery.js"></script>
16+
<script src="../dist/js/standalone/selectize.js"></script>
17+
<script src="js/index.js"></script>
18+
</head>
19+
<body>
20+
<div id="wrapper">
21+
<h1>Selectize.js</h1>
22+
<div class="demo">
23+
<h2>Create Filter</h2>
24+
<p>Examples of how to filter created results.</p>
25+
<div class="control-group">
26+
<label for="regex">Pattern</label>
27+
<input type="text" id="regex" value="a+">
28+
<label for="select-words-regex">Words:</label>
29+
<select id="select-words-regex" multiple placeholder="Enter a word matching the pattern..."></select>
30+
</div>
31+
<div class="control-group">
32+
<label for="length">Minimum Length</label>
33+
<input type="text" id="length" value="2">
34+
<label for="select-words-length">Words:</label>
35+
<select id="select-words-length" multiple placeholder="Enter a word longer than the minimum number of characters..."></select>
36+
</div>
37+
<div class="control-group">
38+
<label for="select-words-unique">Words:</label>
39+
<select id="select-words-unique" multiple placeholder="Enter unique words (case-insensitive)..."></select>
40+
</div>
41+
<script>
42+
$('#select-words-regex').selectize({
43+
create: true,
44+
createFilter: $('#regex').val()
45+
});
46+
47+
$('#select-words-length').selectize({
48+
create: true,
49+
createFilter: function(input) { return input.length >= parseInt($('#length').val(), 10); }
50+
});
51+
52+
var unique = $('#select-words-unique').selectize({
53+
create: true,
54+
createFilter: function(input) {
55+
input = input.toLowerCase();
56+
return $.grep(unique.getValue(), function(value) {
57+
return value.toLowerCase() === input;
58+
}).length == 0;
59+
}
60+
})[0].selectize;
61+
</script>
62+
</div>
63+
</div>
64+
</body>
65+
</html>

src/defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Selectize.defaults = {
66
diacritics: true,
77
create: false,
88
createOnBlur: false,
9+
createFilter: null,
910
highlight: true,
1011
openOnFocus: true,
1112
maxOptions: 1000,

src/selectize.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ var Selectize = function($input, settings) {
6565
self.settings.hideSelected = self.settings.mode === 'multi';
6666
}
6767

68+
if (self.settings.create) {
69+
self.canCreate = function(input) {
70+
var filter = self.settings.createFilter;
71+
return input.length
72+
&& (typeof filter !== 'function' || filter(input))
73+
&& (typeof filter !== 'string' || new RegExp(filter).test(input))
74+
&& (!(filter instanceof RegExp) || filter.test(input));
75+
};
76+
}
77+
6878
self.initializePlugins(self.settings.plugins);
6979
self.setupCallbacks();
7080
self.setupTemplates();
@@ -1043,7 +1053,7 @@ $.extend(Selectize.prototype, {
10431053
}
10441054

10451055
// add create option
1046-
has_create_option = self.settings.create && results.query.length;
1056+
has_create_option = self.settings.create && self.canCreate(results.query);
10471057
if (has_create_option) {
10481058
$dropdown_content.prepend(self.render('option_create', {input: query}));
10491059
$create = $($dropdown_content[0].childNodes[0]);
@@ -1397,7 +1407,7 @@ $.extend(Selectize.prototype, {
13971407
var self = this;
13981408
var input = $.trim(self.$control_input.val() || '');
13991409
var caret = self.caretPos;
1400-
if (!input.length) return false;
1410+
if (!self.canCreate(input)) return false;
14011411
self.lock();
14021412

14031413
if (typeof triggerDropdown === 'undefined') {

test/interaction.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,45 @@
200200
});
201201
});
202202

203+
describe('filtering created items', function() {
204+
function createFilterTest(createFilter) {
205+
return setup_test('<select multiple="multiple"></select>', {create: true, createFilter: createFilter});
206+
}
207+
208+
var text = 'abc';
209+
210+
function execFilterTest(test, done, expectation) {
211+
var selectize = test.selectize;
212+
Syn.click(selectize.$control).type(text, selectize.$control_input).type(selectize.settings.delimiter, selectize.$control_input).delay(0, function() {
213+
expectation(selectize);
214+
done();
215+
});
216+
}
217+
218+
function execFilterTests(heading, filters, expectation) {
219+
for (var i = 0; i < filters.length; i++) {
220+
(function(filter) {
221+
it(heading, function(done) {
222+
execFilterTest(createFilterTest(filter), done, expectation);
223+
});
224+
})(filters[i]);
225+
}
226+
}
227+
228+
execFilterTests('should add an item normally if there is no createFilter', [undefined, null, ''], function(selectize) {
229+
expect(selectize.getItem(text).length).to.be.equal(1);
230+
});
231+
232+
execFilterTests('should add an item if the input matches the createFilter', ['a', /a/, function() { return true; }], function(selectize) {
233+
expect(selectize.getItem(text).length).to.be.equal(1);
234+
});
235+
236+
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) {
237+
expect(selectize.getItem(text).length).to.be.equal(0);
238+
expect($(selectize.$dropdown_content).filter('.create').length).to.be.equal(0);
239+
});
240+
});
241+
203242
});
204243

205244
})();

0 commit comments

Comments
 (0)