[Angular] Disable changing value of kendo elements using arrow up/down keys on numeric textbox and datetime input

0 Answers 123 Views
DateTimePicker NumericTextBox
Waseem
Top achievements
Rank 1
Waseem asked on 19 Nov 2024, 02:08 PM

Hello,

I am trying to implement a directive to prevent changing the values on the client side when an input is disabled. It works perfectly on a native HTML element, but not completely when used on a Kendo UI element such as datetime picker or numeric textbox. 


  @HostListener('keydown', ['$event'])
  onKeydown(event: KeyboardEvent): void {
    if (this.appCustomDisabled) {
      // Prevent arrow keys (Up/Down) from changing the value
      if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
        event.preventDefault();
        event.stopImmediatePropagation();
      }

      // Prevent any other key presses or changes
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  }

  @HostListener('input', ['$event'])
  onInput(event: Event): void {
    if (this.appCustomDisabled) {
      event.preventDefault();  // Prevent any changes to the input
      event.stopImmediatePropagation();
    }
  }

  @HostListener('wheel', ['$event'])
  onWheel(event: WheelEvent): void {
    if (this.appCustomDisabled) {
      event.preventDefault();  // Prevent the mouse wheel action
      event.stopImmediatePropagation();
    }
  }

mouse wheel and key inputs are successfully prevented, but arrow up/down keys are still changing the value. How do I prevent them from changing the value? 

My main goal is to prevent the user as much as possible from modifying the value of a disabled input because the disabled=true approach can be easily bypassed from the devtools.

Georgi
Telerik team
commented on 22 Nov 2024, 10:04 AM

Hi Waseem,

Thank you very much for the code snippet provided.

From what I understood from your question, you are currently utilizing both the Kendo UI for NumericTextBox and Kendo UI for Angular DateTimePicker and are looking for an approach to prevent the default behavior of the two components when the user presses the Up and Down arrow keys. Please, let me know if I misinterpreted the requirement.

One possible approach that would allow the developer to prevent the default behavior of the NumericTextBox upon pressing the Up and Down arrows would be to attach the generic keydown event to the internal <input> element of the component and prevent it using the stopImmediatePropagation() method:

ngAfterViewInit() {
    document.querySelector('kendo-numerictextbox input').addEventListener(
      'keydown',
      (e: KeyboardEvent) => {
        if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
          e.stopImmediatePropagation();
        }
      },
      true
    );
}

A similar approach could be followed for the DateTimePicker component as well:

ngAfterViewInit() {
    document.querySelector('kendo-datetimepicker input').addEventListener(
      'keydown',
      (e: KeyboardEvent) => {
        if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
          e.stopImmediatePropagation();
        }
      },
      true
    );
}

To better illustrate the suggested approach, I am sending you two StackBlitz demos that implement it:

I hope the provided information helps. Please, let me know if I am missing out on something.

Regards,
Georgi
Progress Telerik
Waseem
Top achievements
Rank 1
commented on 27 Nov 2024, 08:40 AM

Thank you for the solution, it works.

But I got another issue now. I'm failing to disable a kendo-dropdownlist using a the directive. Is there a solution for it? 

Georgi
Telerik team
commented on 29 Nov 2024, 10:44 AM

Hi Waseem,

Thank you very much for the clarifications provided.

I am happy to hear that my previous suggestion helped you achieve the desired behavior for the NumericTextBox and DateTimePicker components.

When it comes to disabling the keyboard navigation of the Kendo UI for Angular DropDownList component in a custom directive, what I would suggest would be for the developer to attach the generic keydown event to the host component and programmatically disable the default behavior using the stopImmediatePropagation() method:

ngOnInit(): void {
    this.listener = (event: KeyboardEvent) => {
      if (this.appDisableShortcut.includes(event.key)) {
        event.stopImmediatePropagation();
      }
    };

    this.el.wrapper.nativeElement.addEventListener(
      'keydown',
      this.listener,
      true
    );
}

ngOnDestroy(): void {
    if (this.listener) {
      this.el.wrapper.nativeElement.removeEventListener(
        'keydown',
        this.listener,
        true
      );
    }
}

To better illustrate the suggested approach, I am sending you a StackBlitz demo that implements it:

I hope this helps. Please, let me know if I can further assist you with this case.

Regards,
Georgi
Progress Telerik

 

Waseem
Top achievements
Rank 1
commented on 02 Dec 2024, 08:49 AM

Thank you so much for the suggested solution. But I have to apologize for maybe I did not clarify my question correctly.

My intention was to disable a kendo dropdownlist completely. Rendering it as disabled using a directive. I am failing to achieve that as well with any other kendo component that does not include a native HTML input inside it. It looks like once the kendo dropdownlist has been initialized, its disabled attribute cannot be changed. But I might be mistaken, because setting a condition inside its [disabled] attribute will trigger it on or off accordingly.

Georgi
Telerik team
commented on 03 Dec 2024, 10:18 AM

Hi Waseem,

Thank you very much for the clarifications provided.

If I correctly interpreted the query, you are currently trying to fully disable the Kendo UI for Angular DropDownList component but are experiencing some issues with setting its disabled property using the custom directive applied to the component. Please, let me know if I misinterpreted the requirement.

Based on the information provided in the thread, I tried setting the disabled property of the DropDownList from a custom directive, and from what I have noticed, the component is indeed disabled using such an approach.

To better illustrate the behavior of the DropDownList on my side, here is the StackBlitz demo where I performed the testing:

Since I want to avoid misunderstandings and provide maximum utility out of the support service, I would ask you to provide more detailed information about the specifics of the implementation or, ideally, a small runnable example demonstrating the unexpected behavior of the component when using a similar approach for disabling it. This would allow me to gain a better understanding of the exact scenario and thus come up with a more suitable suggestion.

I am looking forward to your reply.

Regards,
Georgi
Progress Telerik

 

No answers yet. Maybe you can help?

Tags
DateTimePicker NumericTextBox
Asked by
Waseem
Top achievements
Rank 1
Share this question
or