Reputation: 14531
I'm wanting to have an md-select that the user can clear the selected value. E.g. they select a value but decide they want to clear their selection.
The behavior of md-select is to select the first entry in the options. I'd like to make it return to the state where no selection was made.
I'm imagining I probably need a custom directive for this, so I've implemented a simple directive which listens to the keydown for the DELETE key.
HTML:
<div ng-controller="AppCtrl as ctrl" class="md-padding selectdemoBasicUsage" ng-cloak="" ng-app="MyApp">
<div>
<h1 class="md-title">Select a state</h1>
<span>I want the DELETE key to be able to clear the selected state.</span>
<div layout="row">
<md-input-container>
<label>State</label>
<md-select ng-model="ctrl.userState" select-clear>
<md-option ng-repeat="state in ctrl.states" value="{{state.abbrev}}">
{{state.abbrev}}
</md-option>
</md-select>
</md-input-container>
</div>
</div>
</div>
JS:
(function () {
'use strict';
angular
.module('MyApp',['ngMaterial', 'ngMessages'])
.controller('AppCtrl', function() {
this.userState = '';
this.states = ('AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD MA MI MN MS ' +
'MO MT NE NV NH NJ NM NY NC ND OH OK OR PA RI SC SD TN TX UT VT VA WA WV WI ' +
'WY').split(' ').map(function (state) { return { abbrev: state }; });
})
.directive('selectClear', function() {
return {
restrict: 'A',
require: 'ngModel',
link : function(scope, iElement, iAttrs, ngModelCtrl) {
iElement.bind('keydown', function(event) {
if (event.keyCode === 46) {
ngModelCtrl.$setViewValue('', event);
}
})
}
}
});
})();
Here's my code pen:
http://codepen.io/craigsh/pen/GorpVV
But it doesn't work - when the DELETE key is pressed the first options value is selected.
Upvotes: 5
Views: 19664
Reputation: 571
I'm also late but add a template selection variable in the html:
<button (click)="selectAll(selectField)">Deselect All</button>
<mat-select #selectField>
<mat-option
*ngFor="let option of options | async"
[value]="option.id">
{{option.text}}
</mat-option>
</mat-select>
and in the ts:
public deselectAll() {
selectField.value = [];
}
Deselects all checkboxes and resets material select.
Upvotes: 0
Reputation: 1919
I'm late and this might be an evolution in the angular-material lib but there is the possibility of adding the md-option-empty
to an md-option
to mark it as an equivalent of empty.
<md-option md-option-empty ng-value="undefined">No selection</md-option>
This will be display a "No selection" option in the list, and once selected, will make the input empty (and pass undefined
to the ng-model
).
Cf doc
Upvotes: 0
Reputation: 6434
The Angular Material Select demo has a 'State' dropdown which replicates the functionality you need: https://material.angularjs.org/latest/demo/select
The code they use is:
<md-input-container>
<label>State</label>
<md-select ng-model="ctrl.userState">
<md-option><em>None</em></md-option>
<md-option ng-repeat="state in ctrl.states" ng-value="state.abbrev" ng-disabled="$index === 1">
{{state.abbrev}}
</md-option>
</md-select>
</md-input-container>
Upvotes: 0
Reputation: 4628
I made a simple directive to take care of this for me.
angular.module 'app.components'
.directive 'deleteWhenBlank', ->
directive =
restrict: 'A'
require: ['ngModel']
scope:
model: '=ngModel'
link: ($scope, el, attrs) ->
$scope.$watch('model', (value) ->
unless value
delete $scope.model
)
I use it like so and it works for the examples shown. As soon as the md-select looses focus the model is set to null.
<md-select ng-model='some.model' delete-when-blank>
<md-option value=''></md-option>
<md-option value='{{undefined}}'></md-option>
<md-option value='{{null}}'></md-option>
</md-select>
Upvotes: 0
Reputation: 14531
In the end I implemented a directive which works pretty nicely:
.directive('selectClear', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link : function(scope, iElement, iAttrs) {
iElement.bind('keydown', function(event) {
if (event.keyCode === 46) {
event.preventDefault();
event.stopPropagation();
scope.$evalAsync(function() {
var modelGetter = $parse(iAttrs['ngModel']),
modelSetter = modelGetter.assign;
modelSetter(scope, '');
});
}
})
}
}
}
Upvotes: 0
Reputation: 140
In the Angular-material docs they set the value of your md-select to undefined
$scope.clearValue = function() {
$scope.myModel = undefined;
};
You can check it too in their site https://material.angularjs.org/latest/demo/select see the Validations section
Upvotes: 6
Reputation: 17657
I suggest to use a "null" option in addition to the states list:
<md-select ng-model="ctrl.userState" select-clear>
<md-option value="{{null}}">
-- select a state --
</md-option>
<md-option ng-repeat="state in ctrl.states" value="{{state.abbrev}}">
{{state.abbrev}}
</md-option>
</md-select>
so the working snippet (adapted from yours) could be:
http://codepen.io/beaver71/pen/LGxqjp
Upvotes: 8