ng-minlength in directive not populated when invalid - angularjs

I'm creating an input directive that encapsulates a label, and some error messaging but I'm getting stuck with ng-minlength and ng-maxlength. The issue is that they don't populate the model value until it's a valid value, so my parent scope can display a value while my directive doesn't, and vice versa. View this plunk for an example of what I mean.
Is the only way around this to define my own minlength and maxlength validators? Is there some way configure this behaviour so the model is always populated? I want to use all the built in validators in my directive, so no doubt this will be an issue with all of them and I'd rather not redefine them all.
HTML:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="Controller">
<label>Outer scope 1</label>
<input name="input1" type="text" ng-model="model1" ng-minlength="4"/>
<br/>
<label>Directive scope 1</label>
<input-dir ng-model="model1" ng-minlength="0"></input-dir>
<br/>
<br/>
<br/>
<label>Outer scope 2</label>
<input name="input3" type="text" ng-model="model2"/>
<br/>
<label>Directive scope 2</label>
<input-dir ng-model="model2" ng-minlength="4"></input-dir>
</body>
</html>
Javascript:
var app = angular.module('app', []);
app.controller('Controller', function($scope){
$scope.model1 = "Model1";
$scope.model2 = "Model2";
});
app.directive('inputDir', function(){
return {
restrict: 'E',
template: '<input type="text" ng-model="model" ng-minlength="{{ minlength }}" />',
scope: {
model: '=ngModel',
minlength: '=ngMinlength'
}
};
});

For anyone else with the same issue, I solved this by redefining all the validators, except now they return the value when invalid so the model is populated. Just include the valuedValidators module. These validators are available on the $error object as vvminlength etc.
vv-validators.js
(function () {
'use strict';
var validators = {};
validators.vvUrl = function(value){
var urlRegex = new RegExp(/[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi);
return urlRegex.test(value);
}
validators.vvEmail = function(value){
var emailRegex = new RegExp(/^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
return emailRegex.test(value);
}
validators.vvMinlength = function(value, min){
var huh = value.length >= parseInt(min);
return min && value && huh;
}
validators.vvMaxlength = function(value, max){
return max && value && value.length <= parseInt(max);
}
validators.vvMin = function (value, min) {
return min && parseFloat(value) >= parseFloat(min);
}
validators.vvMax = function (value, max) {
return max && parseFloat(value) <= parseFloat(max);
}
validators.vvPattern = function (value, pattern) {
return pattern && new RegExp(pattern).test(value);
}
validators.vvFloat = function (value) {
var floatRegex = new RegExp(/^\-?\d+((\.|\,)\d+)?$/);
return floatRegex.test(value);
}
validators.vvInteger = function (value) {
var integerRegex = new RegExp(/^\-?\d+$/);
return integerRegex.test(value);
}
var app = angular.module('valuedValidators', []);
var names = Object.keys(validators);
names.forEach(function(name){
app.directive(name, function(){
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, controller) {
controller.$parsers.unshift(function (viewValue) {
var valid = true;
var attrValue = attrs[name];
var func = validators[name];
if (attrValue !== 'false') {
valid = func(viewValue, attrValue);
controller.$setValidity(name.toLowerCase(), valid);
}
return viewValue;
});
}
};
});
});
}());

There is an even easier solution: use two textareas.
The first serves as a draft, the second is the model where the verification is to take place.
<textarea name="message_body_draft" cols="47" rows="15" style="width: 100%;"
ng-model="message_body_draft"
ng-change="message_body=message_body_draft"></textarea>
<textarea name="message_body" style="width: 100%;" disabled ng-model="message_body"
ng-minlength="100" required></textarea>
When the user writes in the first one, it automatically will populates the right model (the second one).

Related

How to validate against multiple fields and display a unique error?

I want to validate a control against multiple fields. And I want to display an error indicating which field(s) caused validation to fail.
Run the following code. Change the first value to a high number (E.G. 5) and validation will pass. Change the first value to a low number (2) and validation will fail.
In the case of "2" there should be 2 errors: model3, model4 because those models are higher values than 2. Similarly for all other fields.
The validation works fine. I'm having trouble displaying the correct error messages based on the particular validation rule that failed.
Note, any field changes must re-fire validation just like it does now. You should run this snippet in full page view.
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.model = {number: "1"};
$scope.model2 = {number: "2"};
$scope.model3 = {number: "3"};
$scope.model4 = {number: "4"};
});
app.directive('theGreatest', function(){
return {
require: 'ngModel',
restrict: 'A',
link: function($scope, $element, $attr, ngModel) {
var compareCollection;
// watch the attribute to get the date we need to compare against
$attr.$observe('theGreatest', function (val) {
console.log('compareCollection set to: ', val);
compareCollection = JSON.parse(val);
ngModel.$validate();
});
ngModel.$validators.theGreatest = function(modelValue, viewValue) {
console.log('validating...', modelValue);
console.log('compareDate: ', compareCollection);
var pass = true;
_.map(compareCollection, function(compare){
console.log('comparing value: ', compare);
if(modelValue < compare){
pass = false;
}
});
console.log('validation pass', pass);
return pass;
};
}
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<section ng-app="app" ng-controller="MainCtrl">
<div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" />
(change me to a high number)
</div>
<div>second: <input ng-model="model2.number" type="text" /></div>
<div>third: <input ng-model="model3.number" type="text" /></div>
<div>fourth: <input ng-model="model4.number" type="text" /></div>
<div>validation passed if you see a value here: {{model.number}}</div>
<div>The following errors are not implemented correctly. The intention is to show what I am want to accomplish</div>
<div ng-if="!model.number">ERROR: first is less than model 2</div>
<div ng-if="!model.number">ERROR: first is less than model 3</div>
<div ng-if="!model.number">ERROR: first is less than model 4</div>
<div ng-if="!model.number">ERROR: first is required</div>
</section>
You need to send ErrorFlags array into directive and while you are validating mark those flags as false when validation fails.
HTML:
<section ng-app="app" ng-controller="MainCtrl">
<div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" error-flags="errorFlags" />
(change me to a high number)
</div>
<div>second: <input ng-model="model2.number" type="text" /></div>
<div>third: <input ng-model="model3.number" type="text" /></div>
<div>fourth: <input ng-model="model4.number" type="text" /></div>
<div>validation passed if you see a value here: {{model.number}}</div>
<div>The following errors are not implemented correctly. The intention is to show what I want to accomplish</div>
<div ng-if="!errorFlags[0]">ERROR: first is less than model 2</div>
<div ng-if="!errorFlags[1]">ERROR: first is less than model 3</div>
<div ng-if="!errorFlags[2]">ERROR: first is less than model 4</div>
<div ng-if="!model.number">ERROR: first is required</div>
</section>
AngularJS Code:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.model = {number: "1"};
$scope.model2 = {number: "2"};
$scope.model3 = {number: "3"};
$scope.model4 = {number: "4"};
$scope.errorFlags = [true, true , true];
});
app.directive('theGreatest', function(){
return {
require: 'ngModel',
restrict: 'A',
scope: {
errorFlags:"="
},
link: function(scope, element, attrs, ngModel) {
var compareCollection;
// watch the attribute to get the date we need to compare against
attrs.$observe('theGreatest', function (val) {
console.log('compareCollection set to: ', val);
compareCollection = JSON.parse(val);
ngModel.$validate();
});
ngModel.$validators.theGreatest = function(modelValue, viewValue) {
console.log('validating...', modelValue);
console.log('compareDate: ', compareCollection);
scope.errorFlags = [true, true, true];
console.log("Before Validation Flags", scope.errorFlags);
var pass = true;
var loopVariable = 0;
_.map(compareCollection, function(compare){
console.log('comparing value: ', compare);
if(modelValue < compare){
pass = false;
scope.errorFlags[loopVariable] = false;
}
loopVariable++;
});
console.log("after Validation Flags", scope.errorFlags);
console.log('validation pass', pass);
return pass;
};
}
};
});

Dynamically update ion.rangeSlider ngModel in AngularJS directive

I'm trying to update the value of an Ion.RangeSlider when its bound ng-model scope variable changes. The model updates when the Ion.RangeSlider is used, but not vice-versa. Other inputs with the same ng-model update when the model value changes, so this must be some special case.
Edit: Woo! Here's a snippet #lin :) Also jsfiddle.
var app = angular.module('ngModelIonRangeSliderDemo', []);
app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {
$scope.someNumber = 10;
}).directive('ionRangeSlider', function ionRangeSlider() {
return {
restrict: 'A',
scope: {
rangeOptions: '=',
model: '=ngModel'
},
link: function (scope, elem, attrs) {
scope.$watch('model',function () {
elem.ionRangeSlider(scope.rangeOptions);
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />
<div ng-app="ngModelIonRangeSliderDemo">
<div ng-controller="MainCtrl" class="wrapper">
<h3>Text input updates slider, but not vice-versa.</h3>
<input ion-range-slider ng-model="someNumber" range-options="{min: -100, max: 100, step: .001}">
<br/>
<input type="text" ng-model="someNumber" class="form-control">
</div>
</div>
I have tried all kinds of suggestions in over ten somewhat-related stack overflow posts (which is how I have set up the current scope.$watch scheme on the ngModel), but none have worked. There aren't any errors in my console. What's wrong? Also, why doesn't it work without any mention of the model in my directive? Please let me know if there's anything important I have failed to include in this post.
Just use slider.update() inside your directive and you will be fine:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {
$scope.someNumber = 15;
$scope.apply = false;
}).directive('ionRangeSlider', function ionRangeSlider() {
return {
restrict: 'A',
scope: {
rangeOptions: '=',
model: '=ngModel',
apply: '=apply'
},
link: function (scope, elem, attrs) {
elem.ionRangeSlider(scope.rangeOptions);
scope.$watch('apply',function () {
if (scope.apply) {
scope.apply = false;
var slider = elem.data("ionRangeSlider");
slider.update({
from: scope.model
});
}
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />
<div ng-app="myApp" ng-controller="MainCtrl" class="wrapper">
<h3>Text input updates slider and vice-versa.</h3>
<input ion-range-slider ng-model="someNumber" apply="apply" range-options="{min: -100, max: 100, step: .001}">
<br/>
<input type="text" ng-model="someNumber" class="form-control" ng-change="apply = true">
</div>
Extra demo, how binding ion.rangeSlider to input works:
http://jsfiddle.net/IonDen/r5aox84v/
var $range = $(".js-range-slider"),
$inputFrom = $(".js-input-from"),
$inputTo = $(".js-input-to"),
instance,
min = 0,
max = 1000,
from = 0,
to = 0;
$range.ionRangeSlider({
type: "double",
min: min,
max: max,
from: 200,
to: 800,
onStart: updateInputs,
onChange: updateInputs
});
instance = $range.data("ionRangeSlider");
function updateInputs (data) {
from = data.from;
to = data.to;
$inputFrom.prop("value", from);
$inputTo.prop("value", to);
}
$inputFrom.on("input", function () {
var val = $(this).prop("value");
// validate
if (val < min) {
val = min;
} else if (val > to) {
val = to;
}
instance.update({
from: val
});
});
$inputTo.on("input", function () {
var val = $(this).prop("value");
// validate
if (val < from) {
val = from;
} else if (val > max) {
val = max;
}
instance.update({
to: val
});
});

AngularJS: How to refresh $viewValue even when $modelValue is unchanged

In the example below, the value in input 'ia' can get out of sync with the model value (e.g. if you type in 'aaa'). What I would like to achieve is when the input 'ia' loses focus, update its value to the formatted value of the current model value (e.g. when model value is null, update the view value to string 'N/A'). Anybody know I this might be achieved? Thanks.
The current behaviour is if you type in 'aaa' as profession, model value is updated to null bot 'aaa' stays in the input.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script>
var myapp = angular.module('myapp', []);
myapp.controller('mycontroller', function($scope) {
$scope.model = {
name: "ttt",
age: 24,
profession: null
};
});
var professionList = [{
id: 1,
name: "p1"
}, {
id: 2,
name: "p2"
}, {
id: 3,
name: "p3"
}, {
id: 4,
name: "p4"
}];
myapp.directive("prof", function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$formatters.push(function(value) {
for (var i = 0; i < professionList.length; i++) {
if (value == professionList[i].id)
return professionList[i].name;
}
return "N/A";
});
//format text from the user (view to model)
ngModel.$parsers.push(function(value) {
for (var i = 0; i < professionList.length; i++) {
if (value == professionList[i].name)
return professionList[i].id;
}
return null;
});
element[0].ngModel = ngModel;
}
};
});
</script>
</head>
<body ng-controller="mycontroller">
<form>
Name:
<input ng-model="model.name" />
<br />Age:
<input ng-model="model.age" />
<br />Profession:
<input prof="" ng-model="model.profession" id="ia" />
<input ng-model="model.profession" />
</form>
<hr />Name: {{model.name}}
<br />Age: {{model.age}}
<br />Profession: {{model.profession}}
</body>
</html>
UPDATE:
I found a solution based on the answer in this question
//add this to the link function:
ngModel.$render = function(){
element[0].value = ngModel.$viewValue;
};
element[0].onblur = function(){
var viewValue = ngModel.$modelValue;
for (var i in ngModel.$formatters) {
viewValue = ngModel.$formatters[i](viewValue);
}
ngModel.$viewValue = viewValue;
ngModel.$render();
};
While returning null you are not re-initializing ngModel and I dont think directive is needed here , there is something called ng-blur in angularjs,
Profession : <input ng-model="model.profession" ng-blur="checkProfession() "/>
Profession ID : <input ng-model="model.id" />
In your controller write a function as,
$scope.checkProfession=function(){
var flag=0;
for (var i = 0; i < professionList.length; i++) {
if ($scope.model.profession == professionList[i].name){
$scope.model.id=professionList[i].id;
flag=1;
}
if(!flag){
$scope.model.id="";
$scope.model.profession="";
}
}
}

How to focus to next field when field value reaches a max length

I have a scenario where I have two or more textarea, when user enters the value in the textarea and when the values reaches to max-length for example ng-max-length is 15, the focus should automatically move to next text-area.
How this can be achieved?
For controlling the max-length I have taken solution from this link .
But i do not know how to make the focus to next element automatically
Below i have given the code which i tried
textarea.html
<!DOCTYPE html>
<html>
<head>
<title>Angular App</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<div ng-app="taApp">
<div ng-controller="taController">
<textarea my-maxlength="15" ng-model="ta1.text1" rows="4" cols="20"> </textarea>
<textarea my-maxlength="15" ng-model="ta2.text2" rows="4" cols="20"> </textarea>
<textarea my-maxlength="15" ng-model="ta3.text3" rows="4" cols="20"> </textarea>
</div>
</div>
<script src="js/libs/angularjs-1.0.2/angular.js" type="text/javascript"></script>
<script src="js/controller/pageController.js" type="text/javascript"></script>
<script src="js/controller/textAreaFocus.js" type="text/javascript"></script>
</body>
</html>
textAreaFocus.js
angular.module('textareafocus',[]).directive('myMaxlength', function() {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
var maxlength = Number(attrs.myMaxlength);
function fromUser(text) {
if (text.length > maxlength) {
var transformedInput = text.substring(0, maxlength);
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
return transformedInput;
}
return text;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
});
pageController.js
var taApp = angular.module('taApp',["textareafocus"]); // this creates a new angular module named "myApp";
taApp.controller('taController', function ($scope,$http) {
$scope.ta1 = { text1: 'TextArea 1'};
$scope.ta2 = { text2: 'TextArea 2'};
$scope.ta3 = { text3: 'TextArea 3'};
});
Screenshot
Currently i have only 3 textarea but it could be more, therefore focus should move to next element automatically.
I tried with element[ 1 ].focus() but it doesn't works.
Kindly help me how to resolve this issue.
You can implement a custom directive that requires jQuery to find the other text areas, ngMaxlength to determine the maximum length (this can be changed to a custom attribute), and tabindex to determine tab order:
Directive
app.directive('autoNext', function() {
return {
restrict: 'A',
link: function(scope, element, attr, form) {
var tabindex = parseInt(attr.tabindex);
var maxLength = parseInt(attr.ngMaxlength);
element.on('keypress', function(e) {
if (element.val().length > maxLength-1) {
var next = angular.element(document.body).find('[tabindex=' + (tabindex+1) + ']');
if (next.length > 0) {
next.focus();
return next.triggerHandler('keypress', { which: e.which});
}
else {
return false;
}
}
return true;
});
}
}
});
HTML
<textarea ng-maxlength="10" tabindex="1" auto-next></textarea>
<textarea ng-maxlength="10" tabindex="2" auto-next></textarea>
<textarea ng-maxlength="10" tabindex="3" auto-next></textarea>
Demo Fiddle
Can't you use jQuery in your textarea.html? If you can, then here's a solution:
$("textarea").keyup(function(event) {
if ($(this).val().length == $(this).attr("maxlength")) {
textfields = $("textarea");
curr = textfields.index(this);
next = textfields[curr + 1];
if (next != null) {
next.focus();
}
}
});
JSFiddle Link: http://jsfiddle.net/a2gtnmrm/

Use ngMessages with Angular 1.2

Does anyone know if there is a fork of Angular 1.2 that supports ngMessages?
I'd love to use this but I have a requirement for IE8.
Thanks in advance for your help.
Here is my directive I use:
/**
* Ui-messages is similar implementation of ng-messages from angular 1.3
*
* #author Umed Khudoiberdiev <info#zar.tj>
*/
angular.module('uiMessages', []).directive('uiMessages', function () {
return {
restrict: 'EA',
link: function (scope, element, attrs) {
// hide all message elements
var messageElements = element[0].querySelectorAll('[ui-message]');
angular.forEach(messageElements, function(message) {
message.style.display = 'none';
});
// watch when messages object change - change display state of the elements
scope.$watchCollection(attrs.uiMessages, function(messages) {
var oneElementAlreadyShowed = false;
angular.forEach(messageElements, function(message) {
var uiMessage = angular.element(message).attr('ui-message');
if (!oneElementAlreadyShowed && messages[uiMessage] && messages[uiMessage] === true) {
message.style.display = 'block';
oneElementAlreadyShowed = true;
} else {
message.style.display = 'none';
}
});
});
}
};
});
I've used ui-messages instead of ng-messages to avoid conflicts.
<div ui-messages="form.name.$error">
<div ui-message="minlength">too short</div>
<div ui-message="required">this is required</div>
<div ui-message="pattern">pattern dismatch</div>
</div>
I don't know for sure if a fork exists but it would be easy enough to roll your own ng-message (or something that serves the same purpose). I think the following would do it:
Controller
app.controller("Test", function ($scope) {
$scope.messages = {
"key1": "Message1",
"key2": "Message2",
"key3": "Message3"};
$scope.getMessage = function (keyVariable) {
return $scope.messages[keyVariable.toLowerCase()];
};
$scope.keyVariable = 'key1';
});
HTML (example)
ENTER A KEY: <input type="text" ng-model="keyVariable" />
<h1 ng-bind="getMessage(keyVariable)" ng-show="getMessage(keyVariable) != ''"></h1>
See It Working (Plunker)
I've updated pleerock's answer to handle element directives having for and when attributes like ngMessages and ngMessage. You can find the same in this github repo
angular.module('uiMessages', []).directive('uiMessages', function() {
return {
restrict: 'EA',
link: function(scope, element, attrs) {
// hide all message elements
var messageElements = element.find('ui-message,[ui-message]').css('display', 'none');
// watch when messages object change - change display state of the elements
scope.$watchCollection(attrs.uiMessages || attrs['for'], function(messages) {
var oneElementAlreadyShowed = false;
angular.forEach(messageElements, function(messageElement) {
messageElement = angular.element(messageElement);
var message = messageElement.attr('ui-message') || messageElement.attr('when');
if (!oneElementAlreadyShowed && messages[message] && messages[message] === true) {
messageElement.css('display', 'block');
oneElementAlreadyShowed = true;
} else {
messageElement.css('display', 'none');
}
});
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<form name="userForm" ng-app="uiMessages" novalidate>
<input type="text" name="firstname" ng-model="user.firstname" required />
<ui-messages for="userForm.firstname.$error" ng-show="userForm.firstname.$dirty">
<ui-message when="required">This field is mandatory</ui-message>
</ui-messages>
<br />
<input type="text" name="lastname" ng-model="user.lastname" required />
<div ui-messages="userForm.lastname.$error" ng-show="userForm.lastname.$dirty">
<div ui-message="required">This field is mandatory</div>
</div>
</form>

Resources