This is a migrated thread and some comments may be shown as answers.

Drop Down List inside Grid, custom navigation

4 Answers 350 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Ryan
Top achievements
Rank 1
Ryan asked on 03 Aug 2018, 10:54 PM

Hi,

I have specific requirements for keyboard navigation within a grid. I have implemented custom navigation in the grid that works very well for text box inputs.  However, it does not work well when I navigate across cells containing dropdownlists, as the arrow keys change the values in the list as the user navigates away from these cells.

 

I use the following function to capture keydown events within the grid:

 

            // Key-down event handler to provide custom navigation within the grid.
            $("#auto_gen_conn_mngr_grid table").on("keydown", "td", function (e) {
                switch (e.keyCode ? e.keyCode : e.which) {
                    case kendo.keys.UP:
                        e.preventDefault();
                        e.stopPropagation();
                        NavigateVertically(this, navDirection.UP);
                        break;
                    case kendo.keys.ENTER:
                    case kendo.keys.DOWN:
                        e.preventDefault();
                        e.stopPropagation();
                        NavigateVertically(this, navDirection.DOWN);
                        break;
                    case kendo.keys.LEFT:
                        e.preventDefault();
                        e.stopPropagation();
                        NavigateHorizontally(this, navDirection.LEFT);
                        break;
                    case kendo.keys.TAB:
                        e.preventDefault(); // Keep Tab from navigating to elements outside of the grid.
                        e.stopPropagation();
                    case kendo.keys.RIGHT:
                        e.preventDefault();
                        e.stopPropagation();
                        NavigateHorizontally(this, navDirection.RIGHT);
                        break;
                }
            });

 

The problem is, that before this function executes, the dropdown list has already received the 'select' event and modified it's selected item. I can add an event handler to my list's editor template, which uses preventDefault() to cancel the selection. But I can't tell how to differentiate between events that should vs. should not modify the selection.

 

I would like the selection to be modified only when the user uses holds the 'ctrl' key while pressing the navigational key (i.e. arrows, tab, or enter) or uses a mouse click to click the new selection.

 

I can do this in one of two ways, but I am stuck on both:

method 1: intercept the keydown event before it is handled at the dropdownlist.

problem 1: the event has already gone to the dropdownlist before I capture it, using the code above.

 

method 2: add a handler in the list's editor template for the 'select' event, then use e.preventDefault() when the user is pressing a navigational key without holding down the 'ctrl' key.

problem 2: I don't know if it is possible to get the keystroke information from the context of the list editor's onSelect handler.

 

And finally, if there is no way to accomplish either of the above, disabling keyboard navigation within the dropdown list would be an acceptable compromise. This is not the preferred approach, but if it is possible to configure the dropdownlist to only accept mouse clicks in order to change the selection, that would enable the users to navigate the grid with the keyboard without modifying the selections in the dropdown lists.

 

Thanks,

Ryan

4 Answers, 1 is accepted

Sort by
0
Neli
Telerik team
answered on 07 Aug 2018, 12:40 PM
Hello Ryan,

I am afraid that it is not possible to get the pressed key in the select event handler of the DropDownList.
In order to customize the behavior when the arrow keys are pressed, I would suggest you to override the DropDownList keydown function. In the example below the default behavior is prevented only when the 'up' or 'down' key is pressed and at the same time the 'Alt' key is not pressed. Thus, when the user navigates in the Grid with the arrows, the DropDownList selection will not get changed. The user will still be able to open the DropDownList by pressing the 'Alt + keyDown'
var keyDown = kendo.ui.DropDownList.fn._keydown;
    kendo.ui.DropDownList.fn._keydown = function (e) {
            var that = this;
        var key = e.keyCode;
        var keys = kendo.keys;
        var isOpened = that.popup.visible();
       
        if ((key === keys.DOWN || key === keys.UP) && !isOpened && !e.altKey) {
            e.preventDefault();
        } else {
            keyDown.call(that, e);
        }
    }

Here is a Dojo example where you could find such implementation. The approach in ASP.Net MVC projects will be the same.
I hope the provided solution is suitable for your scenario. 

Regards,
Neli
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Ryan
Top achievements
Rank 1
answered on 07 Aug 2018, 05:47 PM

Hello Neli,

Thank you for your response. This looks like exactly what I am looking for.

But can you please help me understand how to adapt this to ASP.Net MVC? Would this be done through the list editor template?

I do not see the keydown event listed in the documentation, so I am not sure how to bind to it:

https://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#events

Thanks again,

Ryan

1
Accepted
Neli
Telerik team
answered on 09 Aug 2018, 09:10 AM
Hello Ryan,

In order to customize the DropDownList default implementation, such as the _keydown function, you need to override it. In this particular case, you need to include the _keydown customized implementation in your scripts. For convenience I have pasted the code here as well:
  var keyDown = kendo.ui.DropDownList.fn._keydown;
kendo.ui.DropDownList.fn._keydown = function (e) {
var that = this;
  var key = e.keyCode;
  var keys = kendo.keys;
  var isOpened = that.popup.visible();       
 
  if ((key === keys.DOWN || key === keys.UP) && !isOpened && !e.altKey) {
     e.preventDefault();
  } else {
     keyDown.call(that, e);
  }
}
 
I also prepared a sample project. In the sample project there is a Grid with InCell editing. There is a custom editor for the 'OrderName' column that you will find in Views->Home->EditorTemplates->ClientShip.cshtml. The script for the DropDownList keydown functionality is included in the 'Index.cshtml' file. You could test the behavior in the sample project by adding and removing the custom _keydown function. 

Regards,
Neli
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Ryan
Top achievements
Rank 1
answered on 10 Aug 2018, 03:47 PM

Hi Neli,

 

This solution works well for me. Thank you for walking me through it. Your sample project was also very useful, because I had a separate issue that was causing exceptions, so it was useful to run your code to show that the exception was unrelated to this solution.

 

Regards,

Ryan

Tags
DropDownList
Asked by
Ryan
Top achievements
Rank 1
Answers by
Neli
Telerik team
Ryan
Top achievements
Rank 1
Share this question
or