AngularJS Validation on <select> with a prompt option

JS



    angular.module('interfaceApp')
  .directive('requiredSelect', function () {
    return {
      restrict: 'AE',
      require: 'ngModel',
      link: function(scope, elm, attr, ctrl) {

        if (!ctrl) return;
          attr.requiredSelect = true; // force truthy in case we are on non input element

          var validator = function(value) {
            if (attr.requiredSelect && ctrl.$isEmpty(value)) {
              ctrl.$setValidity('requiredSelect', false);
              return;
            } else {
              ctrl.$setValidity('requiredSelect', true);
              return value;
            }
          };

          ctrl.$formatters.push(validator);
          ctrl.$parsers.unshift(validator);

          attr.$observe('requiredSelect', function() {
            validator(ctrl.$viewValue);
          });
      }
    };
  });



you can initial the value of selector in controller:

<select class="form-control" name="businessprocess" ng-model="businessprocess">
    <option value="A">-- Select Business Process --</option>
    <option value="C">Process C</option>
    <option value="Q">Process Q</option>
</select>

in Controller:

$scope.businessprocess = "A" ;

or "C","Q",whatever you want, so the select will always have value. i think you don't need "required" here in select.

If you don't want an init a value. also do some extra effect when user don't select it.

<select class="form-control" name="businessprocess" ng-model="businessprocess" myRequired>
    <option value="">-- Select Business Process --</option>
    <option value="C">Process C</option>
    <option value="Q">Process Q</option>
</select>

then write the directive:

model.directive("myRequired", function() {
    return {
        restrict: 'AE',
        scope: {},
        require: 'ngModel',
        link: function(scope, iElement, iAttrs) {
                if(iElement.val() == ""){
                    //do something
                    return;
                } else {
                    //do other things
                }
            });
        }
    };
});

This approach could/should solve your issue:

1) declare the options inside of your scope:

$scope.processes = [
    { code: "C", name: "Process C" },
    { code: "Q", name: "Process Q" }
];

And 2) use this declaration:

<select class="form-control" name="businessprocess" ng-model="businessprocess" required
    ng-options="c.code as c.name for c in processes" >
    <option value="">-- Select Business Process --</option>
</select>

The trick here is in fact, that during the angular cycles, will firstly fix the issue that the the current value is not among the processes options. So, the default would be set to:

<option value="">-- Select Business Process --</option>

and required will be working as expected (more details)