Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I simplify form validation?

Tags:

angularjs

The code below seems to work pretty well for doing basic required form validation.

The form displays a red Name is required message when the field is dirty + invalid and a Great! message if the field is dirty + valid.

But it's a mess having repeat this code for each and every field in the form:

<form name="myForm">
    <div class="control-group" 
     ng-class="{error: myForm.name.$invalid && myForm.name.$dirty}">
        <label>Name:</label>
        <input type="text" name="name" ng-model="user.name" required/>
        <span ng-show="myForm.name.$invalid && myForm.name.$dirty" 
            class="help-inline">Name is required</span>
        <span ng-show="myForm.names.$valid && myForm.names.$dirty">Great!</span>
    </div>
</form>

I would like to be able to specify the ng-show and ng-class attributes in some easier way.

like image 687
Martin Wickman Avatar asked Feb 22 '13 10:02

Martin Wickman


People also ask

What is basic form validation?

Basic Validation − First of all, the form must be checked to make sure all the mandatory fields are filled in. It would require just a loop through each field in the form and check for data. Data Format Validation − Secondly, the data that is entered must be checked for correct form and value.

What are different types of form validation?

In general, there are two main types of form validation: After submit validation. Inline validation.


3 Answers

One way you could do it is to abstract your validation expression to scope methods:

PLUNKER

HTML

<div class="control-group" ng-class="{error: isInvalid('name')}">
  <label>Name:</label>
  <input type="text" name="name" placeholder="Name" ng-model="user.name" required/>
  <span ng-show="isInvalid('name')" class="help-inline">Name is required</span>
  <span ng-show="isValid('name')">Great!</span>
</div>

Controller

function Ctrl($scope) {
  $scope.isInvalid = function(field){
    return $scope.myForm[field].$invalid && $scope.myForm[field].$dirty;
  };

  $scope.isValid = function(field){
    return $scope.myForm[field].$valid && $scope.myForm[field].$dirty;
  };

}
like image 129
Stewie Avatar answered Oct 01 '22 14:10

Stewie


I know the question is old but I want to share with the world my awesome new angular directive, I made a project on Github and I think that it just rocks compare to whatever is/was available...I based myself on the excellent Laravel PHP Framework and made it available under Angular... Enough said, let's give some examples:

<!-- example 1 -->
<label for="input1">Simple Integer</label>
<input type="text" validation="integer|required" ng-model="form1.input1" name="input1" />

<!-- example 2 -->
<label for="input2">Alphanumeric + Exact(3) + required</label>
<input type="text" validation="alpha|exact_len:3|required" ng-model="form1.input2" name="input2" />

So I can define whatever amount of validation rules which I want in a simple directive validation="min_len:2|max_len:10|required|integer" and the error message will always display in the next <span> Don't you guys like it already? 1 line of code for your input, 1 line of code for the error display, you can't be simpler than that...oh and I even support your custom Regex if you want to add :)

No more clustered Form with 10 lines of code for 1 input when the only thing you need is 2 lines, no more, even for an input with 5 validators on it. And don't worry about the form not becoming invalid, I took care of that as well, it's all handled the good way.

Take a look at my Github project Angular-Validation and spread the word =)

EDIT
To make an even more smoother user experience, I added validation on timer. The concept is simple, don't bother the user while he's busy typing but do validate if he makes a pause or change input (onBlur)... Love it!!!
You can even customize the timer as per your liking, I've decided to default it to 1 second within the directive but if you want to customize you can call as for example typing-limit="5000" to make a 5 sec. timeout. Full example:

<input type="text" validation="integer|required" typing-limit="5000" ng-model="form1.input1" name="input1" />


EDIT #2
Also added input match confirmation validation (ex.: password confirmation), here is a sample code

<!-- input match confirmation, as for example: password confirmation -->
<label for="input4">Password</label>
<input type="password" name="input4" ng-model="form1.input4" validation="alpha|min_len:4|required"  />
<label for="input4c">Password Confirmation</label>
<input type="password" name="input4c" ng-model="form1.input4c" validation="match:form1.input4,Password|required"  />

EDIT #3
Refactored the directive so that the requirement of having a <span> to display the error is unnecessary, the directive now handles it by itself, see the code change reflected on top.

DEMO
Added a live demo on Plunker

like image 8
ghiscoding Avatar answered Oct 01 '22 16:10

ghiscoding


Please use this CSS

.myForm input.ng-invalid.ng-dirty {
    background-color: #FA787E;
}

.myForm input.ng-valid.ng-dirty {
    background-color: #78FA89;
}
like image 5
user1029125 Avatar answered Oct 01 '22 15:10

user1029125