Disabled Datepicker is validated - html

I have a form class with several inputs. There is a Checkbox, which enables/disables Datepicker input (Datepicker is not required) based on boolean variable (switchDate). Even if the Datepicker is disabled, it will be still validated and causing whole form to have status invalid.
My submit form button condition is: [disabled]="productForm.invalid". Unfortunately this button will be disabled without valid Datepicker field.
My question is: how to validate Datepicker field only if it is enabled?
PS I am newbie to Angular
I've tried to change submit button disabled criteria to focus on other fields errors, but this way it will pass any input in Datepicker
I was trying to find some method to check if the Datepicker field is enabled/disabled inside submit button condition, but no luck here
<input type="checkbox"
name="switcherChk"
id="switcherChk"
checked="true"
(change)="changeDatepickerVisibility()" />
<mat-form-field class="example-full-width">
<input matInput [matDatepicker]="picker"
[min]="todaysDate"
placeholder="Example text"
formControlName="userDate"
[attr.disabled]="switchDate ? '' : null"
required = false
>
<mat-datepicker-toggle matSuffix [for]="picker">
<mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>
</mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
<mat-error *ngIf="productForm.controls['userDate'].invalid">
Date should be greater or equal to current date.
</mat-error>
</mat-form-field>

Resolved this way (on the Component side):
private changeUserDateValidators(): void{
var dateControl = this.productForm.get(this.UserDateField);
if (this.switchDate) {
dateControl.setValidators(Validators.required);
}
else {
dateControl.clearValidators();
}
dateControl.updateValueAndValidity();
}
Depending on what you want to achieve, you can replace Validators.required to your custom validator.

Related

Reset ion-input/range value whenever it is loaded on screen

I would like my ion-input and ion-range slider to reset their value to the value set by [(ngModel)] whenever the slider/input is loaded on the page. The slider/input fields show when the user presses a button on the page. Then the user has the option of saving their inputs or canceling, which hides the slider/input. When they cancel I want it so that the value of the slider/input is set to whatever the input was when they last saved. Currently anything a user inputs is kept on the slider/input if they cancel, although the value set by [(ngModel)] is not updated.
I'm using HTML, Angular and TypeScript for this portion of the program.
Here's the important code:
<div *ngIf="showFilter">
<ion-input [(ngModel)]="aFilter" type="number" name="a" min="0"></ion-input>
<ion-range
min="1"
max="3"
snaps="true"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="bFilter">
</ion-range>
<ion-button shape="round" (click)="showFilter=false; filter()">Submit</ion-button>
<ion-button shape="round" (click)="showFilter=false">Cancel</ion-button>
</div>
You can try something like this:
In ngOnInit() as soon as the component is loaded:
ngOnInit() {
this.aFilter.value = '';
}

Angular reactive Form Control default value has no impact

I have a question concerning angular reactive form. When I want to set default values for my form controls it does not work in the HTML.
TS:
// set form controls
this.DataService.TabArchivForm = this.fb.group({
ArchiveControl: [true],
DateChannelControl: [Date.now(), Validators.required]
});
HTML:
<div class="tab_main" [formGroup]="this.DataService.TabArchivForm">
<mat-form-field class="field_width">
<mat-label class="Inputlabel">Date</mat-label>
<input class="Inputvalue" matInput id="date" [formControl]="this.DataService.TabArchivForm.controls.DateChannelControl" [matDatepicker]="dp3" required>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
<mat-error *ngIf="this.DataService.TabArchivForm.controls.DateChannelControl.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
<mat-checkbox color="primary" [formControl]="this.DataService.TabArchivForm.controls.ArchivControl" id="archive">Archive</mat-checkbox>
</div>
I don't know why it does not set the default values for the HTML elements. The checkbox is unchecked and the input field from the date picker is empty as well. Am I missing something?
Thanks for answers!

How to close an Angular Material Mat Datepicker Calendar on enter key

Is it possible to close the Mat Datepicker Calendar window when pressing the enter key? Right now if I click my form input field the calendar opens. I want to be able to press the enter key but close the calendar window and not have it stay open.
<form #form="ngForm" (keyup.enter)="sumbitByEnter($event)">
<mat-form-field floatLabel="never">
<input name="id" matInput placeholder="Search for student by ID number"
[(ngModel)]="model.id" minlength="9" maxlength="9" #uname="ngModel">
</mat-form-field>
<mat-form-field>
<input name="startDate" matInput [max]="model.endDate" [matDatepicker]="picker"
(click)="picker.open()" (focus)="picker?.open()" placeholder="Start Date"
[(ngModel)]="model.startDate">
<mat-datepicker-toggle matSuffix></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</form>
You can get access to your date picker via #ViewChild and to listed for global enter event and then once user press enter you can catch this event end call "close()" which will close the panel. So it will be like this in your TS file:
// getting reference to date picker
#ViewChild(MatDatepicker) private rangePicker: MatDatepicker<Date>;
globalEnter = fromEvent<KeyboardEvent>(document, 'keyup')
.pipe(
filter((event) => event.keyCode === ENTER),
tap(console.log)
)
.subscribe(() => this.rangePicker.close())
Of course import all imports (ENTER you can import from '#angular/cdk/keycodes') and also handle unsubscribtion properly etc.

Set initial value to a Toggle of a form in Angular Material within HTML

I am working with a simple form:
HTML
<mat-card>
<form (submit)="onAddBet(betForm)" #betForm="ngForm">
<mat-form-field>
<textarea #description="ngModel" matInput rows="6" placeholder="Description" name="description" ngModel
required></textarea>
<mat-error *ngIf="description.invalid">Please enter a Bet Description</mat-error>
</mat-form-field>
<mat-slide-toggle #privacy="ngModel" name="privacy" ngModel>Private</mat-slide-toggle>
<mat-slide-toggle #comments="ngModel" name="comments" ngModel>Allow comments</mat-slide-toggle>
<button mat-raised-button color="primary" type="submit">
CREATE
</button>
</form>
</mat-card>
If I press submit without touching any field of the form I get all the fields empty as it should be expected but I would like to get instead of the status of the form, meaning all the fields as "" but in the fields "privacy" and "comments" as false (boolean) (the default appearance of the toggles is as not marked).
I know that this could be easily done by Typescript from the component following the method:
Typescript
onAddBet(form: NgForm) {
if (!form.value.privacy) {
form.value.privacy = false;
console.log(form.value);
} else console.log(form.value);
if (form.invalid) return;
form.resetForm();
}
But I was wondering if there is any HTML attribute to run the same code avoiding to use Typescript
How could I do it?
You can initialize your ngModel in your HTML by using ngModel with a one-way binding
<mat-slide-toggle #privacy="ngModel" name="privacy" [ngModel]="false">Private</mat-slide-toggle>
<mat-slide-toggle #comments="ngModel" name="comments" [ngModel]="false">Allow comments</mat-slide-toggle>
Then in your component
onAddBet(form: NgForm) {
console.log(form.value);
if (form.invalid) return;
form.resetForm();
}
As per the documentation of slide-toggle you can use [checked]="checked" in HTML.

How to clear input field after submitting data in angular?

I have one mat-select dropdown and one input field. When the button is clicked it submits data. After data is submitted I want to clear the input field but I don't want to clear the mat-select dropdown. How can I do that?
chat.component.html
<div>
<mat-form-field>
<mat-select placeholder="Select User" [(ngModel)]="userObject.userid"
name="userid" required>
<mat-option *ngFor="let userObj of userObj [value]="userObj.userid">
{{userObj.username}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Type Message" [(ngModel)]="userObject.chatmessage">
</mat-form-field>
<button mat-raised-button color="primary" (click)="sendMessage()">
SEND MESSAGE</button>
</div>
Since you're two-way data binding to userObject.chatmessage, just setting it to an empty string in your component will do the trick.
In your ChatComponent TypeScript class, just do this:
sendMessage() {
// After Sending Message
userObject.chatmessage = '';
}
I think you should use Reactive forms and call reset()-method on the form.
You can also manually reset the form fields as suggested above by SiddAjmera.
I think the Reactive form is the best way to do it, https://angular.io/guide/reactive-forms use this link to do it
reset the input field by assigning the empty string is not the way to do that, it will going to give error in some condition
I think the way to do this while using Reactive form protocols is upon your button click is to .setValue('').
So instead your send message would look like this.
sendMessage() {
// Operations here prior to resetting value...
this.userObjectField.setValue('');
}