In my text area im using onKeydown event to listen to characters typed by user. I need to prevent Alt gr + key combination values (ē, r̥, ṭ,...) to avoid accented keys in my text area.
if (event.code === 'AltRight') {
console.log('Prevent Accent letters');
event.preventDefault();
}
(or)
if (event.code === 17 || event.code === 18) {
console.log('Prevent Accent letters');
event.preventDefault();
}
Nothing worked. They are entering these if condition but still the accent text is getting printed in my textarea. How can this be prevented
We need to create a custom directive which works with the regex /[\\x00-\\x7F]*/i
to negate all the alt code characters, and only filters out the valid ones, we can use match
to do this!
Article used for deriving this answer
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { PermitDirective } from './app/input.directive';
@Component({
selector: 'app-root',
imports: [PermitDirective],
standalone: true,
template: `
<textarea (input)="onInputChange($event)"></textarea>
`,
})
export class App {
name = 'Angular';
onInputChange(event: any) {
event.target.value = event.target.value.match(/[\\x00-\\x7F]*/i).toString();
}
}
bootstrapApplication(App);
directive
import { Directive, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appPermit]',
standalone: true,
})
export class PermitDirective {
@Input('regex') pattern: RegExp = /[\\x00-\\x7F]*/i;
constructor() {}
@HostListener('input', ['$event']) onInput(e: any) {
e.target.value = this.isValidText(e, '');
}
@HostListener('paste', ['$event'])
onPaste(event: any) {
return this.isValidText(event, event.clipboardData.getData('text/plain'));
}
isValidText(e: any, text: any) {
debugger;
const [selectionStart, selectionEnd] = this.getSelectionRange(e.target);
// for elements not having value accessor(innerText)
const existingValue = e.target.value ?? e.target.innerText;
console.log(
e.target.value,
'typed',
existingValue.substring(0, selectionStart) +
text +
existingValue.substring(selectionEnd)
);
return (
existingValue.substring(0, selectionStart) +
text +
existingValue.substring(selectionEnd)
)
.match(this.pattern)
.toString();
}
getSelectionRange(el: HTMLElement) {
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
// These properties aren't present for any HTMLElement
return [el.selectionStart, el.selectionEnd];
}
// currently getSelection() doesn't work on the content of <textarea> and // <input> elements in Firefox, Edge (Legacy)
const { startOffset, endOffset } = <any>getSelection()?.getRangeAt(0);
return [startOffset, endOffset];
}
}
main.ts
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { PermitDirective } from './app/input.directive';
@Component({
selector: 'app-root',
imports: [PermitDirective],
standalone: true,
template: `
<textarea appPermit></textarea>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App);