Forms and ng-model-options in AngularJs 1.3

ng-model-options

{
    // This can be any event or multiple events (space separated list)
    // Accepts default for the default event
    updateOn: 'blur',

    // time in milliseconds
    debounce: 300, // or debounce: { 'default': 300, 'blur': 0 } - events must be in updateOn

    // Update model with values that did not validate?
    allowInvalid: true,

    // determines whether or not to treat functions bound to ngModel as getters/setters
    getterSetter: true,

    // determines which timezone to use when parsing a date/time input
    // default is the browser's time zone
    // UTC is the only tiemzone supported
    timezone: 'UTC'
}
<input type="text" ng-model="myModel" ng-model-options="{updateOn: 'blur', debounce: 300}" />

$rollbackViewValue()

$commitViewValue()

    angular
        .module('app', [])
        .directive('deaAwesomeModelDirective', deaAwesomeModelDirective);

    function deaAwesomeModelDirective() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: link
        };

        function link(scope, elm, attrs, ngModelController) {
            elm.bind("keyup", function (e) {
                if (e.keyCode === 13) {
                    scope.$apply(function() {
                        ngModelController.$commitViewValue();
                    });
                }

                if (e.keyCode === 27) {
                    ngModelController.$rollbackViewValue();
                }
            });
        }

Validation

  • All HTML5 validation attributes
    • required="bool"
    • minlength="number"
    • maxlength="number"
    • min="number"
    • max="number"
    • pattern="patternValue"
  • <input type="...">
    • type="email"
    • type="url"
    • type="number"
    • type="date"
    • type="time"
    • type="datetime-local"
    • type="week"
    • type="month"

$validators pipeline

<input type="text" name="standard" class="form-control" ng-model="vm.standard" 
    dea-standard-validator>
    angular
        .module('app', [])
        .directive('deaStandardValidator', deaStandardValidator);

    function deaStandardValidator() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: link
        };

        function link(scope, elm, attrs, ngModelController) {
            // The name of the function is what shows up in the $error object
            // Must return boolean
            ngModelController.$validators.standardValidator = function(val) {
                return val === 'standard';
            };
        }
    }

$asyncValidators pipeline

    angular.module('app', []).directive('deaAsyncValidator', deaAsyncValidator);

    // This validator will only run after all standard validators pass
    deaAsyncValidator.$inject = ['$q', '$timeout'];
    function deaAsyncValidator($q, $timeout) {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: link
        };

        function link(scope, elm, attrs, ngModelController) {
            ngModelController.$asyncValidators.asyncValidator = function(value) {
                // $pending property on model and form while unresolved
                // both $valid and $invalid are set to undefined until resolved
                var defer = $q.defer();

                $timeout(function () {
                    // model is not update until this happens
                    if (value === 'async') {
                        defer.resolve();
                    } else {
                        defer.reject();
                    }
                }, 3000);

                return defer.promise;
            };
        }
    }

ngMessages

<form name="myForm" novalidate>
    <input type="text" name="messages" class="form-control" ng-model="vm.mes" required 
        ng-minlength="5" ng-maxlength="10">
    
    <!-- $touched is new in 1.3 -->
    <!-- standardize error message with ng-messages-include -->
    <!-- override any message from ng-messages-include by just including it -->
    <div ng-show="myForm.messages.$touched" ng-messages="myForm.messages.$error">
        <div ng-message="required">You did not enter a field</div>
        <div ng-message="minlength">Your field is too short</div>
        <div ng-message="maxlength">Your field is too long</div>
    </div>
</form>

Thank You!

Forms and ng-model-options in AngularJs 1.3

By Dale Alleshouse

Forms and ng-model-options in AngularJs 1.3

  • 4,721