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

Commit 6372027

Browse files
crisbetoSplaktar
andauthored
feat(select): add the ability to pre-select the only option in the list (#9940)
* feat(select): add the ability to pre-select the only option in the list * Adds the `md-select-only-option` attribute, that will cause `<md-select>` to pre-select the first option, if it only has one option in it's list. * Fixes an ugly way of adding extra classes to the select container. * Removes a few variables and arguments that weren't being used. Fixes #9626. Co-authored-by: Michael Prentice <[email protected]>
1 parent 88fe27e commit 6372027

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

src/components/select/select.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ angular.module('material.components.select', [
6464
* is present.
6565
* @param {string=} md-container-class Class list to get applied to the `.md-select-menu-container`
6666
* element (for custom styling).
67+
* @param {string=} md-select-only-option If specified, a `<md-select>` will automatically select
68+
* it's first option, if it only has one.
6769
*
6870
* @usage
6971
* With a placeholder (label and aria-label are added dynamically)
@@ -157,9 +159,6 @@ angular.module('material.components.select', [
157159
*/
158160
function SelectDirective($mdSelect, $mdUtil, $mdConstant, $mdTheming, $mdAria, $parse, $sce,
159161
$injector) {
160-
var keyCodes = $mdConstant.KEY_CODE;
161-
var NAVIGATION_KEYS = [keyCodes.SPACE, keyCodes.ENTER, keyCodes.UP_ARROW, keyCodes.DOWN_ARROW];
162-
163162
return {
164163
restrict: 'E',
165164
require: ['^?mdInputContainer', 'mdSelect', 'ngModel', '?^form'],
@@ -598,12 +597,9 @@ function SelectDirective($mdSelect, $mdUtil, $mdConstant, $mdTheming, $mdAria, $
598597
element[0].querySelector('.md-select-menu-container')
599598
);
600599
selectScope = scope;
601-
if (attrs.mdContainerClass) {
602-
var value = selectContainer[0].getAttribute('class') + ' ' + attrs.mdContainerClass;
603-
selectContainer[0].setAttribute('class', value);
604-
}
600+
attrs.mdContainerClass && selectContainer.addClass(attrs.mdContainerClass);
605601
selectMenuCtrl = selectContainer.find('md-select-menu').controller('mdSelectMenu');
606-
selectMenuCtrl.init(ngModelCtrl, attrs.ngModel);
602+
selectMenuCtrl.init(ngModelCtrl, attrs);
607603
element.on('$destroy', function() {
608604
selectContainer.remove();
609605
});
@@ -826,9 +822,9 @@ function SelectMenuDirective($parse, $mdUtil, $mdConstant, $mdTheming) {
826822
}
827823
};
828824

829-
self.init = function(ngModel, binding) {
825+
self.init = function(ngModel, parentAttrs) {
830826
self.ngModel = ngModel;
831-
self.modelBinding = binding;
827+
self.modelBinding = parentAttrs.ngModel;
832828

833829
// Setup a more robust version of isEmpty to ensure value is a valid option
834830
self.ngModel.$isEmpty = function($viewValue) {
@@ -871,6 +867,21 @@ function SelectMenuDirective($parse, $mdUtil, $mdConstant, $mdTheming) {
871867
}
872868
return value + '';
873869
}
870+
871+
if (parentAttrs.hasOwnProperty('mdSelectOnlyOption')) {
872+
$mdUtil.nextTick(function() {
873+
var optionKeys = Object.keys(self.options);
874+
875+
if (optionKeys.length === 1) {
876+
var option = self.options[optionKeys[0]];
877+
878+
self.deselect(Object.keys(self.selected)[0]);
879+
self.select(self.hashGetter(option.value), option.value);
880+
self.refreshViewValue();
881+
self.ngModel.$setPristine();
882+
}
883+
}, false);
884+
}
874885
};
875886

876887
/**

src/components/select/select.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,41 @@ describe('<md-select>', function() {
373373
expect($rootScope.testForm.defaultSelect.$error).toEqual({});
374374
});
375375
});
376+
377+
describe('mdSelectOnlyOption support', function() {
378+
var $rootScope, $timeout;
379+
380+
beforeEach(inject(function($injector) {
381+
$rootScope = $injector.get('$rootScope');
382+
$timeout = $injector.get('$timeout');
383+
}));
384+
385+
it('should select the first option if it only has one option', function() {
386+
setupSelect('ng-model="val" md-select-only-option', [1]);
387+
$timeout.flush();
388+
expect($rootScope.val).toBe(1);
389+
});
390+
391+
it('should work with `multiple`', function() {
392+
setupSelectMultiple('ng-model="val" md-select-only-option', [1]);
393+
$timeout.flush();
394+
expect($rootScope.val).toEqual([1]);
395+
});
396+
397+
it('should not do anything if there is more than one option', function() {
398+
setupSelect('ng-model="val" md-select-only-option', [1, 2, 3]);
399+
$timeout.flush();
400+
expect($rootScope.val).toBeUndefined();
401+
});
402+
403+
it('should keep the ngModel pristine', function() {
404+
var el = setupSelect('ng-model="val" md-select-only-option', [1]);
405+
var ngModel = el.find('md-select').controller('ngModel');
406+
407+
$timeout.flush();
408+
expect(ngModel.$pristine).toBe(true);
409+
});
410+
});
376411
});
377412

378413
describe('input container', function() {

0 commit comments

Comments
 (0)