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

select directive should expose options set by ngOptions #7417

Open
pocesar opened this issue May 10, 2014 · 7 comments
Open

select directive should expose options set by ngOptions #7417

pocesar opened this issue May 10, 2014 · 7 comments

Comments

@pocesar
Copy link
Contributor

pocesar commented May 10, 2014

since ngOptions directive is an expression, and can have filters applied to it, the resulting options array is unknown (bound items and labels). the select directive should expose an options array (or object) containing the array of items.

@pkozlowski-opensource
Copy link
Member

@pocesar I'm not sure I got the essence of the issue. Are you thinking about the expression like this:
ng-options="color.name for color in colors | filter:'b'"?
If so you can always assign a filtered array to a variable:

<select ng-model="myColor" ng-options="color.name for color in (filteredColors = (colors | filter:'b'))"></select><br>
    {{filteredColors}}

Here is a plunk: http://plnkr.co/edit/FJywANlXETCOe5Ukk0mG?p=preview

Once again, I'm not sure what you exact problem is so please provide a modified plunk if the above doesn't address your use-case.

@pocesar
Copy link
Contributor Author

pocesar commented May 10, 2014

the main thing I missed was when creating a directive, since I can use require: ['select','ngModel'], I was expecting to use require: ['ngOptions'] so I could take a look at the current result set from the directive. since it creates an array of items from the returned expression, but makes it private inside the setupAsOptions https://github.com/angular/angular.js/blob/master/src/ng/directive/select.js#L372

@pkozlowski-opensource
Copy link
Member

@pocesar no, you can't require ngOptions as it is not a directive with a controller but rather an attribute that gets evaluated: https://github.com/angular/angular.js/blob/master/src/ng/directive/select.js#L213

I'm still not super-clear what is your exact use-case and what is an extension point that you are missing from the select controller. We can mark it as a future request if you've got a good use-case and can explain it with a minimal example.

@pocesar
Copy link
Contributor Author

pocesar commented May 11, 2014

@pkozlowski-opensource indeed, that's why I couldn't require it. I expected at least that the select controller (through require: 'select') had the information about the array that is currently being used on the current element. this is mainly useful to $watchCollection on the items array to do some transforms (assuming controller.options) or passing this information to jQuery plugins, since some items MIGHT HAVE angular bindings that I want interpolated before passing to jQuery plugins or plain DOM manipulation. I was trying to create a child scope from existing select elements and apply a number of jQuery plugins on it, but some pre-rendered items, before the $http call had angular bindings, and were having a racing condition setting the label of the select to, for example <option value="">{{ items.data ? 'Select an employer' : 'Select an employee'}}</option>

@btford btford removed the gh: issue label Aug 20, 2014
@smashercosmo
Copy link

+1, It would be very helpful for writing custom select directives to have access to original parsed collection through select controller and/or somehow easily get object bound to the exact option (may be through exposed optionsMap object)

@hrobertson
Copy link

hrobertson commented Mar 21, 2017

I wanted my directive that invokes bootstrap select to be able to set the data-content attribute on the option elements to add markup to the options. The content of the attribute obviously needed to be option-specific therefore I needed access to the options.

I therefore augmented the ngOptions directive to expose the options:
https://github.com/hrobertson/angular.js/commit/53ef51140984263328819f9f81ec2a6f9c2e0cf0

What do people think of this approach?

As a usage example, in my case I am only using getOptionByTrackByValue:

// Inside bootstrapSelect directive link function
$timeout(function() {
  if (attrs.bootstrapSelect !== '') {
    var expression = $parse(attrs.bootstrapSelect);
    jquery("option", element).each(function(i, e) {
      var result = expression(ctrl.getOptionByTrackByValue(e.value));
      jquery(e).attr('data-content', result);
    });
  }
});

If people want a more complete example I can provide that.

@jongunter
Copy link

It would be very helpful if there was a public API here. SelectController's documentation seems to blank.

I work with a lot of form-heavy applications and one of the use cases (where this situation caused us trouble) was creating a directive that would add an "other" option to the <select> element on which it was applied. The best way I could think of to do that is creating a wrapper directive, which is a poor solution, as I just want to modify the already-working select element, not wrap it in something else and re-implement NgModelController's $render and $setViewValue methods.

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

No branches or pull requests

7 participants