input onfocus event not detecting html element when reference them by # - html

Todo :
I want to open a date picker "#picker" when its input has focus but it's not working when using onfocus input event and gives an error:
error : 'picker is not defined'
<mat-form-field style="width: 100%;">
<input matInput [matDatepicker]="picker" onfocus="picker.open()"
placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker">
</mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
but when I did it by a button press it worked
<button mat-button (click)="picker.open()">show date picker</button>
how can I do this by focusing on an input

You should use Angular event binding:
<input ... (focus)="picker.open()" >
See this stackblitz for a demo.

Related

Angular Material Hide Password toggles on enter

I'm new to angular and i have a project that already has a login with a username and password input. The password input has a button to show the password. The problem is, that when im in the password input field and i press enter, it toggles the button to show the password instead of submitting the form. How can i change that?
component.html
<div style="text-align: center" class="centered">
<form [formGroup]="form">
<br>
<mat-form-field appearance="fill">
<mat-label>Username</mat-label>
<input name="username" formControlName="username" matInput>
</mat-form-field>
<br>
<mat-form-field appearance="fill">
<mat-label>Password</mat-label>
<input name="password" formControlName="password" matInput [type]="passwordVisible ? 'text' : 'password'">
<button mat-icon-button matSuffix (click)="passwordVisible = !passwordVisible" [attr.aria-label]="'Hide password'"
[attr.aria-pressed]="!passwordVisible">
<mat-icon>{{passwordVisible ? 'visibility' : 'visibility_off'}}</mat-icon>
</button>
</mat-form-field>
<br>
<button (click)="login()" mat-raised-button>Login</button>
<button (click)="navigateToRegister()" mat-raised-button color="primary" style="margin-left: 10px">Register</button>
</form>
</div>
Default type for the button is submit that might be causing this issue try changing your show/hide button type to button something like
<button type="button" mat-icon-button matSuffix (click)="passwordVisible = !passwordVisible" [attr.aria-label]="'Hide password'"
[attr.aria-pressed]="!passwordVisible">
<mat-icon>{{passwordVisible ? 'visibility' : 'visibility_off'}}</mat-icon>
</button>
I also stumbled upon this issue recently and was able to resolve it using the approach below.
Method onClickRevealPassword will be called if you press enter on the password input field. Such action results in an event called pointerType which you can detect with this method and keep the password field not to reveal the plain password value. Have a look and experiment it with your component.
<mat-form-field appearance="fill">
<mat-label>Password</mat-label>
<input name="password" formControlName="password" matInput [type]="passwordVisible ? 'text' : 'password'">
<button mat-icon-button matSuffix (click)="passwordVisible = !passwordVisible; onClickRevealPassword($event)" [attr.aria-label]="'Hide password'"
[attr.aria-pressed]="!passwordVisible">
<mat-icon>{{passwordVisible ? 'visibility' : 'visibility_off'}}</mat-icon>
</button>
</mat-form-field>
onClickRevealPassword(event) {
event.preventDefault();
// Prevent revealing the password when enter button is pressed.
if (event?.pointerType) {
this.passwordVisible = !this.passwordVisible;
}
}

Reset a mat-date-range-input

I am trying to reset the content of a mat-date-range-input, but cannot find how
The input itself looks like this :
<mat-form-field appearance="fill" class="calendar-form-field">
<mat-label>Date</mat-label>
<mat-date-range-input [rangePicker]="datePicker" disabled >
<input matStartDate #dateStart placeholder="Start">
<input matEndDate #dateEnd placeholder="End" (dateChange)="dateChange(dateStart.value, dateEnd.value)">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
<mat-date-range-picker #datePicker [calendarHeaderComponent]="calendarHeader" disabled="false">
<mat-datepicker-actions>
<button mat-button matDatepickerCancel>Cancel</button>
<button mat-raised-button matDatepickerApply>Ok</button>
</mat-datepicker-actions>
</mat-date-range-picker>
</mat-form-field>
I would like to be able to reset it with a button, which would trigger a function (which also reset multiple other fields, and some data, omitted in this question. As such, the reset has to be on the Typescript side).
I already tried multiples solution (ViewChild, bindings, etc.) found here and there (Stackoverflow as well as dozen of blogs found via google), but none of those solutions worked. I'm still new to Angular, so it may be just me who badly implemented those solutions, so if you think one of the solutions I tried is the good one, do not hesitate to post it.
You can use the formgroup to make thing work and if you want to reset, just set the value for start, end to null or whatever you want to make it default;
HTML PART:
<mat-form-field appearance="fill">
<mat-label>Enter a date range</mat-label>
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
<input matStartDate formControlName="start" placeholder="Start date">
<input matEndDate formControlName="end" placeholder="End date">
</mat-date-range-input>
<mat-hint>MM/DD/YYYY – MM/DD/YYYY</mat-hint>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
<mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error>
<mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error>
</mat-form-field>
<input type="button" value="reset" (click)="resetRange()" >
<p>Selected range: {{range.value | json}}</p>
TS Part:
range = new FormGroup({
start: new FormControl<Date | null>(null),
end: new FormControl<Date | null>(null),
});
resetRange() {
this.range.patchValue({
start: null,
end: null,
});
}
Here is Example
<input matStartDate #startDate>
<input matEndDate #endDate>
...
<button mat-button (click)="startDate.value = ''; endDate.value = ''">reset</button>

Can I add mat-icon and mat-label in single line under mat-form-field

I'm trying to add a tooltip icon beside the mat-label of a form field.
Is there a way to do that
<mat-form-field appearance="outline">
<mat-label>Date</mat-label>
<mat-icon class="help" svgIcon="faQuestionCircle" [matTooltip]="Date"></mat-icon>
<input matInput formControlName="date" [matDatepicker]="picker" (dateInput)="setDate($event.value)"
[min]="todayDate" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
If I try to add an icon inside the label then the tooltip is not getting displayed.
Date ?

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.

Confused about DataBinding DatePicker in Angular 9

I am trying bind data from a datepicker to a variable such that it can be readily used in Typescript. Any ideas on this problem would be much appreciated
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker #picker></mat-datepicker>
Select Date
MatDatePicker's contents need to be enclosed in a <mat-form-field>. See the following example from the Angular Material documentation.
<mat-form-field>
<mat-label>Choose a date</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
You can use this event dateChange or dateInput on the input tag that you can use in your ts file :
<input matInput [matDatepicker]="picker"
(dateInput)="addEvent( $event)" (dateChange)="addEvent( $event)">