(scope, selectElement, attr, ctrls)
| 31463 | optGroupTemplate = window.document.createElement('optgroup'); |
| 31464 | |
| 31465 | function ngOptionsPostLink(scope, selectElement, attr, ctrls) { |
| 31466 | |
| 31467 | var selectCtrl = ctrls[0]; |
| 31468 | var ngModelCtrl = ctrls[1]; |
| 31469 | var multiple = attr.multiple; |
| 31470 | |
| 31471 | // The emptyOption allows the application developer to provide their own custom "empty" |
| 31472 | // option when the viewValue does not match any of the option values. |
| 31473 | for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) { |
| 31474 | if (children[i].value === '') { |
| 31475 | selectCtrl.hasEmptyOption = true; |
| 31476 | selectCtrl.emptyOption = children.eq(i); |
| 31477 | break; |
| 31478 | } |
| 31479 | } |
| 31480 | |
| 31481 | // The empty option will be compiled and rendered before we first generate the options |
| 31482 | selectElement.empty(); |
| 31483 | |
| 31484 | var providedEmptyOption = !!selectCtrl.emptyOption; |
| 31485 | |
| 31486 | var unknownOption = jqLite(optionTemplate.cloneNode(false)); |
| 31487 | unknownOption.val('?'); |
| 31488 | |
| 31489 | var options; |
| 31490 | var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope); |
| 31491 | // This stores the newly created options before they are appended to the select. |
| 31492 | // Since the contents are removed from the fragment when it is appended, |
| 31493 | // we only need to create it once. |
| 31494 | var listFragment = $document[0].createDocumentFragment(); |
| 31495 | |
| 31496 | // Overwrite the implementation. ngOptions doesn't use hashes |
| 31497 | selectCtrl.generateUnknownOptionValue = function(val) { |
| 31498 | return '?'; |
| 31499 | }; |
| 31500 | |
| 31501 | // Update the controller methods for multiple selectable options |
| 31502 | if (!multiple) { |
| 31503 | |
| 31504 | selectCtrl.writeValue = function writeNgOptionsValue(value) { |
| 31505 | // The options might not be defined yet when ngModel tries to render |
| 31506 | if (!options) return; |
| 31507 | |
| 31508 | var selectedOption = selectElement[0].options[selectElement[0].selectedIndex]; |
| 31509 | var option = options.getOptionFromViewValue(value); |
| 31510 | |
| 31511 | // Make sure to remove the selected attribute from the previously selected option |
| 31512 | // Otherwise, screen readers might get confused |
| 31513 | if (selectedOption) selectedOption.removeAttribute('selected'); |
| 31514 | |
| 31515 | if (option) { |
| 31516 | // Don't update the option when it is already selected. |
| 31517 | // For example, the browser will select the first option by default. In that case, |
| 31518 | // most properties are set automatically - except the `selected` attribute, which we |
| 31519 | // set always |
| 31520 | |
| 31521 | if (selectElement[0].value !== option.selectValue) { |
| 31522 | selectCtrl.removeUnknownOption(); |
nothing calls this directly
no test coverage detected