You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ca...@apache.org on 2020/04/22 17:05:32 UTC
[royale-asjs] branch develop updated: jewel-combobox: add key
handling with arrow keys and enter to close popup. This was
This is an automated email from the ASF dual-hosted git repository.
carlosrovira pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/develop by this push:
new 07c2bea jewel-combobox: add key handling with arrow keys and enter to close popup. This was
07c2bea is described below
commit 07c2beadaed206d56d8221e5cf8184d219afcd7d
Author: Carlos Rovira <ca...@apache.org>
AuthorDate: Wed Apr 22 19:05:28 2020 +0200
jewel-combobox: add key handling with arrow keys and enter to close popup. This was
---
.../jewel/beads/controllers/ComboBoxController.as | 107 ++++++++++++++++-----
.../royale/jewel/beads/views/ComboBoxView.as | 6 +-
.../apache/royale/jewel/beads/views/ListView.as | 2 +-
3 files changed, 89 insertions(+), 26 deletions(-)
diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
index 0a9b95b..919dfd8 100644
--- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
+++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
@@ -24,10 +24,14 @@ package org.apache.royale.jewel.beads.controllers
}
import org.apache.royale.core.IBeadController;
import org.apache.royale.core.IComboBoxModel;
+ import org.apache.royale.core.IItemRendererOwnerView;
import org.apache.royale.core.IStrand;
import org.apache.royale.events.Event;
import org.apache.royale.events.IEventDispatcher;
+ import org.apache.royale.events.KeyboardEvent;
import org.apache.royale.events.MouseEvent;
+ import org.apache.royale.html.beads.IListView;
+ import org.apache.royale.html.supportClasses.StyledDataItemRenderer;
import org.apache.royale.jewel.List;
import org.apache.royale.jewel.beads.controls.combobox.IComboBoxView;
import org.apache.royale.jewel.beads.models.IJewelSelectionModel;
@@ -63,7 +67,6 @@ package org.apache.royale.jewel.beads.controllers
private var model:IComboBoxModel;
private var _strand:IStrand;
-
/**
* @copy org.apache.royale.core.IBead#strand
*
@@ -100,11 +103,11 @@ package org.apache.royale.jewel.beads.controllers
{
IEventDispatcher(viewBead.button).addEventListener(MouseEvent.CLICK, clickHandler);
IEventDispatcher(viewBead.textinput).addEventListener(MouseEvent.CLICK, clickHandler);
+ IEventDispatcher(viewBead.textinput).addEventListener(KeyboardEvent.KEY_DOWN, textInputKeyEventHandler);
COMPILE::JS{
- //keyboard navigation from textfield should also close the popup
- viewBead.textinput.element.addEventListener('blur', handleFocusOut);
+ //keyboard navigation from textfield should also close the popup
+ viewBead.textinput.element.addEventListener('blur', handleFocusOut);
}
-
}
/**
@@ -118,19 +121,18 @@ package org.apache.royale.jewel.beads.controllers
viewBead.popUpVisible = true;
COMPILE::JS {
- //put focus in the textinput
- if (event.target == viewBead.button) {
- viewBead.textinput.element.focus();
- }
+ //put focus in the textinput
+ if (event.target == viewBead.button)
+ viewBead.textinput.element.focus();
}
-
// viewBead.popup is ComboBoxPopUp that fills 100% of browser window-> We want List inside its view
popup = viewBead.popup as ComboBoxPopUp;
popup.addEventListener(MouseEvent.MOUSE_DOWN, removePopUpWhenClickOutside);
list = (popup.view as ComboBoxPopUpView).list;
list.addEventListener(MouseEvent.MOUSE_DOWN, handleControlMouseDown);
+ list.addEventListener(KeyboardEvent.KEY_DOWN, listKeyEventHandler);
list.addEventListener(Event.CHANGE, changeHandler);
if (model is IJewelSelectionModel) {
//don't let the pop-up's list take over as primary dispatcher
@@ -139,6 +141,60 @@ package org.apache.royale.jewel.beads.controllers
}
}
+ /**
+ * key listener at TextInput level
+ * @private
+ */
+ protected function textInputKeyEventHandler(event:KeyboardEvent):void
+ {
+ COMPILE::JS
+ {
+ if (document.activeElement !== viewBead.textinput.element)
+ return;
+ }
+
+ // from this point we don't want to perform this actions if textinput is not active
+
+ if(event.key === KeyboardEvent.KEYCODE__DOWN)
+ {
+ keyPressed = true
+ var view:IListView = list.view as IListView;
+ var dataGroup:IItemRendererOwnerView = view.dataGroup;
+ var goToIndex:int = list.selectedIndex == -1 ? 0 : list.selectedIndex;
+ list.scrollToIndex(goToIndex);
+ var ir:StyledDataItemRenderer = dataGroup.getItemRendererForIndex(goToIndex) as StyledDataItemRenderer;
+ COMPILE::JS
+ {
+ // this 'hack' is needed due to browsers scrolling list on popups when get focus
+ if(list.element.classList.contains("scroll"));
+ {
+ list.element.classList.remove("scroll");
+ setTimeout(restoreScroll, 300);
+ }
+ list.element.focus({preventScroll:true});
+ list.selectedIndex = goToIndex;
+ }
+ }
+ }
+
+ /**
+ * key listener at global List level
+ * @private
+ */
+ protected function listKeyEventHandler(event:KeyboardEvent):void
+ {
+ if(event.key === KeyboardEvent.KEYCODE__ENTER)
+ {
+ dismissPopUp();
+ }
+ }
+
+ COMPILE::JS
+ private function restoreScroll():void
+ {
+ list.element.classList.add("scroll");
+ }
+
private var popup:ComboBoxPopUp;
protected function handleControlMouseDown(event:MouseEvent):void
@@ -146,7 +202,6 @@ package org.apache.royale.jewel.beads.controllers
event.stopImmediatePropagation();
}
-
/**
* @private
*/
@@ -162,7 +217,9 @@ package org.apache.royale.jewel.beads.controllers
}
protected function hidePopup():void{
- viewBead.popUpVisible = false;
+ if(!keyPressed)
+ viewBead.popUpVisible = false;
+ keyPressed = false;
}
/**
* @royaleignorecoercion org.apache.royale.core.UIBase
@@ -170,10 +227,7 @@ package org.apache.royale.jewel.beads.controllers
*/
protected function removePopUpWhenClickOutside(event:MouseEvent = null):void
{
- popup.removeEventListener(MouseEvent.MOUSE_DOWN, removePopUpWhenClickOutside);
- list.removeEventListener(MouseEvent.MOUSE_DOWN, handleControlMouseDown);
- list.removeEventListener(Event.CHANGE, changeHandler);
- viewBead.popUpVisible = false;
+ dismissPopUp();
}
/**
@@ -183,19 +237,28 @@ package org.apache.royale.jewel.beads.controllers
private function changeHandler(event:Event):void
{
event.stopImmediatePropagation();
-
- popup.removeEventListener(MouseEvent.MOUSE_DOWN, removePopUpWhenClickOutside);
- list.removeEventListener(MouseEvent.MOUSE_DOWN, handleControlMouseDown);
- list.removeEventListener(Event.CHANGE, changeHandler);
-
model.selectedItem = IComboBoxModel(list.getBeadByType(IComboBoxModel)).selectedItem;
- viewBead.popUpVisible = false;
-
IEventDispatcher(_strand).dispatchEvent(new Event(Event.CHANGE));
+ dismissPopUp();
}
protected function modelChangeHandler(event:Event):void{
IEventDispatcher(_strand).dispatchEvent(new Event(event.type));
}
+
+ private var keyPressed:Boolean;
+
+ private function dismissPopUp():void
+ {
+ if(!keyPressed)
+ {
+ popup.removeEventListener(MouseEvent.MOUSE_DOWN, removePopUpWhenClickOutside);
+ list.removeEventListener(MouseEvent.MOUSE_DOWN, handleControlMouseDown);
+ list.removeEventListener(Event.CHANGE, changeHandler);
+ list.removeEventListener(KeyboardEvent.KEY_DOWN, listKeyEventHandler);
+ viewBead.popUpVisible = false;
+ }
+ keyPressed = false;
+ }
}
}
diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
index 93861cc..546eeab 100644
--- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
+++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
@@ -129,9 +129,8 @@ package org.apache.royale.jewel.beads.views
}*/
_button = new Button();
- COMPILE::JS {
- _button.element.setAttribute('tabindex', -1);
- }
+ _button.tabIndex = -1;
+
_button.text = '\u25BC';
initSize();
@@ -200,6 +199,7 @@ package org.apache.royale.jewel.beads.views
//popup width needs to be set before position inside bounding client to work ok
_list.width = host.width;
+ _list.scrollToIndex(_list.selectedIndex);
COMPILE::JS
{
diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
index 0703f84..21e34b3 100644
--- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
+++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
@@ -32,6 +32,7 @@ package org.apache.royale.jewel.beads.views
import org.apache.royale.core.IRollOverModel;
import org.apache.royale.core.ISelectableItemRenderer;
import org.apache.royale.core.ISelectionModel;
+ import org.apache.royale.core.StyledUIBase;
import org.apache.royale.events.Event;
import org.apache.royale.events.IEventDispatcher;
import org.apache.royale.events.KeyboardEvent;
@@ -39,7 +40,6 @@ package org.apache.royale.jewel.beads.views
import org.apache.royale.jewel.beads.models.ListPresentationModel;
import org.apache.royale.jewel.supportClasses.list.IListPresentationModel;
import org.apache.royale.utils.getSelectionRenderBead;
- import org.apache.royale.core.StyledUIBase;
/**
* The ListView class creates the visual elements of the org.apache.royale.jewel.List