Keyur Shah Keyur Shah - 3 months ago 11
AngularJS Question

Custom Directive for Required/ngRequired

I want to validate a dropdown with required. Default required only works if value is null or blank (correct me if I'm wrong). I want required to give error and make form invalid true if value is 'not assigned'.

<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required></select>


Using this I can show error message but this does make form invalid

<span class="error" ng-show="applications.first == 'not assigned'?true:false">Select Approver</span>


SOLUTION:-

1) If you want to use required then Check Shannon Hochkins solution.

<form name="formName">
<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required="true">
<option value="">Not Assigned</option>
</select>
<span class="error" ng-show="formName.first.$invalid ?true:false">Select Approver</span>
<pre>{{formName | json}}</pre>
</form>


He Added a option with blank value
<option value="">Not Assigned</option>
. and set
required="true"
in select. This works perfectly.

2) Using custom directive.

app.directive('req', [
function() {
var link = function($scope, $element, $attrs, ctrl) {
var validate = function(viewValue) {
var comparisonModel = $attrs.req;
var invalid = $attrs.invalid;
if (viewValue == invalid) {
// It's valid because we have nothing to compare against
ctrl.$setValidity('req', false);
} else {
ctrl.$setValidity('req', true);
}
};
$attrs.$observe('req', function(comparisonModel) {
// Whenever the comparison model changes we'll re-validate
return validate(ctrl.$viewValue);
});
};
return {
require: 'ngModel',
link: link
};

}
]);


And Your html code :

<select invalid="not assigned" req={{applications.first}} name="first" class="select" ng-model="applications.first" ng-options="x.id as x.value for x in list1" title="Select Approver" ></select>
<span class="error" ng-show="Step5.first.$error.req">Select Approver</span>


Here you will have to set
invalid="not assigned"
or any value like
invalid='0'
or
invalid=' '
. In directive it compares with invalid attribute if value matches it will show error.

Answer

Add the required value to the select element, then you can use the FORM object to check if the field is valid or not.

You can also use the forms name, to access fields in the form to check validity. If you want to add a 'default' option, to the dropdown, you can add in an option with an empty value which is technically invalid on a required dropdown menu. You can choose to hide it if it is valid so the user can't pick it again after a correct option has been chosen.

<form name="formName" ng-controller="testCtrl">
    <select name="first" ng-options="x.id as x.value for x in list1" ng-model="applications.first" required>
        <option value="" ng-hide="formName.first.$valid">Not Assigned</option>
    </select>
    <pre>{{formName.first.$invalid | json}}</pre>
</form>

Inside your controller, setup some options:

angular.module('sandbox', []).controller('testCtrl', function($scope) {

  $scope.list1 = [{
    id: 1,
    value: 'apples'
  }, {
    id: 2,
    value: 'oranges'
  }];
});

Demo: https://jsfiddle.net/suunyz3e/304/