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

Commit b895c80

Browse files
committed
fix(ngValue): set value property instead of attr
in case of input element set value using property instead of attribute fixed #13984
1 parent b8b5b88 commit b895c80

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

src/.jshintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
"jqLiteParseHTML": false,
141141
"jqLiteWrapNode": false,
142142
"getBooleanAttrName": false,
143+
"getValueAttrName": false,
143144
"getAliasedAttrName": false,
144145
"createEventHandler": false,
145146
"JQLitePrototype": false,

src/jqLite.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
addEventListenerFn: true,
1616
removeEventListenerFn: true,
1717
BOOLEAN_ATTR: true,
18+
VALUE_ATTR: true,
1819
ALIASED_ATTR: true,
1920
*/
2021

@@ -577,6 +578,15 @@ var BOOLEAN_ELEMENTS = {};
577578
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
578579
BOOLEAN_ELEMENTS[value] = true;
579580
});
581+
582+
var VALUE_ATTR = {};
583+
VALUE_ATTR['value'] = 'value';
584+
585+
var VALUE_ELEMENTS = {};
586+
forEach('input,textarea'.split(','), function(value) {
587+
VALUE_ELEMENTS[value] = true;
588+
});
589+
580590
var ALIASED_ATTR = {
581591
'ngMinlength': 'minlength',
582592
'ngMaxlength': 'maxlength',
@@ -593,6 +603,14 @@ function getBooleanAttrName(element, name) {
593603
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
594604
}
595605

606+
function getValueAttrName(element, name) {
607+
// check dom last since we will most likely fail on name
608+
var valueAttr = VALUE_ATTR[name.toLowerCase()];
609+
610+
// booleanAttr is here twice to minimize DOM access
611+
return valueAttr && VALUE_ELEMENTS[nodeName_(element)] && valueAttr;
612+
}
613+
596614
function getAliasedAttrName(name) {
597615
return ALIASED_ATTR[name];
598616
}

src/ng/compile.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,13 +1322,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13221322

13231323
var node = this.$$element[0],
13241324
booleanKey = getBooleanAttrName(node, key),
1325+
valueKey = getValueAttrName(node, key),
13251326
aliasedKey = getAliasedAttrName(key),
13261327
observer = key,
13271328
nodeName;
13281329

1329-
if (booleanKey) {
1330+
if (booleanKey || valueKey) {
13301331
this.$$element.prop(key, value);
1331-
attrName = booleanKey;
1332+
attrName = booleanKey ? booleanKey : valueKey;
13321333
} else if (aliasedKey) {
13331334
this[aliasedKey] = value;
13341335
observer = aliasedKey;

test/ng/directive/inputSpec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,26 @@ describe('input', function() {
30463046
expect(inputElm[0].getAttribute('value')).toBe('something');
30473047
});
30483048

3049+
it('should update the input "value" property and attribute after change the "value" property', function() {
3050+
var inputElm = helper.compileInput('<input type="text" ng-value="value">');
3051+
3052+
$rootScope.$apply(function() {
3053+
$rootScope.value = 'something';
3054+
});
3055+
expect(inputElm[0].value).toBe('something');
3056+
expect(inputElm[0].getAttribute('value')).toBe('something');
3057+
3058+
helper.changeInputValueTo('newValue');
3059+
3060+
$rootScope.$apply(function() {
3061+
$rootScope.value = 'anotherValue';
3062+
});
3063+
expect(inputElm[0].value).toBe('anotherValue');
3064+
expect(inputElm[0].getAttribute('value')).toBe('anotherValue');
3065+
3066+
3067+
});
3068+
30493069

30503070
it('should evaluate and set constant expressions', function() {
30513071
var inputElm = helper.compileInput('<input type="radio" ng-model="selected" ng-value="true">' +

0 commit comments

Comments
 (0)