mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	dropdown_list_widget: Improve keyboard focus events.
Previously, our dropdown list widget was lacking several keyUp/keyDown keyboard focus events due to which the user couldn't shift the focus from the dropdown item to it's search input. This commit essentially binds several additional keyboard events by defining a `dropdown_focus_events` function which helps in enhancing our keyboard focus events. Due to the above changes, it removes the custom event binded to dropdown list widget because of which we fallback to our deprecated keydown event handler functions present in /third/bootstrap.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							5c2bafc6b0
						
					
				
				
					commit
					0d20a20b07
				
			@@ -134,6 +134,67 @@ DropdownListWidget.prototype.dropdown_toggle_click_handler = function () {
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DropdownListWidget.prototype.dropdown_focus_events = function () {
 | 
			
		||||
    const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
 | 
			
		||||
    const dropdown_menu = $(`.${CSS.escape(this.widget_name)}_setting .dropdown-menu`);
 | 
			
		||||
 | 
			
		||||
    const dropdown_elements = () => {
 | 
			
		||||
        const dropdown_list_body = $(
 | 
			
		||||
            `#${CSS.escape(this.container_id)} .dropdown-list-body`,
 | 
			
		||||
        ).expectOne();
 | 
			
		||||
 | 
			
		||||
        return dropdown_list_body.children().find("a");
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Rest of the key handlers are supported by our
 | 
			
		||||
    // bootstrap library.
 | 
			
		||||
    dropdown_menu.on("keydown", (e) => {
 | 
			
		||||
        function trigger_element_focus(element) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
            e.stopPropagation();
 | 
			
		||||
            element.trigger("focus");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (e.key) {
 | 
			
		||||
            case "ArrowDown": {
 | 
			
		||||
                switch (e.target) {
 | 
			
		||||
                    case dropdown_elements().last()[0]:
 | 
			
		||||
                        trigger_element_focus(search_input);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case search_input[0]:
 | 
			
		||||
                        trigger_element_focus(dropdown_elements().first());
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "ArrowUp": {
 | 
			
		||||
                switch (e.target) {
 | 
			
		||||
                    case dropdown_elements().first()[0]:
 | 
			
		||||
                        trigger_element_focus(search_input);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case search_input[0]:
 | 
			
		||||
                        trigger_element_focus(dropdown_elements().last());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "Tab": {
 | 
			
		||||
                switch (e.target) {
 | 
			
		||||
                    case search_input[0]:
 | 
			
		||||
                        trigger_element_focus(dropdown_elements().first());
 | 
			
		||||
                        break;
 | 
			
		||||
                    case dropdown_elements().last()[0]:
 | 
			
		||||
                        trigger_element_focus(search_input);
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DropdownListWidget.prototype.setup = function () {
 | 
			
		||||
    // populate the dropdown
 | 
			
		||||
    const dropdown_list_body = $(
 | 
			
		||||
@@ -163,21 +224,7 @@ DropdownListWidget.prototype.setup = function () {
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    search_input.on("keydown", (e) => {
 | 
			
		||||
        const {key, keyCode, which} = e;
 | 
			
		||||
        const navigation_keys = ["ArrowUp", "ArrowDown", "Escape"];
 | 
			
		||||
        if (!navigation_keys.includes(key)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        // We pass keyCode instead of key here because the outdated
 | 
			
		||||
        // bootstrap library we have at static/third/ still uses the
 | 
			
		||||
        // deprecated keyCode & which properties.
 | 
			
		||||
        const custom_event = new $.Event("keydown.dropdown.data-api", {keyCode, which});
 | 
			
		||||
        dropdown_toggle.trigger(custom_event);
 | 
			
		||||
    });
 | 
			
		||||
    this.dropdown_focus_events();
 | 
			
		||||
 | 
			
		||||
    this.render(this.initial_value);
 | 
			
		||||
    this.register_event_handlers();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user