How do I add an unselectable and customizable placeholder to a select box
14,435
Solution 1
We can do this easy by using angular's powerful directive system to extend basic html.
app.directive('select', function($interpolate) {
return {
restrict: 'E',
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var defaultOptionTemplate;
scope.defaultOptionText = attrs.defaultOption || 'Select...';
defaultOptionTemplate = '<option value="" disabled selected style="display: none;">{{defaultOptionText}}</option>';
elem.prepend($interpolate(defaultOptionTemplate)(scope));
}
};
});
With this, we can now do the following:
<select ng-model="number"
ng-options="item.id as item.label for item in values">
</select>
This will create a select box with an unselectable placeholder that says "Select..."
If we want a custom placeholder we can simply do this:
<select ng-model="dog"
ng-options="dog.id as dog.label for dog in dogs"
default-option="What's your favorite dog?">
</select>
This will create a select box with an unselectable placeholder that says "What's your favorite dog?"
Plunker Example (in coffeescript): http://plnkr.co/edit/zIs0W7AdYnHnuV21UbwK
Plunker Example (in javascript): http://plnkr.co/edit/6VNJ8GUWK50etjUAFfey
Solution 2
You can also do it directly in the html.
<select ng-model="number"
ng-options="item.id as item.label for item in values">
<option value="" disabled selected style="display: none;"> Default Number </option>
></select>
Related videos on Youtube
Author by
codevinsky
Updated on September 15, 2022Comments
-
codevinsky almost 2 years
I've got a pretty large app that has many dropdowns. I don't want to have to modify my data to add a blank option and I don't want the placeholder to be selectable. What's the best approach?
-
Mathew Berg over 10 yearsThis will not work if default-option is dynamic: plnkr.co/edit/SNMYtCcjTY5OVYup5TxX?p=preview
-
Mathew Berg over 10 yearsNo.... it doesn't: plnkr.co/edit/q4Kbymxgw3vY6dcXQW1b?p=preview If defaultOption gets set at a later time then the element will not render the updated option. In my example defaultOption gets set to "TEXT SHOULD BE THIS" but you never see it update because you've already created it.
-
Mathew Berg over 10 yearsAlso, did you look at my plunkr? You'll see that the localize filter is not firing
-
codevinsky over 10 yearsA few things here: 1. Your directive isn't firing because your directive is wrong. It should be a filter. 2. If you look at the select over-ride directive, you'll notice that the defaultOption is being set based on an attribute, not a scoped value. Because of this, it has to be a string. However, because angular is so awesome, you can use an expression there like so: plnkr.co/edit/aWUA2lXEeFqhCmZIdr1d
-
Mathew Berg over 10 yearsAs mentioned, look at the latest plunker, if you update the value after the directive is rendered, nothing is changing. Specifically look at the part in the setTimeout.
-
Mathew Berg over 10 yearsHere's my suggestion on a good place to start: plnkr.co/edit/p5bv4jyEpABgKUtVhqOS?p=preview
-
adriendenat about 10 yearsThis doesn't work anymore since Angular 1.2.16. The first option is selected as default.
-
Xinan almost 8 yearsthis is the most elegant way I've ever seen