Reputation: 135
By looking at, https://v5.material.angular.io/components/select/overview
There are several keyboard interactions.
I am able to stop the whole interaction, BUT what I want is:
keep the all the keyboard interactions, except the SPACE one
Is there a way to do it?
Thank you.
Upvotes: 5
Views: 9713
Reputation: 1
@Eliseo answer is correct. Unfortunately, in Angular 16, _handleOpenKeydown & _handleClosedKeydown method are marked as private.
My way out to override the function is calling the parent's method. And I can't use event.keyCode because it is deprecated. So I need to use event.key.
ngOnInit(): void {
this.select._handleKeydown = (event:KeyboardEvent)=>{
if (event.key === ' ' ) return
MatSelect.prototype._handleKeydown.call(this.select, event)
}
}
Upvotes: 0
Reputation: 4003
I think this is related and it might be of interest to someone who has an input field in mat-select
and needs to disable the closing of mat-select
when the user presses a space in the input. You just need to prevent default behavior on click and keydown:
<mat-select>
<mat-option
<input
(click)="$event.stopPropagation()"
(keydown)="$event.stopPropagation()">
</input>
</mat-option>
</mat-select>
Upvotes: 10
Reputation: 57999
Take account the Georg-un's answer
But if there a great great reason you always can "re-writte" the function.
Use a template reference variable in your select
<mat-select #select="matSelect">
...
</mat-select>
And you can use ViewChild to get the mat select and rewrite the function
@ViewChild('select', { static: true }) select: any;
ngOnInit() {
this.select._handleKeydown = (event: KeyboardEvent) => {
if (event.keyCode==SPACE)
return
if (!this.select.disabled) {
this.select.panelOpen
? this.select._handleOpenKeydown(event)
: this.select._handleClosedKeydown(event);
}
};
}
NOTE: SPACE is defined in
import { SPACE} from '@angular/cdk/keycodes';
Update we can use a directive also
@Directive({
selector: '[no-space]',
})
export class NoSpaceDirective {
@Output('spacekeydown') spacekeydown: EventEmitter<any> =
new EventEmitter<any>();
constructor(@Self() private select: MatSelect) {
this.select._handleKeydown = (event: KeyboardEvent) => {
if (event.keyCode == SPACE) {
const active=this.select.panelOpen?
this.select.options.filter(x=>x.active)[0]|| null:
null
this.spacekeydown.emit(active?active.value:null);
} else {
if (!this.select.disabled) {
this.select.panelOpen
? (this.select as any)._handleOpenKeydown(event)
: (this.select as any)._handleClosedKeydown(event);
}
}
};
}
}
And you use as
<mat-select no-space
(spacekeydown)="doSomething($event)">
...
</mat-select>
As always, if we use as "selector" instead [no-space]
mat-select
@Directive({
selector: 'mat-select',
})
...
The directive is applied to all ours mat-select
see a stackblitz with the directive
Upvotes: 9
Reputation: 1263
If you look at the source code, you'll find that the keys are hardcoded. Therefore, you cannot easily override them.
Besides that, you probably should not override them anyways sice this would conflict with accessibility.
Upvotes: 1