Angularjs validation for ui-select multiple
Asked Answered
M

4

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?

Melanosis answered 1/12, 2014 at 8:50 Comment(0)
R
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

Reis answered 1/12, 2014 at 11:55 Comment(1)
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?Melanosis
P
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>
Postaxial answered 5/4, 2015 at 19:4 Comment(2)
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.Solent
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.Tb
R
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

Reis answered 1/12, 2014 at 11:55 Comment(1)
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?Melanosis
F
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>
Fruma answered 17/12, 2015 at 11:27 Comment(0)
M
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.

Mandle answered 6/6, 2016 at 8:7 Comment(1)
Ok. Thanks for letting me know. I have included this info in the question.Melanosis

© 2022 - 2024 — McMap. All rights reserved.