Thursday, September 10, 2015

AngularJS Dynamic Validation and Error Messages

AngularJS directive ngMessages provides a mechanism to show the error message dynamically. The documentation of this can be found at:


Unfortunately this documentation does not provide a sample working code which links the validation and error messages. In this blog I will show how to utilize the ngMessages to show validation error messages that are not predefined, in other words dynamically showing the messages.

In my scenario, I am doing some validations on the server (asp.net) and want to show the messages returned by the server. Let’s assume that user enters a username or something in the UI and this data is posted back to the server. On server I perform some validations such as user name should be unique and then want to show those validation messages attached to the form elements, in my case the textbox. For this dynamic ngMessages is a good fit. To demo this, I extended the AngularJS example to show the dynamic error message. Here is the AngularJS example for the ngMessages


As you see the ngMessage example on AngularJS site is using required and other messages. For this I am going to add the dynamic messages as shown below

<div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
    <div ng-message="required">You did not enter a field</div>
    <div ng-repeat="errorMessage in errorMessages">
        <div ng-message-exp="errorMessage.type">{{ errorMessage.text }}</div>
    </div>
</div>

The errorMessages object will contain the messages that we dynamically add to the textbox control. Further ngRepeat will provide us an ability to attach multiple error messages.

Now when we get the error messages from the server, we can add those to the errorMessages object and then set the validation of textbox control to false as shown by the below code

function getDynamicErrorMessage(control) {
    //making a http request and getting the error. Add that error to the errorMessages
    var serverErrors = [{ type:'dynamicMessage', text:'Error Message Shown Dynamically'}]
    angular.extend(vm.errorMessages, serverErrors);
    control.$setValidity('dynamicMessage', false);
}

With the above few lines of code, we can get the dynamic error messages and show them in UI using AngularJS ngMessages.

Here is the complete code:

<html>
<head>
    <title>Dynamic Messages Sample</title>
</head>
<body ng-app="dynamicMessages">
    <div ng-controller="index as vm">
        <form name="myForm" novalidate>
            <label>
                Enter your name:
                <input type="text" name="myName" ng-model="name" required />
            </label>
            <pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
            <div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
                <div ng-message="required">You did not enter a field</div>
                <div ng-repeat="errorMessage in errorMessages">
                    <div ng-message-exp="errorMessage.type">{{ errorMessage.text }}</div>
                </div>
            </div>
            <button ng-click="getDynamicErrorMessage(myForm.myName)">Get Dynamic ErrorMessage</button>
            <button ng-click="clearDynamicErrorMessage(myForm.myName)">Clear Dynamic ErrorMessage</button>
        </form>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-messages.min.js"></script>
    <script>
        angular.module('dynamicMessages', ['ngMessages'])
          .controller("index", index);

        function index($scope) {
            var vm = {
                errorMessages: [],
                getDynamicErrorMessage: getDynamicErrorMessage,
                clearDynamicErrorMessage: clearDynamicErrorMessage
            }

            init();
            return vm;

            function init() {
                angular.extend($scope, vm);
            }

            function getDynamicErrorMessage(control) {
                //making a http request and getting the error. Add that error to the errorMessages
                var serverErrors = [{
                    type: 'dynamicMessage',
                    text: 'Error Message Shown Dynamically'
                }]
                angular.extend(vm.errorMessages, serverErrors);
                control.$setValidity('dynamicMessage', false);
            }

            function clearDynamicErrorMessage(control) {
                control.$setValidity('dynamicMessage', true);
            }
        }
    </script>
</body>
</html>

You can also view this code in Plunker


No comments:

Post a Comment