(scope, selectElement, attr, ctrls)
| 30679 | optGroupTemplate = window.document.createElement('optgroup'); |
| 30680 | |
| 30681 | function ngOptionsPostLink(scope, selectElement, attr, ctrls) { |
| 30682 | |
| 30683 | var selectCtrl = ctrls[0]; |
| 30684 | var ngModelCtrl = ctrls[1]; |
| 30685 | var multiple = attr.multiple; |
| 30686 | |
| 30687 | // The emptyOption allows the application developer to provide their own custom "empty" |
| 30688 | // option when the viewValue does not match any of the option values. |
| 30689 | for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) { |
| 30690 | if (children[i].value === '') { |
| 30691 | selectCtrl.hasEmptyOption = true; |
| 30692 | selectCtrl.emptyOption = children.eq(i); |
| 30693 | break; |
| 30694 | } |
| 30695 | } |
| 30696 | |
| 30697 | // The empty option will be compiled and rendered before we first generate the options |
| 30698 | selectElement.empty(); |
| 30699 | |
| 30700 | var providedEmptyOption = !!selectCtrl.emptyOption; |
| 30701 | |
| 30702 | var unknownOption = jqLite(optionTemplate.cloneNode(false)); |
| 30703 | unknownOption.val('?'); |
| 30704 | |
| 30705 | var options; |
| 30706 | var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope); |
| 30707 | // This stores the newly created options before they are appended to the select. |
| 30708 | // Since the contents are removed from the fragment when it is appended, |
| 30709 | // we only need to create it once. |
| 30710 | var listFragment = $document[0].createDocumentFragment(); |
| 30711 | |
| 30712 | // Overwrite the implementation. ngOptions doesn't use hashes |
| 30713 | selectCtrl.generateUnknownOptionValue = function(val) { |
| 30714 | return '?'; |
| 30715 | }; |
| 30716 | |
| 30717 | // Update the controller methods for multiple selectable options |
| 30718 | if (!multiple) { |
| 30719 | |
| 30720 | selectCtrl.writeValue = function writeNgOptionsValue(value) { |
| 30721 | // The options might not be defined yet when ngModel tries to render |
| 30722 | if (!options) return; |
| 30723 | |
| 30724 | var selectedOption = selectElement[0].options[selectElement[0].selectedIndex]; |
| 30725 | var option = options.getOptionFromViewValue(value); |
| 30726 | |
| 30727 | // Make sure to remove the selected attribute from the previously selected option |
| 30728 | // Otherwise, screen readers might get confused |
| 30729 | if (selectedOption) selectedOption.removeAttribute('selected'); |
| 30730 | |
| 30731 | if (option) { |
| 30732 | // Don't update the option when it is already selected. |
| 30733 | // For example, the browser will select the first option by default. In that case, |
| 30734 | // most properties are set automatically - except the `selected` attribute, which we |
| 30735 | // set always |
| 30736 | |
| 30737 | if (selectElement[0].value !== option.selectValue) { |
| 30738 | selectCtrl.removeUnknownOption(); |
nothing calls this directly
no test coverage detected