609tom
609tom

Reputation: 299

How to add a clear button in `mat-datepicker`

How to add a clear button in mat-datepicker. Exactly in the open calendar how to add a date cleaning button.

<input matInput [(ngModel)]="data1" [matDatepicker]="data1" [value]="" formControlName="data1" id="data1" name="data1">
<mat-datepicker-toggle matSuffix [for]="data1"></mat-datepicker-toggle>
<mat-datepicker #data1></mat-datepicker>

I put inside the attribute:

<input matInput [(ngModel)]="data1" [matDatepicker]="data1" [value]="" formControlName="data1" id="data1" name="data1">
<mat-datepicker-toggle matSuffix [for]="data1"></mat-datepicker-toggle>
<mat-datepicker #data1>
    <button (click)="onClickMe()">
        <mat-icon matDatepickerToggleIcon>clear</mat-icon>
    </button>
</mat-datepicker>

but it doesn't work.

I would ask for help. Thank you.

Upvotes: 21

Views: 24753

Answers (2)

Ed Momot
Ed Momot

Reputation: 371

This solution uses the existing functionality of mat-datepicker-toggle without tying it to the datePicker using the for binding, which makes it do nothing instead of toggling the visibility of the calendar.

Adding a click binding allows arbitrary code to execute, in this case, calling the clear function in the component's JS/TS.

The icon on mat-datepicker-toggle can be customized by adding a child mat-icon component with a matDatepickerToggleIcon directive. This replaces the calendar icon with an arbitrary icon, in this case, the clear icon. source

By default, the icons are stacked vertically. This is fixed by making mat-datepicker-toggle display as inline-block with CSS.

Screenshot of the control

HTML

<mat-form-field appearance="fill">
    <mat-label>Start date</mat-label>
    <input matInput [matDatepicker]="startDatePicker" [(ngModel)]="startDate">
    <mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle>
    <mat-datepicker-toggle matSuffix (click)="clearStartDate()">
        <mat-icon matDatepickerToggleIcon>clear</mat-icon>
    </mat-datepicker-toggle>
    <mat-datepicker #startDatePicker></mat-datepicker>
</mat-form-field>

Component.ts

startDate: Date;

clearStartDate() {
    this.startDate = null;
}

CSS

mat-datepicker-toggle {
    display: inline-block;
}

Upvotes: 37

nash11
nash11

Reputation: 8680

The mat-datepicker does not have an option to add a clear icon to the input by default. But we can get this in our datepicker by playing around with the css of the mat-icon button and the input. We need to place our mat-icon after the input in our HTML.

I would also suggest against using ngModel and formControlName on the same element. Use one or the other. You are also using data1 as your ngModel when you have a template variable with the same name. Just change the ngModel to another unique variable.

We now have the clear icon in our mat-datepicker, but there's another problem, when you click the clear icon, the datepicker input comes into focus. To prevent the click event from bubbling up the DOM tree, we need to use event.stopPropagation()

Change your HTML like below

<mat-form-field>
    <input class="mat-datepicker-input" matInput [(ngModel)]="date" [matDatepicker]="data1" id="data1" name="data1">
    <mat-icon matDatepickerToggleIcon (click)="clearDate($event)">clear</mat-icon>
    <mat-datepicker-toggle matSuffix [for]="data1"></mat-datepicker-toggle>
    <mat-datepicker #data1></mat-datepicker>
</mat-form-field>

In your css

.mat-datepicker-input {
    width: 85%;
}

mat-icon {
    position: relative;
    float: right;
    top: -3px;
    cursor: pointer;
    color: rgba(0, 0, 0, 0.54);
}

In your component

clearDate(event) {
    event.stopPropagation();
    this.date = null;
}

Here is a working example on StackBlitz.

Upvotes: 1

Related Questions