(scope, selectElement, attr, ctrls)
| 32438 | optGroupTemplate = window.document.createElement('optgroup'); |
| 32439 | |
| 32440 | function ngOptionsPostLink(scope, selectElement, attr, ctrls) { |
| 32441 | |
| 32442 | var selectCtrl = ctrls[0]; |
| 32443 | var ngModelCtrl = ctrls[1]; |
| 32444 | var multiple = attr.multiple; |
| 32445 | |
| 32446 | // The emptyOption allows the application developer to provide their own custom "empty" |
| 32447 | // option when the viewValue does not match any of the option values. |
| 32448 | for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) { |
| 32449 | if (children[i].value === '') { |
| 32450 | selectCtrl.hasEmptyOption = true; |
| 32451 | selectCtrl.emptyOption = children.eq(i); |
| 32452 | break; |
| 32453 | } |
| 32454 | } |
| 32455 | |
| 32456 | // The empty option will be compiled and rendered before we first generate the options |
| 32457 | selectElement.empty(); |
| 32458 | |
| 32459 | var providedEmptyOption = !!selectCtrl.emptyOption; |
| 32460 | |
| 32461 | var unknownOption = jqLite(optionTemplate.cloneNode(false)); |
| 32462 | unknownOption.val('?'); |
| 32463 | |
| 32464 | var options; |
| 32465 | var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope); |
| 32466 | // This stores the newly created options before they are appended to the select. |
| 32467 | // Since the contents are removed from the fragment when it is appended, |
| 32468 | // we only need to create it once. |
| 32469 | var listFragment = $document[0].createDocumentFragment(); |
| 32470 | |
| 32471 | // Overwrite the implementation. ngOptions doesn't use hashes |
| 32472 | selectCtrl.generateUnknownOptionValue = function(val) { |
| 32473 | return '?'; |
| 32474 | }; |
| 32475 | |
| 32476 | // Update the controller methods for multiple selectable options |
| 32477 | if (!multiple) { |
| 32478 | |
| 32479 | selectCtrl.writeValue = function writeNgOptionsValue(value) { |
| 32480 | // The options might not be defined yet when ngModel tries to render |
| 32481 | if (!options) return; |
| 32482 | |
| 32483 | var selectedOption = selectElement[0].options[selectElement[0].selectedIndex]; |
| 32484 | var option = options.getOptionFromViewValue(value); |
| 32485 | |
| 32486 | // Make sure to remove the selected attribute from the previously selected option |
| 32487 | // Otherwise, screen readers might get confused |
| 32488 | if (selectedOption) selectedOption.removeAttribute('selected'); |
| 32489 | |
| 32490 | if (option) { |
| 32491 | // Don't update the option when it is already selected. |
| 32492 | // For example, the browser will select the first option by default. In that case, |
| 32493 | // most properties are set automatically - except the `selected` attribute, which we |
| 32494 | // set always |
| 32495 | |
| 32496 | if (selectElement[0].value !== option.selectValue) { |
| 32497 | selectCtrl.removeUnknownOption(); |
nothing calls this directly
no test coverage detected