Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ng-options is evaluated before ng-if causing invalid "null" option #8408

Closed
lightswitch05 opened this issue Jul 30, 2014 · 9 comments
Closed

Comments

@lightswitch05
Copy link

Overview

ng-if is not used when determining the "null" option for ng-options. Consider the following select:

<select ng-model="ctrl.color" ng-options="color.name for color in ctrl.colors">
  <option ng-if="false" value="">A</option>
  <option ng-if="true" value="">B</option>
</select>

I would expect the above example to produce a select with the null option B. However, ng-options actually finds A as being the correct null option (see selectDirective). After A is set as the null option, ng-if removes it from the DOM, removing the null option as well. It would seem that ng-if needs to be evaluated before ng-options. I looked through the source and was not able to find a simple fix, but I'm not familiar with angular's source either.

Reproduce the error

Simple example on Plunker
Stack overflow question that lead me to this
Another, more complex, Plunker from the above stack overflow

Use Case

I have a select directive that is used in multiple places in different ways. The logic is 100% the same, the only difference is the null option:

  • As a filter
    • When used as a filter, the null option signifies that all options are included. For a color model it would be something like 'Colors - All'
  • As an optional field
    • When used as an optional field, the null option is either blank or 'Colors - None'
  • As a required field
    • When used as a required field, there is either no null option or it is set to '--Please select a color--', depending if the model has a default value or not.

Since the logic is the same for all three of these cases and the only difference is the null option prompt, it doesn't make sense to make 3 separate directives to handle the different cases.

Angular Version

I've verified in both 1.2.21 & 1.3.0.beta.X. I haven't looked at older versions.

Browsers and Operating System

This appears to be an AngularJS bug and not a browser issue. However, I tested and verified the bug in both Chrome 36.0.1985.125 & IE 11 on Windows 8.

@Narretz Narretz added this to the Backlog milestone Jul 31, 2014
@wesleycho
Copy link
Contributor

This would happen because the select element is higher up the DOM tree than the null option with the ng-if, so it would compile first.

I think the appropriate solution would be to move the functionality for optional null options into the select directive instead of using ng-if on the null options, perhaps with an optional attribute.

@lightswitch05
Copy link
Author

@wesleycho what do you think about adding the optional attribute ngIncludeBlank?

Proposed accepted values for ngIncludeBlank:

  • String: The select has a null option and uses the supplied string as the prompt.
  • true: The select has a null option with a blank prompt.
  • false: The select does not have a null option.

This would match the functionality provided by Ruby On Rail's select tags

@btford btford self-assigned this Sep 25, 2014
@btford btford modified the milestones: 1.3.0-rc.4, Backlog Sep 25, 2014
@btford
Copy link
Contributor

btford commented Sep 26, 2014

I don't think that this is a use case we want to support.

Why not:

<select ng-model="ctrl.color" ng-options="color.name for color in ctrl.colors">
  <option value="">{{nullLabel}}</option>
</select>

and then set nullLabel in your directive's linking function?

@btford btford modified the milestones: Backlog, 1.3.0-rc.4 Sep 26, 2014
@lightswitch05
Copy link
Author

@btford that works for my first 2 use cases, but does not work for the 3rd requirement of not having a null option, which is what promoted me to open this ticket.

Currently I'm using this stackoverflow answer to get the functionality I'm looking for. Here is the plunker of it in action.

I don't think my need for an optional null value is unusual. While its true that this functionality can easily be replicated in a linking function - I think adding my proposed ngIncludeBlank option would be a useful feature for Angular. The need for this option is made especially clear since putting ng-if within the option tags do not work as expected.

@btford
Copy link
Contributor

btford commented Oct 1, 2014

While I'm sympathetic towards wanting a simple way to implement this behavior, I really don't see it happening for the following reasons:

  • This case is not common enough to warrant the addition (and extra bytes) of such a feature.
  • There are so many browser quirks with select boxes; trying to support this case is likely to introduce weird behavior elsewhere.

@eperret
Copy link

eperret commented Mar 9, 2015

+10 on wanting this feature!!!

@Narretz Narretz assigned Narretz and unassigned btford Sep 26, 2015
@Narretz Narretz removed the PRs plz! label Sep 26, 2015
@Narretz
Copy link
Contributor

Narretz commented Sep 27, 2015

I agree with Brian that this is not something we want. Although I think that starting from 1.4.7, you can use one option with ngIf that should cover all 3 use cases: http://plnkr.co/edit/dXuAjo3OT5PdTZUdYrlK?p=preview

@Narretz Narretz closed this as completed Sep 27, 2015
@harai
Copy link

harai commented Oct 7, 2015

The example @Narretz pasted has a problem that the entire items are listed twice.

@gkalpak
Copy link
Member

gkalpak commented Oct 7, 2015

@harai, this problem is tracked in #12190 (see #12190 (comment)).
We're working on it 😃

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.