diff --git a/src/components/select/select.js b/src/components/select/select.js index 90257bff19..6d3ee2f497 100755 --- a/src/components/select/select.js +++ b/src/components/select/select.js @@ -1170,6 +1170,12 @@ function SelectMenuDirective($parse, $mdUtil, $mdConstant, $mdTheming) { * @param {string=} value Attribute to set the value of the option. * @param {expression=} ng-repeat * AngularJS directive that instantiates a template once per item from a collection. + * @param {expression=} ng-selected + * AngularJS directive that adds the `selected` attribute to the option when the expression + * evaluates as truthy. + * + * **Note:** Unlike native `option` elements used with AngularJS, `md-option` elements + * watch their `selected` attributes for changes and trigger model value changes on `md-select`. * @param {boolean=} md-option-empty If the attribute exists, mark the option as "empty" allowing * the option to clear the select and put it back in it's default state. You may supply this * attribute on any option you wish, however, it is automatically applied to an option whose `value` @@ -1258,6 +1264,22 @@ function OptionDirective($mdButtonInkRipple, $mdUtil, $mdTheming) { } }); + scope.$$postDigest(function() { + attrs.$observe('selected', function(selected) { + if (!angular.isDefined(selected)) return; + if (typeof selected == 'string') selected = true; + if (selected) { + if (!selectMenuCtrl.isMultiple) { + selectMenuCtrl.deselect(Object.keys(selectMenuCtrl.selected)[0]); + } + selectMenuCtrl.select(optionCtrl.hashKey, optionCtrl.value); + } else { + selectMenuCtrl.deselect(optionCtrl.hashKey); + } + selectMenuCtrl.refreshViewValue(); + }); + }); + $mdButtonInkRipple.attach(scope, element); configureAria(); @@ -1265,7 +1287,7 @@ function OptionDirective($mdButtonInkRipple, $mdUtil, $mdTheming) { * @param {*} newValue the option's new value * @param {*=} oldValue the option's previous value * @param {boolean=} prevAttempt true if this had to be attempted again due to an undefined - * hashGetter on the selectCtrl, undefined otherwise. + * hashGetter on the selectMenuCtrl, undefined otherwise. */ function setOptionValue(newValue, oldValue, prevAttempt) { if (!selectMenuCtrl.hashGetter) { diff --git a/src/components/select/select.spec.js b/src/components/select/select.spec.js index 99c3cf428b..7fa4200777 100755 --- a/src/components/select/select.spec.js +++ b/src/components/select/select.spec.js @@ -738,6 +738,15 @@ describe('', function() { expect(selectedOptions(el).length).toBe(0); }); + it('supports ng-selected on md-options', function() { + var el = setupSelect('ng-model="$root.model"', ['a','b','c'], false, $rootScope, null, + '$index === 2'); + + expect(selectedOptions(el).length).toBe(1); + expect(el.find('md-option').eq(2).attr('selected')).toBe('selected'); + expect($rootScope.model).toBe('c'); + }); + it('supports circular references', function() { var opts = [{ id: 1 }, { id: 2 }]; opts[0].refs = opts[1]; @@ -1688,13 +1697,13 @@ describe('', function() { }); } - function setupSelect(attrs, options, skipLabel, scope, optCompileOpts) { + function setupSelect(attrs, options, skipLabel, scope, optCompileOpts, ngSelectedExpression) { var el; var template = '' + '' + (skipLabel ? '' : '') + '' + - optTemplate(options, optCompileOpts) + + optTemplate(options, optCompileOpts, ngSelectedExpression) + '' + ''; @@ -1713,13 +1722,21 @@ describe('', function() { return toReturn; } - function optTemplate(options, compileOpts) { + /** + * @param {any[]=} options Array of option values to create md-options from + * @param {object=} compileOpts + * @param {object=} ngSelectedExpression If defined, sets the expression used by ng-selected. + * @return {string} template containing the generated md-options + */ + function optTemplate(options, compileOpts, ngSelectedExpression) { var optionsTpl = ''; + var ngSelectedTemplate = ngSelectedExpression ? ' ng-selected="' + ngSelectedExpression + '"' : ''; if (angular.isArray(options)) { $rootScope.$$values = options; var renderValueAs = compileOpts ? compileOpts.renderValueAs || 'value' : 'value'; - optionsTpl = '
{{' + renderValueAs + '}}
'; + optionsTpl = '' + + '
{{' + renderValueAs + '}}
'; } else if (angular.isString(options)) { optionsTpl = options; } @@ -1739,7 +1756,7 @@ describe('', function() { } function openSelect(el) { - if (el[0].nodeName != 'MD-SELECT') { + if (el[0].nodeName !== 'MD-SELECT') { el = el.find('md-select'); } try {