Skip to content

Commit f175d40

Browse files
committed
Merge PR selectize#1131
2 parents 0c6fafc + bbdde95 commit f175d40

File tree

10 files changed

+187
-22
lines changed

10 files changed

+187
-22
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<!-- Feel free to put either your handle and/or full name, according to
22
your privacy needs -->
33

4+
* New feature: allow to disable single options or complete optgroups
5+
6+
*@zeitiger*
7+
48
## v0.12.3 · 24 August 2016
59
* Make `label[for]` work after applying Selectize (#755)
610

docs/usage.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,12 @@ $(function() {
264264
<td valign="top"><code>string</code></td>
265265
<td valign="top"><code>'optgroup'</code></td>
266266
</tr>
267+
<tr>
268+
<td valign="top"><code>disabledField</code></td>
269+
<td valign="top">The name of the property to disabled option and optgroup.</td>
270+
<td valign="top"><code>string</code></td>
271+
<td valign="top"><code>'disabled'</code></td>
272+
</tr>
267273
<tr>
268274
<td valign="top"><code>sortField</code></td>
269275
<td valign="top">

examples/basic.html

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,29 @@ <h2>&lt;select&gt; (disabled)</h2>
9191
</select>
9292
</div>
9393
<script>
94-
$('#select-beast-disabled').selectize({
95-
create: true,
96-
sortField: {field: 'text'}
97-
});
94+
$('#select-beast-disabled').selectize({
95+
create: true,
96+
sortField: {field: 'text'}
97+
});
98+
</script>
99+
</div>
100+
101+
<div class="demo">
102+
<h2>&lt;select&gt; (&lt;option disabled&gt;)</h2>
103+
<div class="control-group">
104+
<label for="select-beast-single-disabled">Beast:</label>
105+
<select id="select-beast-single-disabled" class="demo-default" placeholder="Select a person...">
106+
<option value="">Select a person...</option>
107+
<option value="4" disabled>Thomas Edison</option>
108+
<option value="1">Nikola</option>
109+
<option value="3" selected>Nikola Tesla</option>
110+
</select>
111+
</div>
112+
<script>
113+
$('#select-beast-single-disabled').selectize({
114+
create: true,
115+
sortField: {field: 'text'}
116+
});
98117
</script>
99118
</div>
100119

examples/optgroups.html

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,37 @@ <h2>Optgroups (basic)</h2>
5555
</select>
5656
</div>
5757
<script>
58-
$('#select-gear').selectize({
59-
sortField: 'text'
60-
});
58+
$('#select-gear').selectize({
59+
sortField: 'text'
60+
});
61+
</script>
62+
</div>
63+
64+
<div class="demo">
65+
<h2>Optgroups (disabled)</h2>
66+
<div class="control-group">
67+
<label for="select-gear-disabled">Gear:</label>
68+
<select id="select-gear-disabled" class="demo-default" multiple placeholder="Select gear...">
69+
<option value="">Select gear...</option>
70+
<optgroup label="Climbing">
71+
<option value="pitons">Pitons</option>
72+
<option value="cams">Cams</option>
73+
<option value="nuts">Nuts</option>
74+
<option value="bolts">Bolts</option>
75+
<option value="stoppers">Stoppers</option>
76+
<option value="sling">Sling</option>
77+
</optgroup>
78+
<optgroup label="Skiing" disabled>
79+
<option value="skis">Skis</option>
80+
<option value="skins">Skins</option>
81+
<option value="poles">Poles</option>
82+
</optgroup>
83+
</select>
84+
</div>
85+
<script>
86+
$('#select-gear-disabled').selectize({
87+
sortField: 'text'
88+
});
6189
</script>
6290
</div>
6391

@@ -78,9 +106,9 @@ <h2>Optgroups (repeated options)</h2>
78106
</select>
79107
</div>
80108
<script>
81-
$('#select-repeated-options').selectize({
82-
sortField: 'text'
83-
});
109+
$('#select-repeated-options').selectize({
110+
sortField: 'text'
111+
});
84112
</script>
85113
</div>
86114

src/defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Selectize.defaults = {
3030
optgroupField: 'optgroup',
3131
valueField: 'value',
3232
labelField: 'text',
33+
disabledField: 'disabled',
3334
optgroupLabelField: 'label',
3435
optgroupValueField: 'value',
3536
lockOptgroupOrder: false,

src/less/selectize.less

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,16 @@
221221
.selectize-border-radius(1px);
222222
}
223223
}
224-
[data-selectable], .optgroup-header {
224+
.option, .optgroup-header {
225225
padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x;
226226
}
227+
.option, [data-disabled], [data-disabled] [data-selectable].option {
228+
cursor: inherit;
229+
opacity: 0.5;
230+
}
231+
[data-selectable].option {
232+
opacity: 1;
233+
}
227234
.optgroup:first-child .optgroup-header {
228235
border-top: 0 none;
229236
}

src/selectize.jquery.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ $.fn.selectize = function(settings_user) {
44
var attr_data = settings.dataAttr;
55
var field_label = settings.labelField;
66
var field_value = settings.valueField;
7+
var field_disabled = settings.disabledField;
78
var field_optgroup = settings.optgroupField;
89
var field_optgroup_label = settings.optgroupLabelField;
910
var field_optgroup_value = settings.optgroupValueField;
@@ -84,6 +85,7 @@ $.fn.selectize = function(settings_user) {
8485
var option = readData($option) || {};
8586
option[field_label] = option[field_label] || $option.text();
8687
option[field_value] = option[field_value] || value;
88+
option[field_disabled] = option[field_disabled] || $option.prop('disabled');
8789
option[field_optgroup] = option[field_optgroup] || group;
8890

8991
optionsMap[value] = option;
@@ -104,6 +106,7 @@ $.fn.selectize = function(settings_user) {
104106
optgroup = readData($optgroup) || {};
105107
optgroup[field_optgroup_label] = id;
106108
optgroup[field_optgroup_value] = id;
109+
optgroup[field_disabled] = $optgroup.prop('disabled');
107110
settings_element.optgroups.push(optgroup);
108111
}
109112

src/selectize.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,15 @@ $.extend(Selectize.prototype, {
178178
if ($input.attr('autocapitalize')) {
179179
$control_input.attr('autocapitalize', $input.attr('autocapitalize'));
180180
}
181+
$control_input[0].type = $input[0].type;
181182

182183
self.$wrapper = $wrapper;
183184
self.$control = $control;
184185
self.$control_input = $control_input;
185186
self.$dropdown = $dropdown;
186187
self.$dropdown_content = $dropdown_content;
187188

189+
$dropdown.on('mouseenter mousedown click', '[data-disabled]>[data-selectable]', function(e) { e.stopImmediatePropagation(); });
188190
$dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); });
189191
$dropdown.on('mousedown click', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); });
190192
watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); });
@@ -2093,11 +2095,16 @@ $.extend(Selectize.prototype, {
20932095

20942096
// add mandatory attributes
20952097
if (templateName === 'option' || templateName === 'option_create') {
2096-
html.attr('data-selectable', '');
2098+
if (!data[self.settings.disabledField]) {
2099+
html.attr('data-selectable', '');
2100+
}
20972101
}
20982102
else if (templateName === 'optgroup') {
20992103
id = data[self.settings.optgroupValueField] || '';
21002104
html.attr('data-group', id);
2105+
if(data[self.settings.disabledField]) {
2106+
html.attr('data-disabled', '');
2107+
}
21012108
}
21022109
if (templateName === 'option' || templateName === 'item') {
21032110
html.attr('data-value', value || '');

test/events.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,48 @@ describe('Events', function() {
6969
});
7070
});
7171
});
72+
73+
74+
it('should not be possible to trigger a disabled option', function(done) {
75+
var test = setup_test(['<select>',
76+
'<option value="a" disabled>Item A</option>',
77+
'<option value="b">Item B</option>',
78+
'</select>'].join(''), {});
79+
var counter = 0;
80+
test.$select.on('change', function() { counter++; });
81+
82+
syn.click(test.selectize.$control).delay(0, function() {
83+
syn
84+
.click($('[data-value="a"]', test.selectize.$dropdown))
85+
.delay(0, function() {
86+
expect(counter).to.be.equal(0);
87+
done();
88+
});
89+
});
90+
});
91+
92+
it('should not be possible to trigger a option under a disabled optgroup', function(done) {
93+
var test = setup_test(['<select>',
94+
'<optgroup label="Group 1">',
95+
'<option value="a">Item A</option>',
96+
'</optgroup>',
97+
'<optgroup label="Group 2" disabled>',
98+
'<option value="b">Item B</option>',
99+
'<option value="c">Item C</option>',
100+
'</optgroup>',
101+
'</select>'].join(''), {});
102+
var counter = 0;
103+
test.$select.on('change', function() { counter++; });
104+
105+
syn.click(test.selectize.$control).delay(0, function() {
106+
syn
107+
.click($('[data-value="c"]', test.selectize.$dropdown))
108+
.delay(0, function() {
109+
expect(counter).to.be.equal(0);
110+
done();
111+
});
112+
});
113+
});
72114
});
73115

74116
describe('item_add', function() {

test/setup.js

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,67 @@
5959
});
6060
});
6161

62+
describe('<input type="number">', function() {
63+
it('should complete without exceptions', function(done) {
64+
var test = setup_test('<input type="number">', {});
65+
window.setTimeout(function() {
66+
assert.equal(test.selectize.$control_input.attr('type'), 'number');
67+
done();
68+
}, 0);
69+
});
70+
});
71+
6272
describe('<select>', function() {
6373
it('should complete without exceptions', function() {
6474
var test = setup_test('<select></select>', {});
6575
});
6676
it('should allow for values optgroups with duplicated options', function() {
6777
var test = setup_test(['<select>',
6878
'<optgroup label="Group 1">',
69-
'<option value="a">Item A</option>',
70-
'<option value="b">Item B</option>',
79+
'<option value="a">Item A</option>',
80+
'<option value="b">Item B</option>',
7181
'</optgroup>',
7282
'<optgroup label="Group 2">',
73-
'<option value="a">Item A</option>',
74-
'<option value="b">Item B</option>',
83+
'<option value="a">Item A</option>',
84+
'<option value="b">Item B</option>',
7585
'</optgroup>',
76-
'</select>'].join(''), {
86+
'</select>'].join(''), {
7787
optgroupValueField: 'val',
78-
optgroupField: 'grp'
88+
optgroupField: 'grp',
89+
disabledField: 'dis'
7990
});
8091
assert.deepEqual(test.selectize.options, {
81-
'a': {text: 'Item A', value: 'a', grp: ['Group 1', 'Group 2'], $order: 1},
82-
'b': {text: 'Item B', value: 'b', grp: ['Group 1', 'Group 2'], $order: 2}
92+
'a': {text: 'Item A', value: 'a', grp: ['Group 1', 'Group 2'], $order: 1, dis: false},
93+
'b': {text: 'Item B', value: 'b', grp: ['Group 1', 'Group 2'], $order: 2, dis: false}
8394
});
8495
assert.deepEqual(test.selectize.optgroups, {
85-
'Group 1': {label: 'Group 1', val: 'Group 1', $order: 3},
86-
'Group 2': {label: 'Group 2', val: 'Group 2', $order: 4}
96+
'Group 1': {label: 'Group 1', val: 'Group 1', $order: 3, dis: false},
97+
'Group 2': {label: 'Group 2', val: 'Group 2', $order: 4, dis: false}
98+
}, '2');
99+
});
100+
it('should allow respect disabled flags of option and optgroup', function() {
101+
var test = setup_test(['<select>',
102+
'<optgroup label="Group 1">',
103+
'<option value="a" disabled>Item A</option>',
104+
'<option value="b">Item B</option>',
105+
'</optgroup>',
106+
'<optgroup label="Group 2" disabled>',
107+
'<option value="a">Item A</option>',
108+
'<option value="b">Item B</option>',
109+
'</optgroup>',
110+
'</select>'].join(''), {
111+
optgroupValueField: 'val',
112+
optgroupField: 'grp',
113+
disabledField: 'dis'
114+
});
115+
assert.deepEqual(test.selectize.options, {
116+
'a': {text: 'Item A', value: 'a', grp: ['Group 1', 'Group 2'], $order: 1, dis: true},
117+
'b': {text: 'Item B', value: 'b', grp: ['Group 1', 'Group 2'], $order: 2, dis: false}
87118
});
119+
assert.deepEqual(test.selectize.optgroups, {
120+
'Group 1': {label: 'Group 1', val: 'Group 1', $order: 3, dis: false},
121+
'Group 2': {label: 'Group 2', val: 'Group 2', $order: 4, dis: true}
122+
}, '2');
88123
});
89124
it('should add options in text form (no html entities)', function() {
90125
var test = setup_test('<select><option selected value="a">&lt;hi&gt;</option></select>', {});
@@ -163,6 +198,19 @@
163198
done();
164199
}, 0);
165200
});
201+
it('should respect option disabled flag', function (done) {
202+
var test = setup_test(['<select>',
203+
'<option value="a">Item A</option>',
204+
'<option value="b" disabled>Item B</option>',
205+
'</select>'].join(''), {});
206+
207+
test.selectize.refreshOptions(true);
208+
window.setTimeout(function() {
209+
expect(test.selectize.$dropdown.find('.option')).to.has.length(2);
210+
expect(test.selectize.$dropdown.find('[data-selectable]')).to.has.length(1);
211+
done();
212+
}, 0);
213+
});
166214
describe('getValue()', function() {
167215
it('should return "" when empty', function() {
168216
var test = setup_test('<select>', {});

0 commit comments

Comments
 (0)