web-dev-qa-db-fra.com

Validation AngularJS sur <select> avec une option d’invite

J'ai le code suivant pour une entrée déroulante de sélection qui est stylée dans Bootstrap.

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

Avant que l'utilisateur puisse envoyer ce formulaire, il doit sélectionner un processus métier.

J'ai donc mis la directive required sur l'instruction select, mais comme la première balise d'option a -- Select Business Process -- qui compte toujours comme une option sélectionnée, le drapeau requis est donc rempli et, par conséquent, le formulaire est validé même si aucun processus technique n'est sélectionné.

Comment puis-je surmonter ce problème?

Je vous remercie.

16
J86

Cette approche pourrait/devrait résoudre votre problème: 

1) déclarez les options à l'intérieur de votre portée:

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

Et 2) utiliser cette déclaration:

<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>

L'astuce ici est en fait que, pendant les cycles angulaires, on résoudra d'abord le problème selon lequel la valeur actuelle ne fait pas partie des options processes. Ainsi, la valeur par défaut serait: 

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

et required fonctionnera comme prévu ( plus de détails )

30
Radim Köhler

vous pouvez initialer la valeur du sélecteur dans le contrôleur:

<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>

dans le contrôleur:

$scope.businessprocess = "A" ;

ou "C", "Q", tout ce que vous voulez, ainsi le select aura toujours une valeur Je pense que vous n'avez pas besoin de "requis" ici dans select.

Si vous ne voulez pas qu'un init soit une valeur. faites également un effet supplémentaire lorsque l'utilisateur ne le sélectionne pas.

<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>

puis écrivez la 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
                }
            });
        }
    };
});
4
Frankjs

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);
          });
      }
    };
  });

2
paulohenriquevn

un meilleur moyen consiste à utiliser:

HTML

<select name="businessprocess" ng-model="businessprocess"  required>
        <option selected disabled value="">-- Select Business Process --</option>
        <option ng-repeat="v in processes" value="{{v.id}}">{{v.value}}</option>
</select>
2
youhammi

Vous pouvez essayer d'ajouter un formulaire, comme:

HTML

<div ng-app="myApp" ng-controller="MyCtrl">
     <form name="mainForm">
    <select name="businessprocess" ng-model="businessprocess"  required>    
        <option value="">-- Select Business Process --</option>
        <option ng-repeat="v in processes" value="{{v.id}}">{{v.value}}</option>
    </select>
    <span class="error" ng-show="mainForm.businessprocess.$error.required">required</span>
</form>
</div>

js

angular.module('myApp', []);

function MyCtrl($scope, $timeout) {
   $scope.processes = [{
        id: "C",
        value: "Process C"
    }, {
        id: "Q",
        value: "Process Q"
    }];
}

Démo Fiddle

1
Maxim Shoustin

Ajoutez "désactivé" à la première option:

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

0
Ömer An