Skip to content

Commit f9144f0

Browse files
committed
fix(ng:options): compile null/blank option tag
Fixes angular#562
1 parent e9cd802 commit f9144f0

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

src/widget/select.js

+18-17
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,12 @@ angularWidget('select', function(element){
243243

244244
// find existing special options
245245
forEach(selectElement.children(), function(option){
246-
var opt;
247246
if (option.value == '') {
248-
opt = jqLite(option);
249247
// User is allowed to select the null.
250-
nullOption = {label:opt.text(), id:'', bindTemplate: opt.attr('ng:bind-template')};
248+
// save <option> element
249+
nullOption = jqLite(option).remove();
250+
// compile it in model scope
251+
compile(nullOption)(modelScope);
251252
}
252253
});
253254
selectElement.html(''); // clear contents
@@ -318,7 +319,7 @@ angularWidget('select', function(element){
318319
selectedSet = new HashMap(modelValue);
319320
} else if (modelValue === null || nullOption) {
320321
// if we are not multiselect, and we are null then we have to add the nullOption
321-
optionGroups[''].push(extend({selected:modelValue === null, id:'', label:''}, nullOption));
322+
optionGroups[''].push({selected:modelValue === null, id:'', label:''});
322323
selectedSet = true;
323324
}
324325

@@ -393,19 +394,19 @@ angularWidget('select', function(element){
393394
}
394395
} else {
395396
// grow elements
396-
// jQuery(v1.4.2) Bug: We should be able to chain the method calls, but
397-
// in this version of jQuery on some browser the .text() returns a string
398-
// rather then the element.
399-
(element = optionTemplate.clone())
400-
.val(option.id)
401-
.attr('selected', option.selected)
402-
.text(option.label);
403-
404-
// if it's a nullOption, compile it
405-
if (option.id === '') {
406-
if (option.bindTemplate)
407-
element.attr('ng:bind-template', option.bindTemplate);
408-
compile(element)(modelScope);
397+
398+
// if it's a null option
399+
if (option.id === '' && nullOption) {
400+
// put back the pre-compiled element
401+
element = nullOption;
402+
} else {
403+
// jQuery(v1.4.2) Bug: We should be able to chain the method calls, but
404+
// in this version of jQuery on some browser the .text() returns a string
405+
// rather then the element.
406+
(element = optionTemplate.clone())
407+
.val(option.id)
408+
.attr('selected', option.selected)
409+
.text(option.label);
409410
}
410411

411412
existingOptions.push(existingOption = {

test/widget/selectSpec.js

+33-2
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ describe('select', function() {
431431
});
432432

433433
describe('blank option', function () {
434-
434+
// redefine createSelect for this test a bit
435435
function createSelect(attrs, blank, unknown){
436436
var html = '<select';
437437
forEach(attrs, function(value, key){
@@ -442,7 +442,7 @@ describe('select', function() {
442442
}
443443
});
444444
html += '>' +
445-
(blank ? blank : '') +
445+
(blank ? blank : '') + // blank can be specified in details
446446
(unknown ? unknown : '') +
447447
'</select>';
448448
select = jqLite(html);
@@ -495,6 +495,37 @@ describe('select', function() {
495495
expect(option.val()).toBe('');
496496
expect(option.text()).toBe('blank is so blank');
497497
});
498+
499+
it('should be compiled from ng:bind attribute if given', function () {
500+
var option;
501+
502+
createSingleSelect('<option value="" ng:bind="blankTemplate"></option>');
503+
scope.blankTemplate = 'is blank';
504+
scope.values = [{name:'A'}];
505+
scope.$digest();
506+
507+
// check blank option is first and is compiled
508+
expect(select.find('option').length == 2);
509+
option = jqLite(select.find('option')[0]);
510+
expect(option.val()).toBe('');
511+
expect(option.text()).toBe('is blank');
512+
});
513+
514+
it('should be rendered with the attributes preserved', function () {
515+
var option;
516+
517+
createSingleSelect('<option value="" class="coyote" id="road-runner" custom-attr="custom-attr">{{blankTemplate}}</option>');
518+
scope.blankTemplate = 'is blank';
519+
scope.$digest();
520+
521+
// check blank option is first and is compiled
522+
option = jqLite(select.find('option')[0]);
523+
expect(option.hasClass('coyote')).toBeTruthy();
524+
expect(option.attr('id')).toBe('road-runner');
525+
expect(option.attr('custom-attr')).toBe('custom-attr');
526+
});
527+
528+
498529
});
499530

500531
describe('on change', function() {

0 commit comments

Comments
 (0)