Reputation: 1848
I'm trying to add a clear icon on the right side of a dropdown (select component) in Angular material only if the user selects an option. If the user clicks on the "clear" icon I want to delete the value and reset the field. So far I have the dropdown and struggling on displaying the icon properly. Can anyone point me in the right direction? thanks in advance.
Here's my code:
<mat-form-field appearance="fill">
<mat-label>Select a food</mat-label>
<mat-select>
<mat-option *ngFor="let food of foods" [value]="food.value">
{{food.viewValue}}
</mat-option>
<mat-select-trigger>
<button>
<mat-icon>clear</mat-icon>
</button>
</mat-select-trigger>
</mat-select>
</mat-form-field>
Here's LIVE DEMO
Upvotes: 0
Views: 7193
Reputation: 61
You can use this way:
HTML:
<ng-template #clearRef>
@if (value) {
<svg
class="text-danger"
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
(click)="$event.stopPropagation(); control.reset()"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
}
</ng-template>
<ng-template #chevrondownRef>
<svg class="chevron-down" [class.animate]="isPanelOpen" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
</ng-template>
CSS:
.mat-mdc-form-field-type-mat-select {
.mat-mdc-form-field-infix {
--mat-form-field-container-vertical-padding: 0;
.mat-mdc-select-arrow-wrapper {
flex-direction: row-reverse;
gap: 0.5rem;
}
}
}
.chevron-down {
transition: all 0.25s ease;
transform: translate(-50%, -50%) rotate(0deg);
&.animate {
transform: translate(-50%, -50%) rotate(180deg);
}
}
TS:
encapsulation: ViewEncapsulation.None,
private vcr = inject(ViewContainerRef);
@ViewChild(MatSelect) matSelect!: MatSelect;
@ViewChild("clearRef") clearRef!: TemplateRef<HTMLElement>;
@ViewChild("chevrondownRef") chevrondownRef!: TemplateRef<HTMLElement>;
ngAfterViewInit(): void {
//Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
//Add 'implements AfterViewInit' to the class.
const mdcSelectArrowWrapper = document.querySelector(".mat-mdc-select-arrow-wrapper");
const mdcSelectArrow = this.matSelect._elementRef.nativeElement.querySelector(
".mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow",
) as HTMLElement;
mdcSelectArrowWrapper?.appendChild(this.vcr.createEmbeddedView(this.clearRef).rootNodes[0]);
mdcSelectArrow.replaceChildren(this.vcr.createEmbeddedView(this.chevrondownRef).rootNodes[0]);
}
Upvotes: 0
Reputation: 425
THE SOLUTION that worked fir me is given below.... using mat-select In component.ts file
import {Directive, HostListener} from "@angular/core";
@Directive({
selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
@HostListener("click", ["$event"])
public onClick(event: any): void
{
event.stopPropagation();
}
}
In template call the function like this
(click)="onCLick($event)
Upvotes: 0
Reputation: 1843
You need to add ngModel on mat-select for two way binding to add selected value into it. Also add button as suffix of mat-select.
<mat-select [(ngModel)]="selectedFood">
<mat-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</mat-option>
</mat-select>
<button mat-button matSuffix *ngIf="selectedFood" mat-icon-button (click)="onClick($event)">
<mat-icon>close</mat-icon>
</button>
On your component side you need to add following function to clear selected food value.
onClick(event: any) {
this.selectedFood = "";
event.stopPropagation();
}
event.stopPropagation() will stop mat select dropdown to be opened on cick of clean button.
Here is your working solution:
https://stackblitz.com/edit/angular-c7hgum-94nqyq
Upvotes: 8
Reputation: 1780
<mat-form-field appearance="fill">
<mat-label>Select a food</mat-label>
<mat-select [(ngModel)]="selectedFood">
<mat-option *ngFor="let food of foods" [value]="food.value">
{{food.viewValue}}
</mat-option>
</mat-select>
<button mat-button *ngIf="selectedFood" matSuffix mat-icon-button aria-label="Clear" (click)="selectedFood=''">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
Upvotes: 0