Angular 4: mismatch input fields with error message - javascript

I want to compare password field and confirm password without creating a new directive, just using ngModel and HTML. I have a submit button blocked if the passwords don't match, and thats working fine. But I want to show a span error message when the user is retyping (or on submit) and so far, right after the first input on the password field (when the retype is empty) I get the error message. It's logical, with the code I have, but I wonder if it's possible to have a better UX without using validators or directives? I've tried several aproaches but nothing worked...Any hint would be appreciated. The code:
<form #confirm="ngForm" novalidate>
<mat-form-field class="full-width">
<input matInput type="password" id="password" placeholder="New Password" name="password"
[(ngModel)]="loginValues.password" required>
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="password" id="confirmPassword" placeholder="Retype Password" name="confirmPassword"
[(ngModel)]="loginValues.confirmPassword" required>
</mat-form-field>
<!--Error Message-->
<span *ngIf="loginValues.confirmPassword !== loginValues.password">{{ 'login.password_not_match' | translate }}</span>
<div class="child-padding-top no-side-padding" fxLayoutAlign="end center" >
<button class="button-login-register" [disabled]="loginValues.password !== loginValues.confirmPassword" mat-button color="primary"
(click)="clientNewPassword()" >{{ 'login.SUBMIT' | translate }}</button>
</div>
</form>

You should not use a span for *ngIf, unless you are using the span for a purpose (add a class to it, etc.). But it seems you are just using that to hold your *ngIf statement, since *ngIf has to be tagged to an element. If you're going to do this, you should instead use
<ng-container *ngIf=""></ng-container>.
To answer your question, the only thing that I think you can do without applying validation, is to add more logic. For example you could do:
<ng-container* ngIf="loginValues.confirmPassword !== loginValues.password
&& loginValues.confirmPassword.length > 0
&& loginValues.password.length > 0 ">
{{ 'login.password_not_match' | translate }}
</ng-container>
Basically what you're doing is changing it so that the error is not always shown when the passwords don't match, but instead the user has to have filled out both inputs first. There's other things you could do. For example you could use ngTouched/ngDirty, etc. You can set up the rules as you like them.

Related

How to display max limit error message without using ts file in angular?

I want to show error message like required error message for max input limit but using below code it work for required but not for maxlength . I also not to use ts file . Is there any way to achieve this. Thanks
<form #featureForm="ngForm">
<mat-form-field class="featureInputForm" appearance="fill">
<mat-label>Feature Namre</mat-label>
<input matInput [(ngModel)]="featureName" required name="featureName" maxlength="64" (ngModelChange)="moduleNameChange($event)" />
<mat-error *ngIf="featureForm.controls['featureName']?.errors?.required">Feature Name is required.</mat-error>
<mat-error *ngIf="featureForm.controls['featureName']?.errors?.maxlength">Maximum limit exceed.</mat-error>
</mat-form-field>
</form>
According to documentation for HTML attribute: maxlength, the browser will generally prevent the user from entering more text than the maxlength attribute allows. This explains why you don't see the error message when typing into the input.
However, if the value is longer than the maxlength on the .ts side of things, then the code you have will render the error text. For instance assuming maxlength=10 and if featureName = '12345678901' <- string is longer than maxlength so error message would render on the page.
See this stackblitz for an example.
There are two approaches to this.
1. Use reactive forms approach
2. Use template forms approach
As per your requirement, you don't want to use the .ts file for validation.
Then you can proceed with template-driven forms in angular rather than proceeding with the reactive forms-driven approach. Reactive Forms driven approach mainly deals with forms of validation-related logic in the .ts file itself. While in the template-driven approach it does handle the logics in the template itself.
For further reading on reactive-forms in angular
For further reading on template-forms in angular
Please refer to the code block below :
<form #featureForm="ngForm">
<mat-form-field class="featureInputForm" appearance="fill">
<input matInput name="featureName" [ngModel]="featureName" maxlength="10" #featureName="ngModel" required>
<div *ngIf="featureName.errors" [ngClass] = "'error'">
<div *ngIf="featureName.errors.maxlength">
Name must be at least 10 characters long.
</div>
<div *ngIf="featureName.errors.required">
featureName is required.
</div>
</div>
</mat-form-field>
</form>

How to disable input fields conditionally in Vuejs

<input
:type="passwordFieldType"
v-model="user.password"
id="password"
name="password"
class="input-section-three"
:class="{ 'is-invalid': submitted && $v.user.password.$error }"
placeholder="Enter new password"
:maxlength="maxpassword"
v-on:keypress="isPassword($event)"
/>
<input
:type="passwordFieldTypetwo"
v-model="user.confirmPassword"
id="confirmPassword"
name="confirmPassword"
class="input-section-three"
:class="{
'is-invalid': submitted && $v.user.confirmPassword.$error,
}"
placeholder="Confirm password"
:maxlength="maxconfirmpassword"
v-on:keypress="isconfirmPassword($event)"
/>
I have two input fields like password and confirm password. where i am trying to disable confirm password field, untill user enter some content in password field. Can we do anything with v-bind:disabled="newPassword.length === 0 ? true : false" to get resolved.
If you simply need to lock the second field until the user types anything in the first one, try using the disabled attribute on the second input:
<input
:disabled="!user.password"
...
>
This will set the disabled attribute as long as the value of user.password is falsy (eg. empty string).
You can set either the :disabled="!newPassword" or :read-only="!newPassword" properties on the field.
Either one should achieve the desired outcome, and then in your css if you need to apply any specific styles to the field you can use #confirmPassword::disabled {} or #confirmPassword::read-only {}

Angular 5 required form fields not working with material

My first Angular app with Angular 5.
I am following the documentation here: https://angular.io/guide/form-validation. Here is the form that I created:
<form class="form-container">
<mat-form-field>
<input matInput placeholder="Shop Name" [(ngModel)]="pizzaPlace.shopName"
id="shopName" #shopName="ngModel"
required minlength="4">
</mat-form-field>
<div *ngIf="shopName.invalid && (shopName.dirty || shopName.touched)"
class="alert alert-danger">
<div *ngIf="shopName.errors.required">
Shop name is required.
</div>
<div *ngIf="shopName.errors.minlength">
Shop name must be at least 4 characters long.
</div>
</div>
<br/>
<mat-form-field>
<input matInput placeholder="Contact Name" [(ngModel)]="pizzaPlace.contactName"
id="contactName" #contactName="ngModel"
required minlength="4">
</mat-form-field>
</form>
So now if I read the docs correctly, entering and leaving the shop name field will generate an error, but it doesn't seem to be working. I get no indication whatsoever that there's any kind of a problem at all.
Template driven forms need a name attribute.
<input matInput placeholder="Shop Name" [(ngModel)]="pizzaPlace.shopName"
id="shopName" #shopName="ngModel"
required minlength="4"
name="shopName">
https://stackblitz.com/angular/eqormqnlkme
I would recommend strongly to use reactive forms, they aren't more difficult to master, but much more powerful.
Also, angular-material provides a built in component for error handling:
mat-error
you need to add a component to display the error
<mat-form-field>
<input matInput placeholder="Shop Name" [(ngModel)]="pizzaPlace.shopName"
id="shopName" #shopName="ngModel"
required minlength="4">
<mat-error>I said required !</mat-error>
</mat-form-field>

How to enable a button once all form fields pass

My first Angular 5 app.
I've read through: https://angular.io/guide/form-validation and several pages I googled to find the answer, only to find that they're all really out of date.
I have multiple input boxes on my form like:
<form name="pizzaPlaceForm" class="form-container">
<mat-form-field>
<input matInput placeholder="Shop Name" [(ngModel)]="pizzaPlace.shopName"
id="shopName" name="shopName" #shopName="ngModel"
required minlength="4">
<mat-error>You must provide a shop name at least 4 characters in length.</mat-error>
</mat-form-field>
<br/>
<mat-form-field>
<input matInput placeholder="Contact Name" [(ngModel)]="pizzaPlace.contactName"
id="contactName" name="contactName" #contactName="ngModel"
required minlength="4">
<mat-error>You must provide a contact name at least 4 characters in length.</mat-error>
</mat-form-field>
</form>
Now I want to control the disabled state of my button and only enable it when all of the required fields have been entered, like:
<button mat-raised-button disabled="pizzaPlaceForm.$invalid" (click)="onCreateClick()" *ngIf="createMode">Create</button>
Only it doesn't appear that $invalid works any more, so how do I do this with Angular 5?
you want to disable the button if the form is not valid. so you can try below
<button mat-raised-button [disabled]="!pizzaPlaceForm.valid" (click)="onCreateClick()" *ngIf="createMode">Create</button>
Add an identifier for the form with an ngForm. Then you can disabled the submit button
with [disabled] attribute.
[disabled]="pizzaPlace.form.invalid" OR [disabled]="pizzaPlace.invalid"
<form #pizzaPlace="ngForm" name="pizzaPlaceForm" class="form-container">
<button mat-raised-button [disabled]="pizzaPlace.form.invalid" (click)="onCreateClick()" *ngIf="createMode">Create</button>
</form>

How to hide/show helper messages in form validation with AngularJS?

I have included ngMessages into my AngularJS application to do some form validation. It's pretty useful, however I've came across something that I can't really understand.
Let's say I have this code inside my Form that is named: testForm
<input type="text" name="test1" class="form-control" ng-model="test1" required>
<span class="help-block" ng-hide="testForm.test1.$error">Please enter the a test name</span>
<div ng-messages="testForm.test1.$error" ng-if="testForm.test1.$dirty">
<div class="text-danger" ng-message="required">This field is required</div>
</div>
I want to hide the helper message when there is an error in this textbox EXCEPT if the user hasn't started to type anything yet (on $dirty).
How is this possible? With this above code my testForm.test1.$error always gives me true value even if it's empty, therefore always hiding it.
What am I missing here?
EDIT:
I'm clarifying more what I want to achieve:
when typing, the helper message should be visible and the error message should be hidden
when there is an error, the helper message should be hidden and the error message should be visible
when nothing is touched yet, the helper message should be visible and the error message should be hidden
Have you tried ng-hide="testForm.test1.$error && testForm.test1.$dirty"? That way the message always displays when the input field is clean (not dirty).
Edit:
As far as I see it, you want the message to be visible when input field has focus.
In your controller, initialize hasFocus to false:
$scope.hasFocus = false;
In your HTML file:
<input type="text" name="test1" class="form-control" ng-model="test1"
ng-focus="hasFocus=true" ng-blur="hasFocus=false" required>
<span class="help-block" ng-hide="!hasFocus && testForm.test1.$error && testForm.test1.$dirty">Please enter the a test name</span>
<div ng-messages="testForm.test1.$error" ng-if="testForm.test1.$dirty">
<div class="text-danger" ng-message="required">This field is required</div>
</div>
You can replace ng-hide as follows if it suits you. It will hide the message when test1 is not empty and when it has error.
ng-hide="!hasFocus && testForm.test1.$error && test1"

Categories

Resources