In this plunk the objective is to show an error message based on validation in the controller (instead of the built-ins required
or min-length
). The message error does not display when the ng-message-exp is set.
Any idea on how to make this work or better how ng-message
actually works which is tied to the error or model?
HTML
<body ng-app="ngMessagesExample" ng-controller="ctl">
<form name="myForm" novalidate ng-submit="submitForm(myForm)">
<label>
This field is only valid when 'aaa' is entered
<input type="text"
ng-model="data.field1"
name="field1" />
</label>
<div ng-messages="myForm.field1.$error" style="color:red">
<div ng-message-exp="validationError">this is the error</div>
</div>
<br/><br/>
<button style="float:left" type="submit">Submit</button>
</form>
Javascript
var app = angular.module('ngMessagesExample', ['ngMessages']);
app.controller('ctl', function ($scope) {
$scope.submitForm = function(form) {
if (form.field1.$modelValue != 'aaa') {
$scope.validationError = true;
console.log('show error');
}
else {
$scope.validationError = false;
console.log('don\'t show error');
}
};
});
Overview. ngMessages is a directive that is designed to show and hide messages based on the state of a key/value object that it listens on. The directive itself complements error message reporting with the ngModel $error object (which stores a key/value state of validation errors).
in controller: $scope. errors = []; $scope. hasError = false; $scope.
$dirty means the user has changed the input value, $invalid means the address itself is invalid. Therefore the error is only shown if the user has actively changed the input value to either an empty or invalid value.
Sets the form to its pristine state. This method sets the form's $pristine state to true, the $dirty state to false, removes the ng-dirty class and adds the ng-pristine class. Additionally, it sets the $submitted state to false.
Your main ng-messages
argument is tied to myForm.field1.$error
, but you never actually add an error to the form.field1.$error
. So in your controller, just manually add an error to the $error
object via $setValidity(field, isValid)
:
if ($scope.data.field1 != 'aaa') {
form.field1.$setValidity('validationError', false);
// Angular will make form.field1.$error.validationError = true;
}
else {
form.field1.$setValidity('validationError', true);
// Angular will make form.field1.$error.validationError = false;
}
Then, you can just have the ng-message
directive do its work. The child elements that provide ng-message
are evaluated as properties of their parent ng-messages
already (note the extra s
). So typically, this is used with the parent being the form element's $error
object and the inner children are the properties like $error.required
or in your case $error.validationError
. No need for ng-message-exp
here:
<div ng-messages="myForm.field1.$error" style="color:red">
<div ng-message="validationError">this is the error</div>
</div>
Fixed plunker
The more proper way to do this in controller is to use $setValidity
if(a !== b){
form.inputName.$setValidity('custom-err', false);
} else {
form.inputName.$setValidity('custom-err', true);
}
form.$setSubmitted();
The Dmitry K's answer it's excellent.
I´m going to expand the answer.
//Function before show your form:
vm.showForm(form){
form.$setPristine();
form.$setUntouched();
form.myFieldName.$setValidity('myCustomValidationName', false);
//More code...
}
//funtion to validate field on "ng-change"
vm.validateField(form){
if(xxxx == yyy) //Make your own validation{
form.myFieldName.$setValidity('myCustomValidationName', true);
}else{
form.myFieldName.$setValidity('myCustomValidationName', false);
}
}
And the relevant HTML code:
<form name="myFormName" novalidate>
<md-input-container class="md-block">
<label>myField</label>
<input ng-model="ctrl.myFieldName" name="myFieldName" ng-change="ctrl.validateField(myFormName)" />
<div ng-show="myFormName.myFieldName.$touched || myFormName.$submitted">
<div ng-messages="myFormName.myFieldName.$error">
<div ng-message="myCustomValidationName">this is the message to show</div>
</div>
</div>
</md-input-container>
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With