()
| 28496 | * |
| 28497 | */ |
| 28498 | var selectDirective = function() { |
| 28499 | |
| 28500 | return { |
| 28501 | restrict: 'E', |
| 28502 | require: ['select', '?ngModel'], |
| 28503 | controller: SelectController, |
| 28504 | link: function(scope, element, attr, ctrls) { |
| 28505 | |
| 28506 | // if ngModel is not defined, we don't need to do anything |
| 28507 | var ngModelCtrl = ctrls[1]; |
| 28508 | if (!ngModelCtrl) return; |
| 28509 | |
| 28510 | var selectCtrl = ctrls[0]; |
| 28511 | |
| 28512 | selectCtrl.ngModelCtrl = ngModelCtrl; |
| 28513 | |
| 28514 | // We delegate rendering to the `writeValue` method, which can be changed |
| 28515 | // if the select can have multiple selected values or if the options are being |
| 28516 | // generated by `ngOptions` |
| 28517 | ngModelCtrl.$render = function() { |
| 28518 | selectCtrl.writeValue(ngModelCtrl.$viewValue); |
| 28519 | }; |
| 28520 | |
| 28521 | // When the selected item(s) changes we delegate getting the value of the select control |
| 28522 | // to the `readValue` method, which can be changed if the select can have multiple |
| 28523 | // selected values or if the options are being generated by `ngOptions` |
| 28524 | element.on('change', function() { |
| 28525 | scope.$apply(function() { |
| 28526 | ngModelCtrl.$setViewValue(selectCtrl.readValue()); |
| 28527 | }); |
| 28528 | }); |
| 28529 | |
| 28530 | // If the select allows multiple values then we need to modify how we read and write |
| 28531 | // values from and to the control; also what it means for the value to be empty and |
| 28532 | // we have to add an extra watch since ngModel doesn't work well with arrays - it |
| 28533 | // doesn't trigger rendering if only an item in the array changes. |
| 28534 | if (attr.multiple) { |
| 28535 | |
| 28536 | // Read value now needs to check each option to see if it is selected |
| 28537 | selectCtrl.readValue = function readMultipleValue() { |
| 28538 | var array = []; |
| 28539 | forEach(element.find('option'), function(option) { |
| 28540 | if (option.selected) { |
| 28541 | array.push(option.value); |
| 28542 | } |
| 28543 | }); |
| 28544 | return array; |
| 28545 | }; |
| 28546 | |
| 28547 | // Write value now needs to set the selected property of each matching option |
| 28548 | selectCtrl.writeValue = function writeMultipleValue(value) { |
| 28549 | var items = new HashMap(value); |
| 28550 | forEach(element.find('option'), function(option) { |
| 28551 | option.selected = isDefined(items.get(option.value)); |
| 28552 | }); |
| 28553 | }; |
| 28554 | |
| 28555 | // we have to do it on each watch since ngModel watches reference, but |
nothing calls this directly
no test coverage detected