Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Form Validation with Directives - "myform.$valid" not quite right for me

Tags:

angularjs

I've hacked a solution to my problem, but I am not pleased, it doesn't feel "angular" to me, and it adds to the maintenance of the code.

First, the form requirements:

  1. Modular Directives (so I can re-use them.)
  2. Each field can have multiple errors, but only one is shown at a time, in a logical order...
  3. Hide the submit button until the form is complete, not just valid.
  4. Bootstrap Themed
  5. Do it "the angular way."

The problem is #3. I tried this:

<div ng-show="myform.$valid">
   <input type="submit" value="Submit" />
</div>

But this just makes the submit button show up as soon as one field is valid, and then it hides again as you start the next field. My "hack fix" was to create variables on the scope and a method in the controller to check them all (mainly to keep the view clean...) But this just doesn't feel right.

Here's my fiddle: http://jsfiddle.net/thomporter/e3jye/

like image 546
Thom Porter Avatar asked Jan 27 '13 01:01

Thom Porter


2 Answers

I was just poking around with this and here's what I landed on for highlighting errors on an email field in logical order (using bootstrap form control groups)... http://jsfiddle.net/kNKbJ/1/

<form name="form" ng-app>
    <div class="control-group" ng-class="{true: 'error'}[form.email.$error.email || (submitted && form.email.$error.required)]">
        <label class="control-label" for="email">Your email address</label>
        <div class="controls">
            <input type="email" name="email" ng-model="email" required />
            <span class="help-inline" ng-show="submitted && form.email.$error.required">Required</span>
            <span class="help-inline" ng-show="form.email.$error.email">Invalid email</span>
        </div>
    </div>

    <button type="submit" class="btn btn-primary btn-large" ng-click="submitted=true">Submit</button>
</form>

You could add the submitted check to anything you don't want to show until after first submit

like image 141
JeremyWeir Avatar answered Nov 01 '22 07:11

JeremyWeir


It's a common problem that people don't want all of their validation messages showing at the same time, even if they all apply.

The following form should fit your requirements, however I didn't "Bootstrap theme" the error validation messages. It is only using the default angular functionality.

But in a nutshell, it should show the required message, if a value exists but it's not a valid email, it should show the invalid email message.

It also hides the submit button if it's not valid... HOWEVER... I recommend just disabling the submit button with ng-disabled instead. It's poor usability IMO to not let people know where the submit button is.

<form name="myForm">
   <label for="email">Email</label>
   <input type="email" id="email" name="email" ng-model="formData.email" required/>
   <span ng-show="myForm.email.$error.required && myForm.email.$dirty">required</span>
   <span ng-show="!myForm.email.$error.required && myForm.email.$error.email && myForm.email.$dirty">invalid email</span>

   <button type="submit" class="btn" ng-show="myForm.$valid">Submit</button>
</form>

It gets a little long adding those checks to the validation, but it is the "angular way" to do it.

I hope that helps.

like image 23
Ben Lesh Avatar answered Nov 01 '22 07:11

Ben Lesh