Angular select $ touched validation

I have a form with select and a button that activates when the form is validated. It works great with the input field. However, this $ touched does not seem to work properly for selection. The button is activated even when touched. When choosing a cable, it is assumed that it will be invalid. It becomes invalid and the button is disabled when I select the option and then select the default value. I want it to work when an indirect selection has been selected and the mouse pointer is gone. Here is my html:

 <form role="form" name="frameVersionEditor" novalidate class="form-horizontal col-md-12"> <div class="row"> <div class="form-group col-lg-2 col-lg-push-1" ng-class="{'has-error' : frameVersionEditor.distributor.$invalid && frameVersionEditor.distributor.$touched}"> <label>Distributor</label> <select name="distributor" data-ng-model="myDistr" data-ng-options="distributors.key as distributors.value for distributors in distributorOptions" class="form-control" required> <option value="">Select Distributor</option> </select> <span ng-show="frameVersionEditor.distributor.$error.required && frameVersionEditor.distributor.$touched" class="help-block">Please select a distributor</span> </div> </div> </form> <button data-ng-click="generate()" ng-disabled="frameVersionEditor.$invalid">Generate</button> 

Here is my controller:

 var myApp = angular.module('myApp',[]); myApp.controller('myController', ['$scope', function($scope) { $scope.myDistr = []; $scope.distributors = [ { 'key': '0', 'value': 'A' }, { 'key': '1', 'value': 'B' }, { 'key': '2', 'value': 'C' } ]; $scope.generate = function() { //Do something }; }]); 
+8
angularjs validation select
source share
2 answers

I had the same problem recently. I solved this by adding a few things to the selection box and another entry to the array of possible choices.

First you want to add an empty or invalid selection to the list of possible choices, the best place in slot [0], and you will see why further down.

 vm.distributors = [ "Select Distributor", "A", "B", "C" ]; 

Then you need to add and update some Angular directives for your selection field. You want ng-valid to tell Angular which is acceptable here. You also need to indicate that you are running a field with the value “select something else” and that it is not valid for this value, which must be selected at the time of sending. Adding a name and identifier is usually the best thing. The last bit to add is the ng-required directive, since you used novalidate on the form, but this form element needs to change to something real. The end result is below:

 <div class="form-group col-lg-2 col-lg-push-1" ng-class="{'has-error' : vm.myDistr == vm.distributors[0] && frameVersionEditor.$dirty || frameVersionEditor.distributor.$pristine && frameVersionEditor.distributor.$touched}"> <label>Distributor</label> <select data-ng-model="vm.myDistr" id="myDistr" name="myDistr" ng-init="vm.distributors[0]" class="select form-control skinny" ng-required="true" data-ng-options="d for d in vm.distributors" ng-valid="vm.myDistr != vm.distributors[0]"></select> <p class="required" ng-show="vm.myDistr == vm.distributors[0]">&#42;</p> <p class="good" ng-show="vm.myDistr != vm.distributors[0]">&#10004;</p> <span ng-show="vm.myDistr == vm.distributors[0] && frameVersionEditor.$dirty || frameVersionEditor.distributor.$pristine && frameVersionEditor.distributor.$touched" class="help-block">Please select a distributor</span> 

This has also been updated to illustrate the simplest implementation (since you use 0-4 as keys, you really don't need them, just use the base array). I also changed my code to match John Papa's best practices and added to the red star (for invalid choices) and the green tick (for the right choice), as well as other good practice (show success as well as failure) in case of non-English users .

You also do not need the initial parameter that you specified initially, since my updates do a great job of this.

Upon request, Plunker is located here .

Hope this helps.

-C§

+4
source share

I compiled this script and everything seems to be working fine.

 <div ng-app="myApp" ng-controller="myController"> <h1>Select a Distributor</h1> <form name="form" class="form-horizontal col-md-12" novalidate> <div class="row"> <div class="form-group col-lg-2 col-lg-push-1" ng-class="{ 'has-error': form.distributor.$invalid && form.distributor.$touched }"> <label>Distributor</label> <select name="distributor" ng-model="mySelection" ng-options="d.key as d.value for d in myDistr" class="form-control" required> <option value="">Select Distributor</option> </select> <span ng-show="form.distributor.$error.required" class="help-inline">Please select a distributor</span> </div> </div> </form> <hr/><hr/> <button class="btn btn-primary" data-ng-click="generate()" ng-disabled="form.$invalid || form.distributor.$touched">Generate</button> </div> 

I have a suspicion that perhaps the $touched event is not what you think.

Please give me some feedback if I am wrong!

+2
source share

All Articles