16

I have the following code for a select drop down input that is styled in 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>

Before the user is able to submit this form, he or she must select a business process.

So I have put the required directive on the select statement, however because the first option tag has -- Select Business Process -- that still counts as a selected option, and thus the required flag is met, and therefore the form validates even though no actual Business Process is selected.

How can I overcome this issue?

Thank You.

1
  • Can you create an attribute directive with link property that will setup a listener for onchange event ant and validate things there? Commented Dec 31, 2013 at 14:46

9 Answers 9

30

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)

Sign up to request clarification or add additional context in comments.

1 Comment

It's all about having that empty <option> tag in your HTML, not as an option in 'processes' :) Thanks for pointing this out!
4

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

2 Comments

I get that, but I purposefully want the user to select something. I don't want a default there.
i have reedited my answer, hope it is useful for you.
2

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


Comments

2

a best way and straight one is to use:

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>

Comments

1

You can try to add form, like:

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"
    }];
}

Demo Fiddle

Comments

1

Use the following code snippet

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

Comments

0

Add "disabled" to the first 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>

Comments

0

This works for me. Form is invalid until user selects any other value than "Choose..."

<select name="country" id="country" class="form-control" formControlName="country" required>
    <option selected value="">Choose...</option>
    <option *ngFor="let country of countries">{{country.country}}</option>
</select>

Comments

-1

Maybe this code, can be usefull for this... in this case the form is called myform

<select ng-model="selectX" id="selectX" name="selectX"  required>
                                            <option  value="" ></option>
                                            <option  value="0" >0</option>
                                            <option value="1">1</option>
                                          </select>

    <span style="color:red" ng-show="myform.selectX.$dirty && myform.selectX.$invalid">
    <span ng-show="myform.selectX.$error.required">Is required.</span>
    </span> 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.