Skip to content

Commit

Permalink
feat(ngModelOptions): Model update behavior can now be customized
Browse files Browse the repository at this point in the history
By default, any change on the content will trigger an immediate model update
and form validation. This PR implements a new directive `ng-model-options`
that allow you to override this default behavior in several ways.

You should specify an object with the different parameters.

For example, it allows to trigger an update only when a particular event or
list of events is received by the input using the `updateOn` key. Should you
need multiple events, just assign an array to it.

I.e. `ng-model-options="{ updateOn: 'blur' }"` will update and validate only
after the control loses focus.

If you want to keep the default behavior and just add new events that may
trigger the model update and validation, add "default" as one of the specified
events.

I.e. `ng-model-options="{ updateOn: ['default','submit'] }"`

Also, with the `debounce` option, `ng-model-options` will allow defering the
actual model update until a timer expires. The timer will be reset each time
an event is triggered.

I.e. `ng-model-options="{ debounce: 500 }" for 500ms after the latest event.

Custom timeouts for each event can be set for each event if you use an object
in `debounce`. This can be useful to force immediate updates on some specific
circumstances (like blur events).

I.e. `ng-model-options="{ updateOn: ['default', 'blur'], debounce: { default: 500, blur: 0} }"`

You can use the directive in any tag so its contents became the default settings
for any child control, although they can be overriden.

Closes angular#1285, angular#2129
  • Loading branch information
lrlopez committed Apr 1, 2014
1 parent c704f76 commit 9bd4aa5
Show file tree
Hide file tree
Showing 3 changed files with 491 additions and 68 deletions.
63 changes: 63 additions & 0 deletions docs/content/guide/forms.ngdoc
Expand Up @@ -181,6 +181,69 @@ This allows us to extend the above example with these features:



# Non-immediate (debounced) or custom triggered model updates

By default, any change on the content will trigger a model update and form validation. You can override this behavior using the {@link ng.directive:ngModelOptions ngModelOptions}
directive to bind only to specified list of events. I.e. `ng-model-options="{ updateOn: "blur" }"` will update and validate only after the control loses
focus. You can set a single event using an array instead of a string. I.e. `ng-model-options="{ updateOn: ["mousedown", "blur"] }"`

If you want to keep the default behavior and just add new events that may trigger the model update
and validation, add "default" as one of the specified events. I.e. `ng-model-options="{ updateOn: ["default", "blur"] }"`

You can delay the model update/validation by writing a `debounce` key. I.e. `ng-model-options="{ debounce: 500 }"` will wait for half a second since
the last content change before triggering the model update and form validation.

Custom debouncing timeouts can be set for each event for each event if you use an object in `debounce`. This can be useful to force immediate updates on
some specific circumstances (like blur events).

I.e. `ng-model-options="{ updateOn: ["default", "blur"], debounce: { default: 500, blur: 0 } }"`

If those attributes are added to an element, they will be applied to all the child elements and controls that inherit from it unless they are
overriden.

The following example shows how to override immediate updates. Changes on the inputs within the form will update the model
only when the control loses focus (blur event).

<example>
<file name="index.html">
<div ng-controller="ControllerUpdateOn">
<form name="form" class="css-form">
Name:
<input type="text" ng-model="username" ng-model-options="{ updateOn: "blur" }" name="uName" /><br />
Other data:
<input type="text" ng-model="userdata" name="uData" /><br />
</form>
<pre>username = "{{username}}"</pre>
</div>
</file>
<file name="script.js">
function ControllerUpdateOn($scope) {
$scope.username = "";
}
</file>
</example>

This one shows how to debounce model changes. Model will be updated only 250 milliseconds after last change.

<example>
<file name="index.html">
<div ng-controller="ControllerUpdateOn">
<form name="form" class="css-form">
Name:
<input type="text" ng-model="username" name="uName" ng-model-options="{ debounce: 250 }" /><br />
</form>
<pre>username = "{{user.name}}"</pre>
</div>
</file>
<file name="script.js">
function ControllerUpdateOn($scope) {
$scope.username = "";
}
</file>
</example>



# Custom Validation

Angular provides basic implementation for most common html5 {@link ng.directive:input input}
Expand Down

0 comments on commit 9bd4aa5

Please sign in to comment.