5

THE SITUATION:

I have an angular app that send emails. There is a form with three fields: Address - Subject - Text.

For the address field I am using angular ui-select.

Everything is working fine, except the validation on the address field (on subject and text validation is working properly).

EDIT:

This bug has been fixed from version 0.16.1. as pointed out by @yishaiz.

So this question and its relative solution regard ui-select versions < 0.16.1.


THE CODE:

HTML:

 <form name="emailForm" ng-submit="submitForm(emailForm.$valid)"> 

    <div class="row form-group">

        <label class="col-sm-2 control-label">To: </label>

        <div class="col-sm-10">

            <ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%">

              <ui-select-match placeholder="Select person...">{{$item.name}} &lt; {{$item.value}} &gt;</ui-select-match>

              <ui-select-choices repeat="person2 in list_people | filter: {name: $select.search.name, value: $select.search.value, db_data_type_id: 5}">

                  <div ng-bind-html="person2.name | highlight: $select.search"></div>

                    <small>

                        email: <span ng-bind-html="''+person2.value | highlight: $select.search"></span>

                    </small>

              </ui-select-choices>

            </ui-select>

        </div>

    </div>

    <div class="col-sm-8">

         <button type="submit" class="btn btn-primary">Send</button>

    </div>

</form>

ANGULARJS:

$scope.submitForm = function(isValid) 
 {
    if (isValid) {
        alert('valid');
    }
    else {
        alert('not valid')
    }
};


PLUNKER:

http://plnkr.co/edit/MYW7SM9c9anH6RTomfRG?p=preview

As you can see the ui-select is required but the form is parse as valid.


QUESTION(s):

How can i make the ui-select multiple required?

4 Answers 4

11

Since angular#1.3, the angular way to do so is to create a custom (validation) directive.

Directive:

angular.module('myApp').directive('requireMultiple', function () {
    return {
        require: 'ngModel',
        link: function postLink(scope, element, attrs, ngModel) {
            ngModel.$validators.required = function (value) {
                return angular.isArray(value) && value.length > 0;
            };
        }
    };
});

Code becomes:

<ui-select name="test"
           multiple 
           require-multiple  
           ng-model="database_people.selectedPeople" ...>
  <ui-select-match placeholder="Select person...">...
  </ui-select-match>
  <ui-select-choices ...>
        ...
  </ui-select-choices>
</ui-select>

Adapted from this solution

PS: you can also use ng-messages to properly display an error if validation fail. Example:

<div ng-messages="emailForm.test.$error" >
  <p ng-message="required">Custom message here</p>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

The best one. I created another for selectize too. Earlier I was using watch in controller. Now I can use this in any view, no need of extra code in every controllers.
Great solution! Though in my case I had to set elevated priority for this directive (for e.g. 1000), else the link function would not even get executed.
5

This is a working Plunker.

The line I have changed is this:

<form name="emailForm" ng-submit="submitForm(multipleDemo.selectedPeople.length > 0)"> 

It doesn't use the form $valid which is what I guess you would ideally like to do.

I tried using the recommended way as outlined here https://docs.angularjs.org/api/ng/directive/form

<form name="emailForm" ng-submit="submitForm(emailForm.test.$valid)"> 

...

<ui-select multiple required ng-model="multipleDemo.selectedPeople" theme="select2" ng-disabled="disabled" style="width: 800px;" name=test>

but it doesn't work.

I wonder if the problem is down to the fact that multipleDemo.selectedPeople is always valid even when it is an empty array.

Edit: To validate more than one field you could do this

<form name="emailForm" ng-submit="submitForm()"> 

In the controller

  $scope.submitForm = function() 
     {
      var valid = true;
      if ($scope.multipleDemo.selectedPeople.length === 0) {
        valid = false;
      }
      // Followed by tests on other fields


      if (valid) {
          alert('valid');
      }
      else {
        alert('not valid')
      }


    };

Plunker

1 Comment

thank you very much @camden_kid. This is a nice solution. What can i do in the event i have to validate more than one field?
1

Try this: If length of the ng-model i.e. 'storage' is '0' then show the error message and also you can show error message by using form form_name.$submitted. This is simple way to handle required field for multiple select.

<form name="myform" ng-submit="!storage.length>0 && functionname()">
    <div class="form-group">
        <ui-select multiple ng-model="storage" name="weekdays">
            <ui-select-match>
                {{$item.name}}
            </ui-select-match>
            <ui-select-choices>
                {{weekday.name}}
            </ui-select-choices>
        </ui-select>
        <div ng-show="myform.$submitted">
           <div ng-show="!storage.length>0" >
               <span style="color:red;">Storage is required</span>
           </div>
        </div>
    </div>
    <button type="submit">Click</button>  
</form>

Comments

1

They have fixed the bug at ui-select version 0.16.1. See this working plunker. The one thing I've changed is the ui-select version in here

  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.16.1/select.js"></script>

And this is the github closed bug issue.

1 Comment

Ok. Thanks for letting me know. I have included this info in the question.

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.