Setting angular material date picker value programmatically - javascript

I am using angular material date picker in one of my component's of angular project. This component has two tabs. Using *ngIf I am showing only one at a time based on what user has clicked.In one tab user selects a date and if navigate away to other tab of same component and comes back to previous one, I need to retain the selected date.
This is what I am doing in HTML side:
<mat-form-field class="dropdownWidth">
<input #dateInput matInput [matDatepickerFilter]="myFilter" [matDatepicker]="picker"
placeholder="Choose a date"
[value]="datePickerDate"
[(ngModel)]="datePickerDate"
(dateChange)="addDateEvent($event)"
[disabled]="selectedOperator.length === 0 && userDateRange.length === 0">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
And in TS file:
addDateEvent(event) {
this.datePickerEvent = event;
this.datePickerDate = new Date(`${event.value['_i'].month + 1}-${event.value['_i'].date}-${event.value['_i'].year}`);
this.formatDate = moment(event.value).format('YYYY-MM-DD');
}
But when I navigate back, date value is not retained. Any suggestions how can I achieve this?
Here is sample stackblitz

It does not work because you are not storing a selected value. So create a variable in typescript:
yourDate: any;
HTML:
<p> YourDate {{ yourDate | date }} </p>
<mat-form-field>
<input matInput [(ngModel)]="yourDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
It is possible to see the whole code at stackblitz

In your example you are not using any bindings. Try to use [(ngModel)], so that it will take and hold the selected value.
Do like this, it will work:
<mat-form-field>
<input matInput [(ngModel)]="date" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Related

mat-autocomplete the option value does not appear correctly in IOS device

When I select the first option in the dropdown, the option is not reflected in the field. When I select the second option then first option value appears and when selects third the second option value appears. Any suggestions as to what the problem is in my code?
This is happening only on iOS devices.Its working fine on Android and Desktop.
emailDomains = AvailableDomains.emailDomains;
export const AvailableDomains = {
emailDomains: [
"hotmail.com",
"gmail.com",
"yahoo.com",
"outlook.com"
]
}
<mat-form-field appearance="outline" class="textbox mat-form-field-invalid">
<span class="iconError icon-alert" aria-hidden="false" aria-label="Error"></span>
<mat-label>Email</mat-label>
<input matInput placeholder="Enter" formControlName="email" type="email" [matAutocomplete]="emailAutoComplete" #email>
<mat-autocomplete #emailAutoComplete="matAutocomplete" panelWidth="auto">
<mat-option *ngFor="let emailDomain of (email.value.endsWith('#') && email.value.split('#').length == 2 ? emailDomains : [])" [value]="email.value + emailDomain">#{{emailDomain}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
I have some auto-complete code that does work on IOS. I compared the two and the difference I see is that I am using (optionSelected) on the mat-autocomplete tag instead of (onSelectionChange) on the mat-option tag. Try it and see.
<mat-form-field appearance="outline" class="textbox mat-form-field-invalid">
<span class="iconError icon-alert" aria-hidden="false" aria-label="Error"></span>
<mat-label>Email</mat-label>
<input matInput placeholder="Enter" formControlName="email" type="email" [matAutocomplete]="emailAutoComplete" #email>
<mat-autocomplete #emailAutoComplete="matAutocomplete" panelWidth="auto" (optionSelected)="updateForm($event,emailDomain)">
<mat-option *ngFor="let emailDomain of (email.value.endsWith('#') && email.value.split('#').length == 2 ? emailDomains : [])" [value]="email.value + emailDomain">#{{emailDomain}}
</mat-option>
</mat-autocomplete>
</mat-form-field>

show component error in mat-from-field angular 9

i want to create a share component for show error in angular material .
this is my share component pfa-share-error:
<mat-error *ngIf="fieldErrors(fieldName).required && fieldErrors(fieldName)">
Reqierd
</mat-error>
<mat-error *ngIf="fieldErrors(fieldName).touched && fieldErrors(fieldName)">
Reqierd
</mat-error>
<mat-error *ngIf="fieldErrors(fieldName).pattern && fieldErrors(fieldName)">
Reqierd
</mat-error>
and i using this in the my form :
<mat-form-field appearance="outline">
<mat-label>{{ "COUNTEY.NAME" | translate }}</mat-label>
<input formControlName="name" matInput />
<pfa-share-error [form]="addCountryFG" field="name"></pfa-share-error>
</mat-form-field>
but it show like this in my form when error occure :
i want show that like this :
now how can i solve this problem ????
You may try something like following:
In your main HTML file:
<mat-form-field appearance="outline">
<mat-label>{{ "COUNTEY.NAME" | translate }}</mat-label>
<input formControlName="name" matInput />
<mat-error>
<pfa-share-error [form]="addCountryFG" field="name"></pfa-share-error>
</mat-error>
</mat-form-field>
In your shared component pfa-share-error:
<ng-container *ngIf="fieldErrors(fieldName).required && fieldErrors(fieldName)">
This field is required and cannot be empty
</ng-container>

How to disable Values before Today in Mat-Date Picker

I have two Mat-Date Picker which I use to schedule work.
I want to apply a couple of custom validations such as User should not be able to select start date less than today's date and Start Date should be less than End Date.
I am having an issue in figuring out how to dynamically set start day less than the Current Date every day.
For eg: As on 30/03/2020 all dates before should be disabled. As on
31/032020 even today's date should be disabled.
My HTML Code:
<mat-form-field>
<mat-label>Start Date</mat-label>
<input
matInput
[matDatepicker]="picker"
formControlName="startDate"
readonly
/>
<mat-datepicker-toggle
matSuffix
[for]="picker"
></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Typescript Code:
this.Dategroup= new FormGroup({
startDate: new FormControl('', [Validators.required]),
endDate: new FormControl('', [Validators.required])
});
You just need to add min property to disable previous dates from today.
Example: In html
<mat-form-field>
<mat-label>Start Date</mat-label>
<input matInput [matDatepicker]="picker" [min]="minDate" formControlName="startDate" readonly />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
In your ts file:
Add minDate: Date;
constructor(){
this.minDate = new Date();
}

Angular 2 way number binding converting to string from input

Any time I enter a number into an input that is 2 way bound to my object the value is converted to a string.
How can I force it or convert it to be a number?
It seems like it should be very simple and yet I have struggled to find an elegant solution.
I saw this solution of using a function to convert it but I don't see how that would work for 2 way data binding.
convert string to number angular 2 one way binding
<div class="row">
<mat-form-field class="custom-control">
<input type="number" matInput class="custom-control" [(ngModel)]="mpv.baseFare" required placeholder="Base Fare">
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="custom-control">
<input type="number" matInput class="custom-control" [(ngModel)]="mpv.mileageRate" required placeholder="Mileage Rate">
</mat-form-field>
</div>
mpv is an object of class VehicleType I have my VehicleType class set up as follows. The number types are completely ignored, I guess because it is at run time so just non typed javascript.
export class VehicleType {
baseFare: number;
mileageRate: number;
}
UPDATE - CURRENT HACKY SOLUTION:
onSave(vehicleType: VehicleType) {
// Hack to convert string to number
vehicleType.bags = +vehicleType.bags;
vehicleType.baseFare = +vehicleType.baseFare;
vehicleType.mileageRate = +vehicleType.mileageRate;
vehicleType.passengers = +vehicleType.passengers;
this.vehicleTypeService.updateVehicleType(vehicleType.id, vehicleType).subscribe(result => {
It turns out that the order of the attributes on a matInput mater. This issue does not occur on a standard input only a matInput.
Does not work:
<input type="number" matInput class="custom-control" [(ngModel)]="mpv.baseFare" required placeholder="Base Fare">
Works:
<input matInput type="number" class="custom-control" [(ngModel)]="mpv.baseFare" required placeholder="Base Fare">
If you want to be able to modify the value when ngModel sets a new value then you're most likely looking at creating a get and set function. Example,
<div class="row">
<mat-form-field class="custom-control">
<input type="number" matInput class="custom-control" [(ngModel)]="baseFare" required placeholder="Base Fare">
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="custom-control">
<input type="number" matInput class="custom-control" [(ngModel)]="mileageRate" required placeholder="Mileage Rate">
</mat-form-field>
</div>
get baseFare(): number {
return mpv.baseFare;
}
set baseFare(value: any) {
mpv.baseFare = pareseInt(value, 10);
}
get mileageRate(): number {
return mpv.mileageRate;
}
set mileageRate(value: any) {
mpv.mileageRate = pareseInt(value, 10);
}
That should do the job.
Update: you could just have value as any or both as any since you know the return type will be a number.

Quarterly date picker

I am looking for a quarterly date picker, preferably using Angular, like something shown below:
Both Bootstrap and (Angular) Material dont seem to offer this functionality.
Is there any other existing frameworks/libraries that could offer this?
Why not use, e.g. an autocomplete in material, some like
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<button mat-icon-button (click)="change(-1)"><</button>{{year}}<button mat-icon-button (click)="change(1)">></button>
<mat-option *ngFor="let option of options;let i=index" [value]="option.value">
{{option.value}}<span *ngFor="let month of option.months">{{month}}</span>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
options: any[] = [
{value:1,months:['Ene','Feb','Mar']},
{value:2,months:['Apr','May','Jun']},
{value:3,months:['Jul','Ago','Sep']},
{value:4,months:['Oct','Nov','Dec']}
];
year=new Date().getFullYear()
change(inc)
{
this.year+=inc
}
see a fool example in stackblitz

Categories