Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add two extra options to a select list with ngOptions on it

I have a bunch of select lists and I'm trying to add a "none" and a title option to them. The code looks like so:

<select ng-options="value.name for value in values" ng-model="selection">
    <option value="" disabled>{{title}}</option>
    <option value="">None</option>
</select>

For right now, I cannot add them to the data so I am trying to find a way to get this working. When I load them for the first time, the "none" option is not there. The title is there and works as intended, but it seems I cannot add two blank entries to this select list.

The easiest way would be to have the "none" option added to the data but it's not a possibility for me. Is there a proper way to achieve what I want?

like image 651
ajmajmajma Avatar asked Jun 02 '15 19:06

ajmajmajma


People also ask

What is ngOptions?

The ngOptions attribute can be used to dynamically generate a list of <option> elements for the <select> element using the array or object obtained by evaluating the ngOptions comprehension expression.

What is the difference between Ng-options and Ng-repeat?

ng-options is the directive which is designed specifically to populate the items of a dropdown list. One major advantage using ng-options for the dropdown is, it allows us to pass the selected value to be an object. Whereas, using ng-repeat the selected value can only be string.

How do I set default selected value in ng-options?

Use ng-init to set default value for ng-options .

How does ng-options work?

The ng-options directive fills a <select> element with <options>. The ng-options directive uses an array to fill the dropdown list. In many cases it would be easier to use the ng-repeat directive, but you have more flexibility when using the ng-options directive.


2 Answers

That's correct, you can only have one hard-coded element. <option ng-repeat> can technically be done, but that method only cleanly supports binding to strings, so it would get very kludgey to bind to objects, as you're doing.

You say you can't add "None" to the data, but you can do the next best thing: prepend it to the array ng-options is iterating across, using a filter:

app.filter('addNone', function () {
    return function(input) {
        var newArray = input.slice(0); //clone the array, or you'll end up with a new "None" option added to your "values" array on every digest cycle.
        newArray.unshift({ name: "None" });
        return newArray;
    };
})

Then use the filter like this:

 <select class="form-control" ng-options="value.name as value.name for value in filter.values | addNone" ng-model="filter.selected" ng-change="goSearch()">
                    <option value="" disabled>{{filter.name}}</option>
                </select>
like image 144
Kevin Crumley Avatar answered Oct 12 '22 13:10

Kevin Crumley


It's impossible with ngOptions, as explicitly mentioned in the documentation (emphasis mine):

Optionally, a single hard-coded <option> element, with the value set to an empty string, can be nested into the <select> element. This element will then represent the null or "not selected" option.

If you want, you can manually construct the options list with the ngRepeat directive:

<select ng-model="selection">
    <option value="" disabled>{{title}}</option>
    <option ng-repeat="value in values">{{value.name}}</option>
    <option value="">None</option>
</select>

But I would strongly advice against that, as it's absolutely not semantic: your title isn't an option. Do you have contemplate to use a heading element, a <label> or an <optgroup> (with the group by expression in ngOptions) instead?

<select ng-options="value.name group by title for value in values" ng-model="selection">
    <option value="">None</option>
</select>
like image 31
Blackhole Avatar answered Oct 12 '22 12:10

Blackhole