Is there a way to require and use ngModel inside the controller of a custom Angular directive without using the link function? I have seen examples that use the link function, but I want to know if it's possible to access ngModel inside the directive controller. The method I tried below returns undefined. Is there another approach to achieve this? I need to validate the component and apply the invalid class to the error object.
//directive
angular.module('myApp', [])
.directive('validator', function (){
return {
restrict: 'E',
require: {
ngModelCtrl: 'ngModel',
formCtrl: '?^form'
},
replace: true,
templateUrl: 'view.html',
scope: {},
controllerAs: 'ctrl',
bindToController: {
rows: '=',
onSelected: '&?' //passsed selected row outside component
typedText: '&?' //text typed into input passed outside so developer can create a custom filter, overriding the auto
textFiltered: '@?' //text return from the custom filter
ngRequired: "=?" //default false, when set to true the component needs to validate that something was selected on blur. The selection is not put into the input element all the time so it can't validate based on whether or not something is in the input element itself. I need to validate inside the controller where I can see if 'this.ngModel' (selectedRow - not passed through scope) is undefined or not.
},
controller: ["$scope", "$element", function ($scope, $element){
var ctrl = this;
ctrl.rowWasSelected;
//called when a user clicks the dropdown to select an item
ctrl.rowSelected = function (row){
ctrl.rowWasSelected = true;
ctrl.searchText = row.name; //place the name property of the dropdown data into ng-model in the input element
}
ctrl.$onInit = $onInit;
function $onInit (){
ctrl.ngModelCtrl.$validators.invalidInput = validate;
}
function validate (modelValue, viewValue) {
var inputField = ctrl.formCtrl.name;
var ddField = ctrl.formCtrl.listData;
inputField.$setValidity('invalidInput', ddField.$touched && ctrl.rowWasSelected);
return true;
}
}];
}
});
//template
<form name="validatorForm" novalidate>
<div class="form-group" ng-class="{ng-invalid:validatorForm.name.$error.invalid}">
<label for="name">Names</label>
<input type="name" class="form-control" name="name" placeholder="Your name" ng-change="typedText(text)" ng-model="ctrl.textFiltered" ng-blur="ctrl.validate()" ng-required="ctrl.ngRequired">
</div>
<ul ng-show="show list as toggled on and off" name="listData" required>
<li ng-repeat="row in ctrl.rows" ng-click="ctrl.rowSelected({selected: row}) filterBy:'ctrl.textFiltered' ng-class="{'active':row === ctrl.ngModel}">{{row}}<li>
</ul>
</form>
//html
<validator
rows="[{name:'tim', city:'town', state:'state', zip: 34343}]"
on-selected="ctrl.doSomethingWithSelectedRow(selected)"
typed-text="ctrl.manualFilter(text)"
text-filtered="ctrl.textReturnedFromManualFilter"
ng-required="true">
</validator>