Date validation in AngularJS form - angularjs

I have an input with type text, that I'm using to set dates:
<input ng-model="model.JoinDate"
ui-mask="{{'99/99/9999'}}"
type="text" required
ng-class="{error: form.JoinDate.$dirty && form.JoinDate.$invalid}" />
The problem is that the user can type something like 00/00/0000.
How can I validate the date, without creating a new directive?

What about using angular ui bootstrap datepicker?
http://angular-ui.github.io/bootstrap/#/datepicker

<span style="color:red" ng-show="subform6{{$index}}.$dirty && subform6{{$index}}.date.$invalid && subform6{{$index}}.date.$error">
<br> <small ng-show="subform6{{$index}}.fd_judgement_date.$error.pattern">Incorrect Format, should be DD/MM/YYYY</small>
</span>
</ng-form>

Related

ng-show doesn't work in form

I create form and use AngularJs. I need display errors and I have a problem.
My expression for ng-show doesn't work.
My code:
<form name="createProductForm" ng-submit="createProduct(product)" novalidate>
<input type="text" ng-model="product.name" ng-minlength="3" required> <br>
<p ng-show="createProductForm.product.name.$error.required && createProductForm.product.name.$dirty">Nazwa produktu jest wymagana.</p>
<p ng-show="createProductForm.product.name.$error.minlength && createProductForm.product.name.$dirty">Nazwa produktu jest zbyt krótka.</p>
<button type="submit" ng-disabled="createProductForm.$invalid">Dodaj produkt</button>
</form>
Your input tag MUST have a name attribute. ngModel does not provide validation states.
<input name="nameAttributeHere"/>
<p ng-show="createProductForm.nameAttributeHere.$error.required && createProductForm.nameAttributeHere.$dirty">...</p>
ngModel and form validation states are completely separate directives.

$dirty vs $invalid: What is the difference?

I am a novice in angular. I am confused by $dirty and $invalid, they almost sound the same.
What is the difference between $dirty and $invalid used in email ng-model? Below is the scenario. It's an example form W3Schools.
<form ng-app="myApp" ng-controller="validateCtrl" name="myForm" novalidate>
<p>
Username:<br>
<input type="text" name="user" ng-model="user" required>
<span style="color: red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
<span ng-show="myForm.user.$error.required">Username is required.</span>
</span>
</p>
<p>
Email:<br>
<input type="email" name="emaill" ng-model="email" required>
<span style="color: red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</p>
<p>
<input type="submit" ng-click="Count()"
ng-disabled="myForm.$invalid" title="Submit" value="Submit">
</p>
</form>
EDIT 1:
I am wondering if I change the ng-model name from email to email8 it's not working anymore.
<input type="email" name="emaill" ng-model="email8" required>
Whether the validation is doing by myForm HTML element name which is not defined using ng attribute. How does it work?
ng-show="myForm.email.$dirty && myForm.email.$invalid"
$dirty: It will be TRUE, if the user has already interacted with the form.
$invalid: It will be TRUE, if at least one containing form and control is invalid.
Source
Also on Angular Docs
After the update in the Question...The validation is being done on the form element name. All the ng-models inside a form is tracked and that is how it is working.
Also changing a ng-model name will have no impact on validation. I tried your link and it works for me. That has to work.
$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.
$dirty is True if user has already interacted with input. And $invalid is true if the the input is not a valid email address
$error is the object of errors where the key is the field validation name and value is the actual error message
<input type="email" name="emailName" ng-model="email" required>
for this example myForm.emailName.$error.email = true if email is not matched with format.
myForm.emailName.$error.required = true if you haven't added anyhting in input field
you can check valid or not of the field directly by using myForm.emailName.$valid but
the problem in your case is they want to show the user what is the error by having two cases. so they entered into $error object to check for the error is required email or invalid email
1.Email is required.
2.Invalid email address.
so they used $error object.
this is how myForm.emailName looks:
{"$viewValue":"ss","$validators":{},"$asyncValidators":{},"$parsers":[],"$formatters":[null],"$viewChangeListeners":[],"$untouched":false,"$touched":true,"$pristine":false,"$dirty":true,"$valid":false,"$invalid":true,"$error":{"email":true},"$name":"emailName","$options":null}
I think the example provide by you explains a lot.
You have done mistake That is why it was not working , can you see below code which you have written
<pre>
<input type="email" name="emaill" ng-model="email8" required>
<ng-show="myForm.email.$dirty && myForm.email.$invalid">
</pre>
Why it was not working because input name you have given "emaill" and in myForm.email.$dirty you have given "email" If both names should be same then it will work fine
<pre>
<input type="email" name="emaill" ng-model="email8" required>
<ng-show="myForm.emaill.$dirty && myForm.emaill.$invalid"></pre>

How to make field required with k-ng-model?

I have validation issue if i use k-ng-model on field that field is not required with Angularjs validation , User can submit the form so below code field is required even i dont select the value user can still submit the form.. Any idea how to solve it ?
main.html
<div class="row">
<div class="form-group col-md-12">
<label for="themesList" class="required col-md-4">Themes:</label>
<div class="col-md-8">
<select class="multiselect" kendo-multi-select="themes"
k-options="challengThemesOptions" data-text-field="'text'"
data-value-field="'id'" name="themesList"
k-ng-model="challengesDTO.themesKyList" required
id="themesList"></select>
<p class="text-danger" ng-show="addChallengeForm.themesList.$touched && ddChallengeForm.themesList.$error.required">Theme(s) is required</p>
</div>
</div>
</div>
You can use ng-model with k-ng-model, Try assigning ng-model to a seperate variable and use ng-required.
<select class="multiselect" kendo-multi-select="themes"
k-options="challengThemesOptions" data-text-field="'text'"
data-value-field="'id'" name="themesList"
k-ng-model="challengesDTO.themesKyList" ng-model="challengesDTO.themesKyListValue" ng-required
id="themesList"></select>
This solution worked for me: kendo ui, angular require validation for numeric text box
Just create a hidden input for the each kendo widget and bind the model from your k-ng-model also to the ng-model of the hidden field. The k-ng-model seems to be no NgModelController, which is why the validators cannot hook into the models $validators and do their work.
<input kendo-date-time-picker k-ng-model="$ctrl.event.endDate"></input>
<input type="hidden" name="endDate" ng-model="$ctrl.event.endDate" required></input>

Why name attribute required in AngullarJs validation

Friends, I am new to angularjs please explain why name attribute required for angularjs validation
<form name="lform" novalidate>
<input type="text" name="userName" ng-model="userName" required novalidate/>
<span style="color:red" ng-show="lform.userName.$dirty && lform.userName.$invalid">
<span ng-show="lform.userName.$error.required">Username is required.</span>
</span>
<br/>
</form>
If I remove name="userName" code not working, please explain this.
Update: If I remove "ng-model" it is not working, but I can change "ngmodel='newName'" is working, please explain this reason also.
This is just how HTML form works, name describe the parameter that will be sent to the server.
Angular's approach is to extend HTML and its behaviour, instead of inventing the wheel. Angular encapsulates "form" (see ngForm directive) and extend it. Because name is the unique id of an input in a form, it is also the unique id of the input in ngForm's collection.
ng-model is another directive that bind the value of the input into a variable in the current scope, it doesn't have to hold the same value as name.
Let's take your example and change ng-model:
<form name="lform" novalidate>
<input type="text" name="userName" ng-model="object.name" required novalidate/>
<span style="color:red" ng-show="lform.userName.$dirty && lform.userName.$invalid">
<span ng-show="lform.userName.$error.required">Username is required.</span>
</span>
<br/>
</form>
The validation will work, but the variable that will be updated in your scope is "object.name".
To sum it up, lform.userName holds the metadata and object.name will hold the actual data.
The answer is in your code.
<span ng-show="lform.userName.$error.required">Username is required.</span>
Angular is using the input name to store the error related information.
lform – your form name
username – your input name

Validating nested form in angular

Having this ordinary (name attribute is requred by server) form with angular and can't figured out how to make validations work. What should i put into ng-show="TODO"
http://jsfiddle.net/Xk3VB/7/
<div ng-app>
<form ng-init="variants = [{duration:10, price:100}, {duration:30, price:200}]">
<div ng-repeat="variant in variants" ng-form="variant_form">
<div>
<label>Duration:</label>
<input name="variants[{{$index}}][duration]" ng-model="variant.duration" required />
<span ng-show="TODO">Duration required</span>
</div>
<div>
<label>Price:</label>
<input name="variants[{{$index}}][price]" ng-model="variant.price" />
<span ng-show="TODO">Price required</span>
</div>
</div>
</form>
</div>
ps: this is just piece of form, which is more complicated
Thanks
AngularJS relies on input names to expose validation errors.
Unfortunately, as of today it is not possible (without using a custom directive) to dynamically generate a name of an input. Indeed, checking input docs we can see that the name attribute accepts a string only.
Long story short you should rely on ng-form to validate dynamically created inputs. Something like :
<div ng-repeat="variant in variants" >
<ng-form name="innerForm">
<div>
<label>Duration:</label>
<input name="duration" ng-model="variant.duration" required />
<span ng-show="innerForm.duration.$error.required">Duration required</span>
</div>
<div>
<label>Price:</label>
<input name="price" ng-model="variant.price" required/>
<span ng-show="innerForm.price.$error.required">Price required</span>
</div>
</ng-form>
Working fiddle here
UPDATE : Base on your serverside requirement why not do something like that :
<input type="hidden" name="variants[{{$index}}][duration]" ng-model="variant.duration"/>
<input name="duration" ng-model="variant.duration" required />
The hidden input will be the one read by the server while the other one will be used to do the client side validation (later discarded by server). It s kind of an hack but should work.
PS : Be sure that your form is valid before actually submitting it. Can be done with ng-submit

Resources