1

I have this directive:

This directive should disable typing on input type="number" after reaching max length (that passed as an input).

Because maxlength attribute doesn't work on type="number".

export class AIGMaxLengthDirectiveCO {
    constructor(private elm: ElementRef) { }
    @Input('aigmaxlengthCO') aigmaxlength: number;

    @HostListener('keydown', ['$event'])
    handleKeyboardEvent(e: KeyboardEvent) {
        if (e.keyCode === 8 || e.keyCode === 9 || e.keyCode === 46) {  //  Backspace\tab\delete
            return true;
        } else if (this.isTextSelected(e)) {
            return true;
        } else if ((e.target as HTMLInputElement).value.length >= this.aigmaxlength) {
            e.preventDefault();
            return false;
        }
    }
    isTextSelected(e) {
        if (document.getSelection().toString() !== '') {
            return true;
        }
        const textbox = e.target as HTMLInputElement;
        const startIndex = textbox.selectionStart;
        const endIndex = textbox.selectionEnd;
        return endIndex - startIndex > 0;
    }
}

      <input [aigmaxlengthCO]="9" class="aig-input aig-17 input-text padding-0" type="number" formControlName="id" [ngClass]="form.get('id').invalid && (form.get('id').touched|| validations) ? 'error' : ''"/>

As in the third if block you can see the return false and the preventDefault().

my problem that is on mobile Chrome it just doesn't stop the event, I can see that I enter the third "if" block, and should return false, but it's not working. On the desktop, all works fine

Things I tried:

  • changing keydown to keypress.
  • changing keydown to document:keydown.
Rohit Sharma
  • 3,304
  • 2
  • 19
  • 34

1 Answers1

0

Wouldn't it be a better solution if you implement (change) evento on your input? You could still pass itself for your method and check for its value.

<input [aigmaxlengthCO]="9" (change)="handleKeyboardEvent" class="aig-input aig-17 input-text padding-0" type="number" formControlName="id" [ngClass]="form.get('id').invalid && (form.get('id').touched|| validations) ? 'error' : ''"/>

and your method would be the same:

handleKeyboardEvent(e: KeyboardEvent) {
        if (e.keyCode === 8 || e.keyCode === 9 || e.keyCode === 46) {  //  Backspace\tab\delete
            return true;
        } else if (this.isTextSelected(e)) {
            return true;
        } else if ((e.target as HTMLInputElement).value.length >= this.aigmaxlength) {
            e.preventDefault();
            return false;
        }
    }

The difference is that what I think is happening after some testing and googling is that chrome web browser for mobiles don't work well with keypress and keydown

Source:

The last link offers another solution, but I think passing a directive for (change) would be enough :)

  • thank you for the links, but your solution doesn't work. the change event not being fired (I tried to test it with regular function in regular component). – Daniel Liverant Sep 13 '18 at 14:13