Angular enabling and disabling component or element based on input changes - javascript

How do we do this in angular, make button disabled by default if email address is invalid , If email is invalid get started button will enable and the user can click get started button ,
after the user click get started button it will disabled again and will only enable again if user changes the email input and if the new email input is valid , vice versa.
I already have the checked and the form controls , but is there a cleaner way to do this in angular? Thanks.
#html code
<mat-form-field class="full-width" appearance="fill" style="margin-top: 20px;">
<mat-label>Email</mat-label>
<input type="email" matInput autocomplete="emailAddress" matInput formControlName="emailAddress" />
<mat-error *ngIf="modelForm.get('emailAddress').hasError('email')">
Email is in invalid format.
</mat-error>
<mat-error *ngIf="modelForm.get('emailAddress').hasError('required')">
Email is required.
</mat-error>
</mat-form-field>
</div>
<div style="text-align:right;margin-top: 19.0px;">
<button click)="getStarted()" [disabled]="!modelForm.get('emailAddress')?.valid" mat-flat-button color="primary"
class="v-btn-sml" id="get-started-button">
Get Started
</button>
</div>
#ts validation code
ngOnInit(): void {
this.initFormGroup();
}
initFormGroup() {
this.modelForm = this.formBuilder.group({
id: [this.model.id || 0],
emailAddress:[this.model.emailAddress,[Validators.required, Validators.email]],
});
}

Angular has built in validators you can use, combining it with the ReactiveFormsModule you have to import in your app.module.ts.
In your typescript file you can do it like:
formGroup: FormGroup;
private model: { id: number; emailAddress: string } = {
id: 1,
emailAddress: ''
};
ngOnInit() {
this.formGroup = new FormGroup({
id: new FormControl(this.model.id),
email: new FormControl(this.model.emailAddress, [Validators.email])
});
}
And than in your html file you can access this formControls valid/invalid state.
<form [formGroup]="formGroup">
<input type="text" formControlName="email">
<button type="button" [disable]="form?.get('emailAddress').invalid">
</form>

Related

mat-form-field required field is showing red asterik even if there is no error in Angular

Iam facing the issue that mat-form-field required asterik even if there is no error. I would like to show blue asterik if there is no error. I have spent a lot of time but I am not able to fogure it out. If anyone knows what is wrong then please let me know. Thank you
<mat-form-field appearance="outline" class="input-field-large input-normal-wide" matInput>
<mat-label>Name</mat-label>
<input
(input)="onNameChange()"
formControlName="name"
type="text"
autocomplete="off"
matInput
maxlength="50"
required="required"
/>
<mat-icon
*ngIf="form.hasError('required', 'name') && isNameSubmitted"
class="mdi mdi-24px mdi-alert-circle"
matSuffix
>
</mat-icon>
<mat-error *ngIf="form.hasError('required', 'name') && isNameSubmitted">
<span>{{ "This field is mandatory" | translate }}</span>
</mat-error>
<mat-error *ngIf="form.hasError('maxlength', 'name') && isNameSubmitted">
<span>{{ "Maximum 50 charachers are allowed" | translate }}</span>
</mat-error>
</mat-form-field>
It can be done as follow:
::ng-deep .mat-form-field.mat-focused {
.mat-form-field-required-marker {
color: blue;
}
}
::ng-deep .mat-form-field.mat-form-field-invalid {
.mat-form-field-required-marker {
color: red;
}
}
If you want to change the color of the "*", add this .css to your "styles.css" (not in the component.css)
.mat-focused .mat-form-field-required-marker
{
color:blue
}
.ng-invalid.ng-touched.mat-focused .mat-form-field-required-marker
{
color:red
}
In only want to hide the "*" you use
[required]="form.hasError('required','name')?true:null"
See the stackblitz
Since you're using a form field with formControlName directive i guess you have a formGroup, if you just want to make sure the input has a value don't use required directly on the template, instead use Validators in the .ts file of your component.
For example:
public myFormGroup: FormGroup = new FormGroup({
name: new FormControl('', Validators.required)
})
In the FormControl constructor you can pass, as the second parameter, a validator function or an array of validator functions. The required function is one of them, addional pre-defined validators are:
max
min
not-null
pattern(for regex validations)
and more.
You can also define a custom function if you need it tho

Edit Email firestore vue

I have a problem editing the 'email' field. When I click change mail, the email changes correctly, but when I want to log in again, the new email is not working, only the old one is still working. How to do it so that after clicking on change email it will change in the database so that after logging in again the new email will work. I do not know how to do this. I have this code.
<template>
<div class="editemail">
<div class="container">
<form class="form" #submit.prevent>
<!-- email -->
<label for="email" class="form__label">Email</label>
<input
class="form__input"
type="text"
id="email"
name="email"
:placeholder="userProfile.email"
v-model.trim="email"
/>
<button class="form__button" type="submit" #click="editEmail()">
ZmieƄ email
</button>
</form>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex';
import * as firebase from '../firebase';
export default {
data() {
return {
email: '',
};
},
computed: {
...mapState(['userProfile']),
},
methods: {
editEmail() {
firebase.usersCollection.doc(firebase.auth.currentUser.uid).update({
email: this.email,
});
},
},
};
</script>
If you're using Firebase Authentication to sign the user in, then the email address that it uses has nothing to do with the value you store in the database.
To update the email address that Firebase uses to sign in, you'll also want to call firebase.auth().currentUser.updateEmail(this.email) to update the user's email address.

Angular Validation: Validate/Highlight child input on button click

Using Angular 6 here:
I have a parent component and within that I have a child component. The child component has a text fields. The parent has a submit button.
On the submit click button, I want to validate all the inputs of the child as they are required and throw error accordingly.
I am using reactive forms and was successfully able to pass form info from parent to child. But I am not sure how to highlight my text input when the submit button is clicked.
I have used $touched property on my child, which works and shows the required error. But I want the error to also show in case user just clicked the button.
Here is some relevant code.
--Parent--
<form class="form-horizontal" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<child [myForm]="myForm"></child>
<button type="submit">Submit</button>
</form>
<br>
Form Valid: <pre>{{myForm.valid}}</pre>
export class AppComponent {
myForm: FormGroup
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
uname: ['', Validators.required]
});
}
onSubmit() {
console.log('value: ', this.myForm.value);
console.log('the whole form and its controls: ', this.myForm)
}
}
--Child--
<div class="form-group" [formGroup]="myForm">
<label for="myForm" class="col-sm-3 control-label">Name:</label>
<div class="col-sm-8" [ngClass]="{ 'has-error': myForm.controls?.uname.errors }">
<input type="text" formControlName="uname" placeholder="Enter Name...">
<em *ngIf="myForm.hasError('required', 'uname') && myForm.controls?.uname.touched">*Required</em>
</div>
</div>
export class ChildComponent {
#Input() myForm: FormGroup;
ngOnInit() {
}
}
I have also created a demo to show this at:
https://stackblitz.com/edit/angular-dbevnj
FYI, this is just a sample I created to show my issue. I would be having 2-3 child components and few form controls on each.
Any inputs how to get this resolved?
We resolved this by calling markAsTouched on all form controls when submitting the form.
In your case you can add this.myForm.get('uname').markAsTouched(); to your onSubmit() method.

angular 5, reactive form- resetting a required form control does not reset the required error under the input

In the template I have a form that is opened by pressing on a button-
<form [formGroup]="person"
(ngSubmit)="onSubmitNewPerson()"
#formDirective="ngForm">
<mat-form-field>
<input matInput formControlName="firstName" required>
</mat-form-field>
<mat-form-field>
<input matInput formControlName="lastName" #last required>
</mat-form-field>
</form>
In the component I have this code-
#ViewChild('formDirective') formDirective: FormGroupDirective;
this.person = this.formBuilder.group({
lastName: ['', Validators.required],
firstName: ['', Validators.required]
});
After closing the button I run this function-
this.formDirective.resetForm();//hack that I saw in some question
this.person.reset();
but after openning again the form, I immediatly see the red error under the input.
I also tried this-
this.person.get('firstName').markAsUntouched();
this.person.get('lastName').markAsUntouched();
this.person.get('firstName').markAsPristine();
this.person.get('lastName').markAsPristine();
But this does not work also.
Any idea how to fix it?
I used the following once when I wanted to reset the validators:
this.person.get('firstName').clearValidators();
this.person.get('firstName').updateValueAndValidity();
Simply remove required from your html template and if you want to display error message on focus out than try this to show different error message.
this is html template:
<div class="form-group">
<label for="name" class="form-control-label">
*Amount:
</label>
<input type="number" name="amount" class="form-control" [formControl]="form.controls['amount']">
<div>
<small *ngIf="form.controls['amount'].hasError('required') && form.controls['amount'].touched" class="text-danger">
Please enter an amount.
</small>
<small *ngIf="form.controls['amount'].hasError('min') && form.controls['amount'].touched" class="text-danger">
Your amount must be at least 0.01.
</small>
<small *ngIf="form.controls['amount'].hasError('max') && form.controls['amount'].touched" class="text-danger">
Your amount cannot exceed 999999.99.
</small>
</div>
This is component.ts
import { FormGroup, FormBuilder, Validators} from '#angular/forms';
constructor(private fb: FormBuilder) { }
this.form = this.fb.group({
amount: [null, Validators.compose([Validators.required, Validators.min(0.01), Validators.max(999999.99)])],
});
Although this question is slightly old,
This answer may help people who have this issue.
If this problem occurs in the Angular material mat-stepper, you can see the solution offered for this question.
(That why some respondents were unable to reproduce the problem)

how to validate expansion panel title highlight, when expansion panel having input field and while having empty value In Angular

Am trying to create Expansion Panel in Angular 7, I have a small issue. In expansion panel title section font colour should change when the expansion panel input field having data, it must changed to green , if input field is empty panel title should be in red colour. i tried for that but i didn't get , can u please help me out.
Thanks & Regards
<form [formGroup]="formGroup2">
<mat-expansion-panel [expanded]="step === 0"(opened)="setStep(0)"hideToggle>
<mat-expansion-panel-header>
<i class="material-icons">arrow_right_alt</i>Call Volumes
</mat-expansion-panel-header>
<mat-card>
<mat-card-content>
<mat-form-field style="width: 300px; padding: 10px;" class="example-full-width">
<input matInput placeholder="Calls / Volumes / Transaction per month" formControlName="secondCtrl" required>
</mat-form-field>
<mat-form-field style="width: 350px; padding: 10px;">
<input matInput placeholder="AHT Per call / volume / transaction in Seconds" formControlName="eighthCtrl" required>
</mat-form-field>
</mat-card-content>
</mat-card>
<mat-action-row>
<button mat-button color="primary" (click)="nextStep()">Next</button>
</mat-action-row>
</mat-expansion-panel>
</form>
Here is the app.component.ts code
formGroup2: FormGroup;
constructor(private _formBuilder: FormBuilder ) {}
ngOnInit() {
this.formGroup2 = this._formBuilder.group({
eighthCtrl: ['', Validators.required],
});

Categories