« Kevin Ngo

ng-okevin's Angular ch.5 - Forms

3 Apr 2014

The form, input, select, and textarea elements are augmented (as directives) in Angular for added sauce. Angular forms have a built-in awareness of their state, such as whether data has been inputted or whether the forms are valid. Angular forms provide


We have covered the two-way data binding in ch.1 AngularJS. Form state, however, can be used to conditionally

With directives though, we can also achieve

Form State

A bit about the backend. Angular forms and inputs are instances of FormController. As instances of FormController, form and input directives contain a handful of useful properties that represent form state.

$error is a bit confusing as it has two faces. If getting the $error attribute from a form’s FormController, it will be a reference to invalid form controls.

{"required": [{}], "max": false}

Else if getting the $error attribute from an input’s FormController, it will be a mapping of error names to booleans (with “true” indicating an error).

{"required": false, "max": true}

To reference all these properties though, the form and input directives need to be given a name attribute to register it into scope. We can then use these properties to drive form interaction and behavior.

Example

In Muffin Button, we will create a button that dispenses a number of muffins to demonstrate form states.

<form name="muffinForm" ng-submit="muffins = muffinNum">
  <input id="muffinNum" type="number" name="muffinNumInput"
         ng-model="muffinNum" min="1" max="255">

  <button ng-disabled="muffinForm.muffinNumInput.$invalid">
    Dispense Muffins
  </button>

  <span ng-show="muffinForm.muffinNumInput.$error.max">
    Muffin Overload!
  </span>

  <img src="muffin.png" ng-repeat="i in [] | range: muffins">
</form>

Muffin Button contains a number input field. Given a number, it dispenses or displays a respective number of muffins when pressing the muffin button. We use form states to disable the muffin button on invalid and non-number inputs, and we also use it to display a specific error message in the case that too many muffins are requested.

We disabled the button with the ng-disabled directive when our HTML5 number input field is invalid. We give the input field the name muffinNumInput. That name can then be referenced from the muffinForm object in the scope as muffinForm.muffinNumInput. Our number field dictates whether the form is invalid. If the input is not a number, is under the min, or over the max, muffinForm.muffinNumInput.$invalid will be switched on.

However, $invalid is general catch-all flag. If we want make use of more detailed form states, we can make use of the $error attribute to see specific error flags. In the example, we display an error message with the ng-show directive when the number input field contains too large of a number. In that case, the max flag will be set and can be referenced by




### Styling the Form Based on Form State

We can style elements differently based on form states. It is nothing new, we
simply use form states in conjunction with ```ng-class```. With that, we can
give the number input element a red error border when the input is invalid and
green when valid.

As a side thriller, we use ```$pristine``` to not apply these classes when the
form has not been touched. The border color would then initially default to
gray.

```html

Up Next

Scopes, controllers, and templates lay the foundation of the cake. Now we can start decorating with the frostiest part of Angular, Directives, where I demonstrate hands-on how to build a mobile slider.