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

fix(select): don't support binding to select[multiple] #3337

Closed
wants to merge 1 commit into from
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
5 changes: 5 additions & 0 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,11 @@ function $CompileProvider($provide) {
if (!interpolateFn) return;


if (name === "multiple" && nodeName_(node) === "SELECT") {
throw new $compileMinErr("selmulti", "Binding to the multiple attribute is not supported. Element: {0}",
startingTag(node));
}

directives.push({
priority: 100,
compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
Expand Down
39 changes: 3 additions & 36 deletions src/ng/directive/booleanAttrs.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,42 +199,6 @@
*/


/**
* @ngdoc directive
* @name ng.directive:ngMultiple
* @restrict A
*
* @description
* The HTML specs do not require browsers to preserve the special attributes such as multiple.
* (The presence of them means true and absence means false)
* This prevents the angular compiler from correctly retrieving the binding expression.
* To solve this problem, we introduce the `ngMultiple` directive.
*
* @example
<doc:example>
<doc:source>
Check me check multiple: <input type="checkbox" ng-model="checked"><br/>
<select id="select" ng-multiple="checked">
<option>Misko</option>
<option>Igor</option>
<option>Vojta</option>
<option>Di</option>
</select>
</doc:source>
<doc:scenario>
it('should toggle multiple', function() {
expect(element('.doc-example-live #select').prop('multiple')).toBeFalsy();
input('checked').check();
expect(element('.doc-example-live #select').prop('multiple')).toBeTruthy();
});
</doc:scenario>
</doc:example>
*
* @element SELECT
* @param {expression} ngMultiple Angular expression that will be evaluated.
*/


/**
* @ngdoc directive
* @name ng.directive:ngReadonly
Expand Down Expand Up @@ -334,6 +298,9 @@ var ngAttributeAliasDirectives = {};

// boolean attrs are evaluated
forEach(BOOLEAN_ATTR, function(propName, attrName) {
// binding to multiple is not supported
if (propName == "multiple") return;

var normalized = directiveNormalize('ng-' + attrName);
ngAttributeAliasDirectives[normalized] = function() {
return {
Expand Down
34 changes: 24 additions & 10 deletions test/ng/directive/booleanAttrsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,6 @@ describe('boolean attr directives', function() {
}));


it('should bind multiple', inject(function($rootScope, $compile) {
element = $compile('<select ng-multiple="isMultiple"></select>')($rootScope)
$rootScope.isMultiple=false;
$rootScope.$digest();
expect(element.attr('multiple')).toBeFalsy();
$rootScope.isMultiple='multiple';
$rootScope.$digest();
expect(element.attr('multiple')).toBeTruthy();
}));

it('should bind open', inject(function($rootScope, $compile) {
element = $compile('<details ng-open="isOpen"></details>')($rootScope)
$rootScope.isOpen=false;
Expand All @@ -84,6 +74,30 @@ describe('boolean attr directives', function() {
$rootScope.$digest();
expect(element.attr('open')).toBeTruthy();
}));


describe('multiple', function() {
it('should NOT bind to multiple via ngMultiple', inject(function($rootScope, $compile) {
element = $compile('<select ng-multiple="isMultiple"></select>')($rootScope)
$rootScope.isMultiple=false;
$rootScope.$digest();
expect(element.attr('multiple')).toBeFalsy();
$rootScope.isMultiple='multiple';
$rootScope.$digest();
expect(element.attr('multiple')).toBeFalsy(); // ignore
}));


it('should throw an exception if binding to multiple attribute', inject(function($rootScope, $compile) {
if (msie < 9) return; //IE8 doesn't support biding to boolean attributes

expect(function() {
$compile('<select multiple="{{isMultiple}}"></select>')
}).toThrow('[$compile:selmulti] Binding to the multiple attribute is not supported. ' +
'Element: <select multiple="{{isMultiple}}">');

}));
});
});


Expand Down