aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Balboni2014-01-26 16:17:36 -0500
committerCaitlin Potter2014-03-18 23:18:42 -0400
commitf40f54c6da4a5399fe18a89d068634bb491e9f1a (patch)
tree6681e53e65a05d54c53dd1214d549785afa1a63b
parent37bc5ef4d87f19da47d3ab454c43d1e532c4f924 (diff)
downloadangular.js-f40f54c6da4a5399fe18a89d068634bb491e9f1a.tar.bz2
fix(select): avoid checking option element selected properties in render
In Firefox, hovering over an option in an open select menu updates the selected property of option elements. This means that when a render is triggered by the digest cycle, and the list of options is being rendered, the selected properties are reset to the values from the model and the option hovered over changes. This fix changes the code to only use DOM elements' selected properties in a comparison when a change event has been fired. Otherwise, the internal new and existing option arrays are used. Closes #2448 Closes #5994
-rw-r--r--src/ng/directive/select.js8
-rw-r--r--test/ng/directive/selectSpec.js21
2 files changed, 28 insertions, 1 deletions
diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js
index 0b562cca..628d2177 100644
--- a/src/ng/directive/select.js
+++ b/src/ng/directive/select.js
@@ -394,6 +394,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
value = valueFn(scope, locals);
}
}
+ // Update the null option's selected property here so $render cleans it up correctly
+ if (optionGroupsCache[0].length > 1) {
+ if (optionGroupsCache[0][1].id !== key) {
+ optionGroupsCache[0][1].selected = false;
+ }
+ }
}
ctrl.$setViewValue(value);
});
@@ -531,7 +537,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
lastElement.val(existingOption.id = option.id);
}
// lastElement.prop('selected') provided by jQuery has side-effects
- if (lastElement[0].selected !== option.selected) {
+ if (existingOption.selected !== option.selected) {
lastElement.prop('selected', (existingOption.selected = option.selected));
}
} else {
diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js
index 6fcd1fe0..d270f438 100644
--- a/test/ng/directive/selectSpec.js
+++ b/test/ng/directive/selectSpec.js
@@ -733,6 +733,27 @@ describe('select', function() {
expect(sortedHtml(options[2])).toEqual('<option value="1">3</option>');
});
+ it('should not update selected property of an option element on digest with no change event',
+ function() {
+ createSingleSelect();
+
+ scope.$apply(function() {
+ scope.values = [{name: 'A'}, {name: 'B'}, {name: 'C'}];
+ scope.selected = scope.values[0];
+ });
+
+ var options = element.find('option');
+ var optionToSelect = options.eq(1);
+
+ expect(optionToSelect.text()).toBe('B');
+
+ optionToSelect.prop('selected', true);
+ scope.$digest();
+
+ expect(optionToSelect.prop('selected')).toBe(true);
+ expect(scope.selected).toBe(scope.values[0]);
+ });
+
describe('binding', function() {
it('should bind to scope value', function() {