Angular JS - How do I hide ng-message after form submit & valid entry - angularjs

I'm building a simple form using AngularJS Messages.
Basically what I want to happen is:
User submits form, all appropriate errors show and prevents
submission
User then completes fields and errors hide one by one after 'focus out' of field ($touched ?)
First point is working fine but I can't figure out the second part, I can't hide the error messages at all afterwards. I'm sure I'm missing something simple but other related questions aren't really helping too much.
Any ideas?
<form name="orderForm"
ng-submit="orderForm.$valid && placeOrder()" novalidate>
<input type="text"
ng-model="orderParams.delivery_address.full_name"
name="fullName" required />
<p ng-message="orderForm.fullName.$error"
ng-if="orderForm.fullName.$invalid && orderForm.$submitted">
This field is required</p>
<input type="submit" value="Submit" />
</form>

For me the problem was solved by adding ngMessgaes to my module dependencies.
I installed had it installed with bower before, but forgot to add it to module dependencies. For some reason it caused no errors. It only prevented my error messages from hiding.

you need to do three things:
1. add a boolean variable in your controller like: "showMessageBox" which is set to true.
2. when you submit you set "showMessageBox" to false.
3. on your message box you put the ng-show directive and bind it to "showMessageBox" variable

I actually just figured this out. I'm using Angular 1.4.2 and it would seem that Angular Messages is now part of the core build which I didn't pick up on before (I'd just forgotten to inject into the angular module), removed the angular-messages.js file (which was probably causing conflicts) and the above code works fine.
Anyone know why the seperate module is still available on code.angularjs.org? - https://code.angularjs.org/1.4.2/

Related

How to keep form error message blank on initial load in AngularJS

I'm trying to learn forms in AngularJS 1.x. But I have error messages that are always on when it first loads. How to develop behaviour such that they are blank on load, and only red after a submit if fields were not entered? Seems to be a few states I have to use the built-in directives for.
All the elements are similar so let's just take apart this bit. Also if different for a radio and dropdown list maybe we can discuss that too.
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required">The first name is required.</span>
</p>
Do I chain a few directives with || or && ?
Behaviour I'm aiming for
How to keep the error messages off when it loads?
when I hit submit, and a field is blank, will it then activate the css red error messages?
I'd like the error messages to clear as I fill in the form without reloading.
Yeah, so any tips greatly appreciated. Doesn't have to be particularly pretty
Thanks
UPDATE 1
gist of current code
Well I took a stab at it. Still really a hot mess at this point. Don't know how to use submit to test for each field and then display the error message if blank. Also seems like a lot of duplication on the testing of field states. Is there a better way to break up that logic? Ugggghhhhh
UPDATE 2
This one's weird, the form now has all text boxes not buttons or checkboxes!? But the HTML hasn't changed. Sigh
ng-if="identification.firstName.$error.required && !$pristine"
Go search more on $pristine and $dirty validator
You can add some other property to your ng-if and set its value to true only when form is submitted.
in your html add this new property
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required && running">The first name is required.</span>
</p>
in your controller set this property to true when form is submitted
$scope.submit = function(){
$scope.running = true;
...
}

Angularjs validation - bootstrap datepicker input is not recognized

If you read following Angularjs validations, you understand that:
Message will appear if user interacted and did not fill the date manually.
The problem is when date is filled using the datepicker the input is not recognized by Angularjs and still consider $invalid true, so the message remains there which is confusing/problem although date is already filled using datepicker!
<div class="form-group" ng-class="{ 'has-error' : AddForm.Birthdate.$invalid && !AddForm.Birthdate.$pristine }">
<input type="text" required data-provide="datepicker" class="form-control" name="Birthdate" ng-model="Birthdate" />
<span ng-show="AddForm.Birthdate.$invalid && !AddForm.Birthdate.$pristine" class="help-block" >
Birthdate is required.
</span>
</div>
You can either validate it prior to form submit, or else hook a listener on your datepicker to manually set the model property Birthdate value.
It seems bootstrap datepicker is built on top of JQuery datepicker, manually setting the value would be a bad practice you can refer to:
Update Angular model after setting input value with jQuery
a better approach would be to use some built-in angular component such as the ones from:
https://angular-ui.github.io/bootstrap/
http://dalelotts.github.io/angular-bootstrap-datetimepicker/
https://github.com/dalelotts/angular-bootstrap-datetimepicker
I discovered a new way for this problem-
First of all create an id for that input box and then create a function say $scope.assign(), which simply assign the id value to the model of that input.
Something Like this-
$scope.assign = function() {
$scope.modelValue = $('#idName').val();
}
Now use ng-bind="assign()" to your input box.
It worked for me :)
Was facing the issue, and its because of the picker you are using is built on top of Jquery which remains undetectable by the scope on update.
For my new project I have added another library and its pretty awesome.
See the documentation http://dalelotts.github.io/angular-bootstrap-datetimepicker
Providing the piece of code for which I have added a wrapper directive
My Previous Answer was based on work around and because at that time of answer I was pretty new to the angular and now instead of that I will recommend, not to use an library which is built on top of Jquery in Angular project. Instead prefer angular libraries.
Coming on the topic-
For date time picker I found one very good library
https://github.com/indrimuska/angular-moment-picker
You can find more libraries in built in angular, but I found it pretty useful for other validations too like min-date, max-date validation.
Using this library will solve the issue of validation for sure and its pure Angular way.

angular form validation - set required by code (not working)

if(currentAdmin.target =='new')
{
$('#btnDel').hide();
//Not working !!!
$('#inputPassword1').attr("ng-required","true");
$('#inputPassword2').attr("ng-required","true");
}
else
{
$('#btnDel').show();
$('#inputPassword1').attr("ng-required","true");
$('#inputPassword2').attr("ng-required","true");
}
Well, basically I want to place the ng-required based on the condition. I made a trial using the required (without ng) and it does not works as well.
I inspected the element and injected the required and ng-required into the html and it's not works.
This will always be ignored after rendered. I need to do such thing like "Validator, refresh because it's different now"
any clue ?
Even though I myself hate the kind of answer I am about to give, I feel it is appropriate in this situation: This is not the way to write if using angular...
So what should you do?
place the ng-required in the html code and set the value of the attribute to a bound variable that you set depending on your condition.
Example:
index.html
<form ng-controller="formController">
<input type="password" ng-required="isAdmin">
<input type="password" ng-required="!isAdmin">
</form>
app.js
angular.module('app',[]).controller('formController', function($scope){
$scope.isAdmin=false;
if(currentAdmin.target == 'new'){
$scope.isAdmin=true;
}
});
Not complete code, but hopefully you still understand what I mean.

validation with dynamic name in ng-repeat

Im currently having an issue where I want to create multiple form inputs with validation. The form elements I want to
create will be up to 100 duplicated fields. To do this I have used ng-repeat as can be seen in this small example below. As you may notice
I have a dynamic model and name for my input. Everything works fine with the one exception of validation.
When I inspect the element in the html the dynamic name has got applied as expected and the first name input is called
test0. As you may know form validation in angular is done using the form name and input name. As my input is dynamically
named it seems to be causing issues as you can see by my error output it doesnt seem to log the error correctly, however,
if I was to hardcode the name as test0 instead of test{{i}} (which in the html inspection is test0) everything would work.
This is an issue as validation on the duplicated inputs is not doable this way and the only way I can think of resolving this
is outputting 100 html input elements manually with the only difference being the name of each input. This is not Ideal and I was
wondering if anyone knows a way around this issue or if it is a known bug with Angular? Quite possibly I could just be doing something stupid.
<ng-form name="testform">
<div ng-repeat="i in [0,1,2]">
ERROR {{testform.test0.$error}}
<label>
TEST<br />
<input name="test{{i}}" ng-model="$parent.test[i]" type="text" required />
</label>
</div>
Any help with this matter would be greatly appreciated as I have spent a considerable amount of time trying to resolve this issue.
Thanks.

AngularJS custom form validation error message

Is there any way to pass an error message in custom form validation?
E.g. I have a directive that checks a username. There are three possible outcomes:
It is valid
It is invalid because it isn't a good username ("this.is-invalid")
It is invalid because it is already in use
I have a directive like (simplified pseudo-html):
<input type="text" namecheck></input><span ng-show="name.$error.namecheck">You had an error {{ error }}</span>
And in my custom directive, I can do
// check for a conflict and valid name here
ngModel.$setValidity("namecheck",false);
But how do I pass an error message that indicates if the problem was a conflict or invalid name? Is there anything like ngModel.$setValidityErrorMessage() ?
As I wrote in the comments, I just figured it out. I just need to use different validity flags. Nothing says that I have to use the same key in $setValidity() as the name of the directive!
<span ng-show="name.$error.nameinvalid">This is not a valid username, it must be alphanmueric</span>
<span ng-show="name.$error.nametaken">Sorry, the username {{ name }} is already taken</span>
And in the directive
// if I got a 409
ngModel.$setValidity("nametaken",false);
// if I got a 400
ngModel.$setValidity("nameinvalid",false);
The name of the $error is the error message!
No. Setting the validity on a form element just simply adds the appropriate class to the element, which can then be used to style the element to indicate an error. There aren't any error messages that indicate why the element is invalid. Angular doesn't provide that support.
You may have noticed error messages that pop up on required fields that are empty? In chrome they say something like: "Please fill out this field" or something. Those are browser-specific and aren't related to angular in any way.
You'd have to roll your own error messaging service. You can use the same ng-invalid classes to check when a form element is invalid and show the error messages based on that, but Angular doesn't provide that out of the box.
There is an example in the angular docs (found here) that shows one way you can do that.
UPDATE:
As of Angular 1.3, there is now support for the ngMessage and ngMessages directives. These new directives attempt to make form validation and error messaging less of a hassle. The angular docs for these directives are here. Check the link out for more details.
In my opinion, your three rules include both client and server validation. I'll validate the first two in client side, and the validate last rule in server side.
Because an username is duplicate or not, we get it until we post it to the server.
So, my practice is following:
<div class="col-md-offset-3 col-md-9" ng-show="detailForm.$error && detailForm.name.$invalid && (detailForm.name.$touched || detailForm.$submitted)"
ng-messages="detailForm.name.$error">
<div class="error-message" ng-message="required">the field is required </div>
<div class="error-message" ng-message="maxlength">you are too lang</div>
<div class="error-message" ng-message="pattern">your format is incorrect </div>
</div>
<div class="col-md-offset-3 col-md-9" ng-show="serverError && serverError.name">
<div class="error-message">{{serverError.name}}</div>
</div>

Resources