Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(select): placeholder (empty option) is lost in IE9 #2188

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/ng/directive/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {

if (multiple) {
selectedSet = new HashMap(modelValue);
} else if (modelValue === null || nullOption) {
// if we are not multiselect, and we are null then we have to add the nullOption
optionGroups[''].push({selected:modelValue === null, id:'', label:''});
selectedSet = true;
}

// We now build up the list of options we need (we merge later)
Expand All @@ -422,9 +418,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
selected: selected // determine if we should be selected
});
}
if (!multiple && !selectedSet) {
// nothing was selected, we have to insert the undefined item
optionGroups[''].unshift({id:'?', label:'', selected:true});
if (!multiple) {
if (nullOption || modelValue === null) {
// insert null option if we have a placeholder, or the model is null
optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
} else if (!selectedSet) {
// option could not be found, we have to insert the undefined item
optionGroups[''].unshift({id:'?', label:'', selected:true});
}
}

// Now we need to update the list of DOM nodes to match the optionGroups we computed above
Expand Down Expand Up @@ -468,7 +469,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
if (existingOption.id !== option.id) {
lastElement.val(existingOption.id = option.id);
}
if (existingOption.element.selected !== option.selected) {
// lastElement.prop('selected') provided by jQuery has side-effects
if (lastElement[0].selected !== option.selected) {
lastElement.prop('selected', (existingOption.selected = option.selected));
}
} else {
Expand Down
28 changes: 28 additions & 0 deletions test/ng/directive/selectSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,19 @@ describe('select', function() {
expect(option.attr('id')).toBe('road-runner');
expect(option.attr('custom-attr')).toBe('custom-attr');
});

it('should be selected, if it is available and no other option is selected', function() {
// selectedIndex is used here because jqLite incorrectly reports element.val()
scope.$apply(function() {
scope.values = [{name: 'A'}];
});
createSingleSelect(true);
// ensure the first option (the blank option) is selected
expect(element[0].selectedIndex).toEqual(0);
scope.$digest();
// ensure the option has not changed following the digest
expect(element[0].selectedIndex).toEqual(0);
});
});


Expand Down Expand Up @@ -1099,6 +1112,21 @@ describe('select', function() {
browserTrigger(element, 'change');
expect(scope.selected).toEqual(['0']);
});

it('should deselect all options when model is emptied', function() {
createMultiSelect();
scope.$apply(function() {
scope.values = [{name: 'A'}, {name: 'B'}];
scope.selected = [scope.values[0]];
});
expect(element.find('option')[0].selected).toEqual(true);

scope.$apply(function() {
scope.selected.pop();
});

expect(element.find('option')[0].selected).toEqual(false);
})
});


Expand Down