Angular js ng messages show error on init - angularjs

In my project I have angularjs 1.5.10 and ng-messages 1.5.10. I use it in simple form:
<form class="form-horizontal" ng-submit="createBooking()" role="form" name="createBookingForm" novalidate>
<div class="form-group">
<label for="payment_details_last_name" class="col-sm-3 control-label">Last name</label>
<div class="col-sm-6">
<input type="text"
id="payment_details_last_name"
name="payment_details_last_name"
class="form-control"
ng-model="payment_details.last_name"
ng-required="true"
ng-maxlength="30" />
<div ng-messages="createBookingForm.payment_details_last_name.$error" role="alert">
<div ng-message="required">This field is required</div>
<div ng-message="maxlength">Your field is too long</div>
</div>
</div>
<div class="col-sm-3"></div>
</div>
</form>
In controller:
$scope.members = [{
'first_name': '',
'last_name': '',
'email': '',
'phone_number': '',
'date_of_birth': '',
}];
And on initial I always see error This field is required. I tried to create empty object in controller:
$scope.createBookingForm = {};
I also show form after initialized <div ng-if="initialized">
Nothing is working. Project using angular-seed skeleton
I saw dirty hacks like if $touched else, but I want to understand what is wrong...

Nothing is wrong about it, check out the sample in the official guide. They have required error shown by default. It seems wrong for the first glance, but this is the only correct way to handle such a case.
So basically, ng-messages does exactly what docs says:
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 works in a real time and shows errors for current input state, that makes sense.
So if you want no messages to be shown by default, you should use some of approaches, discussed hundred of times
How to make ngMessage for required fields only show when dirty or submitting a form?
Angular : ng-message validation on submit click
AngularJS: Hiding ng-message until hitting the form-submit button
AngularJS 1.5.6 reset form & ng-messages
If you need some other improved behavior - there is no quick solution at the moment, you have to come up with your own validation engine that fit your needs.

Related

Deletion Error with Email Validation in Angular

So I've recently taken over an Angular Giving Form Application. I am running validation on the email field using ng-pattern and displaying the errors on blur with ngMessages. The validation works great, however once the validation passes as $valid if the user decides they need to make a change in their email and begin to delete part of the first deletion deletes the last character of the email as expected, but the second deletion deletes the entire field forcing the user to start from scratch.
The regex for ng-pattern is being set in the controller scope with the variable $scope.emailre
The files are much to large to place here but here is the link to the site I am working on for my client.
https://epiqa.moodyglobal.org/corporate/
Snippet of Angular controller:
myApp.controller('mainCtrl', function($scope, localStorageService, $http) {
$scope.emailre = /^(([^<>()\[\]\\.,;:\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,}))$/;
Snippet of HTML Form:
<div class="row form-group">
<div class="col-sm-6">
<div>
<label class="label" for="txt_donorEmail">E-mail:</label>
<input ng-class="{ 'submitted-error' : givingForm.email.$invalid && submitted }" ng-model="email" type="text" id="email" name="email" class="textbox required full form-control" maxlength="50" ng-pattern="emailre" required />
</div>
<div ng-messages="givingForm.email.$error" ng-if="givingForm.email.$touched || submitted">
<div class="errorText" ng-message="required">This field is required</div>
<div class="errorText" ng-message="pattern">Enter a valid email</div>
</div>
</div>
</div>
I have tried changing the input type from type="text" to type="email" but when doing that any time the user types two (.) periods the field gets immediately deleted.
Please help any ideas are very welcome.
The behavior is caused by this section
$scope.$watch('email', function(value){
localStorageService.set('email',value);
$scope.emailValue = localStorageService.get('email');
});
By Angular documentation
The default behaviour in ngModel is that the model value is set to undefined when the validation determines that the value is invalid. By setting the allowInvalid property to true, the model will still be updated even if the value is invalid.
I'm not sure whether you want to save the invalid email into localStorage, though. Maybe you can add a check only update when the value is valid.

How to get the uib-popover to open or close when the focus of the input field changes

I have a input field that has the uib-popover control on it. I have followed the documentation on how to get the directive to open but I have noticed some discrepancies in the documentation as well as examples on plnker and SO questions here.
Within my hmtl I have the inputs set as follows:
<div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-6">
<label>Password</label><input type="{{user.inputType}}" ng-blur="user.validatePassword(user.newUser.password, user.newUser.confirmPassword)" placeholder="Enter Password" id="password" required class="form-control" ng-model="user.newUser.password" uib-popover-template="'myPopoverTemplate.html'" uib-popover-trigger="'focus'"/>
</div>
<div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-6">
<label>Confirm Password</label>
<input type="{{user.inputType}}" ng-keyup="user.validatePassword(user.newUser.password, user.newUser.confirmPassword)" placeholder="Confirm Password" id="confirmPassword" required class="form-control" ng-model="user.newUser.confirmPassword"/>
<span style="color: red">{{user.message}}</span>
</div>
Most examples as well as the SO questions on here are using an older library as attributes are not prefaced with uib-*.
This code/directive currently works and renders but it only work or appears when clicking in the field and then clicking in the same field to close the popover. I have tried both the focus trigger and the oustsideClick trigger. Both have the same result of not rendering or closing the popover unless clicking in the field.
versions of the frameworks used are:
angularjs 1.5.8
ui-bootstrap 1.3.3
Changing the trigger to match earlier examples were popover-trigger is used vs. uib-popover-trigger is used disables the popover
I have created a working plunker that demonstrates what is happening.
Any suggestions on what I am missing or what I need to change.
Thanks in advance
According to tooltip.js description, in order to set a custom trigger,
it needs to be specified via trigger option passed to the $tooltipProvider.options method. In your case for focus trigger it will be:
app.config(['$uibTooltipProvider', function ($uibTooltipProvider) {
$uibTooltipProvider.options({ trigger: 'focus' });
}]);
Updated plunker that shows how to trigger tooltip on focus handler.
There's a problem of your code, please modify like below:
app.js:
(function() {
var app = angular.module('app', ['ui.bootstrap']);
app.controller('main',[ '$scope', main]);
function main($scope)
{
vm = this;
vm.message = 'hello';
vm.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
}
}());
index.html
<input class="form-control" uib-popover-template="vm.dynamicPopover.templateUrl" popover-trigger="focus"/>
Actually, you can not just pass the template's id to the uib-popover-template attribute, you need to create an object to map it waited to pass.

Form validation with modals in Angular

I have a form inside a modal pop up. I am trying to run form validation on the inputs after the user attempts to submit the form. So far, I'm struggling to make things work.
In my view, I have the following (sorry if there are any syntax errors, I'm converting this from jade on the fly):
<script type="text/ng-template", id="modalVideoNew">
<div class="ngdialog-message">
<form class="form-horizontal" ng-submit="submitForm()" novalidate name="newVideoForm">
...
<div class="form-group">
<label> Title </label>
<div class="col-sm-8">
<input type="text" name="title", required='', ng-model="newVideoForm.title">
<span class="text-danger" ng-show="validateInput('newVideoForm.title', 'required')"> This field is required</span>
</div>
</div>
</div>
</script>
And then in my controller, where I'm calling the ng-dialog pop up, I have this:
$scope.newVideo = function() {
ngDialog.openConfirm({
template: 'modalVideoNew',
className: 'ngdialog-theme-default',
scope: $scope
}).then(function() {
$scope.validateInput = function(name, type) {
var input = $scope.newVideoForm[name];
return (input.$dirty || $scope.submitted) && input.$error[type];
};
var newVideo = $scope.newVideoForm;
...
Right now, I am still able to submit the form, but once I open it back up I see the 'This field is required' error message. Also, the input is pre-filled with [object, Object] instead of an empty text input box.
A way of cleaning your model would work with using a model var that belongs to your parent controller and cleaning it in the callback. Check out how the template has attached your parent controller's var FormData.
Check this out
So about your validation, what I would recommend you is to have your own controller in it, no matter how much code it will have. It helps you keeping concepts of modularization and a better control over your scopes. This way will also facilitate a lot when validating.

angularjs: ng-message always showing

I'm using angular-messages to display form validation errors on my angular app.
As per the documentation, I have built the following code
<form name="loginForm">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="data.email" name="email" required>
</label>
<div ng-messages="loginForm.email.$error" style="color:maroon">
<div ng-message="required">Please input a valid e-mail address</div>
<div ng-message="email">You did not enter your email address correctly...</div>
</div>
</form>
I have included the ngMessages directive in my javascript as well as imported the angular-messages.js file.
Unfortunately, these two messages are showing perpetually. Regardless of what I type in the input field, be it a valid email or not. Both messages are always showing. If I try to only include one ng-message, the result is the same.
What could I be doing wrong?
edit: In case my description isn't very clear, this is a print of the result
https://s9.postimg.cc/du9230tdb/Screen_Shot_2015_06_26_at_17_09_24.png
You gotta make sure you are actually including ngMessage to your module.
var app = angular.module('app', [
'ngMessages'
])
... and that you included the library to your project
<script src="/scripts/vendors/angular-messages/angular-messages.js"></script>
Everything seems to be fine in the code you're sharing.
<form name="loginForm">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="data.email" name="email" required>
</label>
<div ng-messages="loginForm.email.$error" style="color:maroon">
<div ng-message="required">Please input a valid e-mail address</div>
<div ng-message="email">You did not enter your email address correctly...</div>
</div>
</form>
Here is a working copy on Plunker I'm using your piece of code.
From Angularjs documentation.
By default, ngMessages will only display one error at a time. However, if you wish to display all messages then the ng-messages-multiple attribute flag can be used on the element containing the ngMessages directive to make this happen.
If you want to show the errors after the field is dirty, please visit this link.
Make sure you are including ngMessage module and the library as well. Please see Carlos's answer.
Thanks
Check with
<div ng-messages="loginForm.email.$error" ng-show="loginForm.email.$invalid && loginForm.email.$touched">
...
</div>
This trick saved my day.

angular 1.3.6 ng-messages are present regardless of value

I'm trying to incorporate some of the new features of 1.3 into our app. I have a form and couldn't seem to get ng-messages to work. So I put it in a plunker and I still seem to be doing something wrong. My view looks like this:
<form name="profileForm"
ng-submit="profile.submit(profileForm.$valid)"
novalidate>
<input type="text" name="favoriteNumber"
ng-model="profile.number"
required ng-minlength="5" />
<div class="errors" ng-messages="profileForm.favoriteNumber.$error">
<div ng-message="required">this is required</div>
<div ng-message="minlength">this is too short</div>
</div>
<input type="submit" value="Save" />
</form>
I expected to see only one ng-message tag at a time, but both are present when the page loads.
At least I expect the message to go away as their validation criteria are met, but no matter what I type in the input, both messages are always present. It is as if I didn't include the ng-messages script at all.
What am I doing wrong here?
var app = angular.module("demo", ['ngMessages']);
include ngMessages module in you application module as a dependency.
plunker

Resources