IDEMPIERE-4864 Fix shortcut handling for combobox and ad window (#765)

* IDEMPIERE-4864 Fix shortcut handling for combobox and ad window

* IDEMPIERE-4864 Fix shortcut handling for combobox and ad window

- fix combobox keyboard navigation
- improve focus handling with mask
This commit is contained in:
hengsin 2021-07-06 16:40:07 +08:00 committed by GitHub
parent 72ba9fd9d3
commit 7b55139ffa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 42 deletions

View File

@ -48,7 +48,7 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
<javascript-module name="jawwa.atmosphere" version="202102091500"/>
<javascript-module name="adempiere.local.storage" version="202011151100"/>
<javascript-moudle name="html2canvas" version="1.0.0.rc7"/>
<javascript-module name="org.idempiere.commons" version="202105201416"/>
<javascript-module name="org.idempiere.commons" version="202107060204"/>
<javascript-module name="jquery.maskedinput" version="1.4.1" />
<javascript-module name="photobooth" version="0.7-rsd3" />
<javascript-module name="chosenbox" version="202012041500"/>

View File

@ -304,6 +304,12 @@ public final class LayoutUtils {
protected static void showWindowWithMask(Window window, ISupportMask mask){
mask.showMask();
mask.getMaskComponent().appendChild(window);
StringBuilder script = new StringBuilder("var w=zk.Widget.$('#");
script.append(mask.getMaskComponent().getUuid()).append("');");
script.append("var d=zk.Widget.$('#").append(window.getUuid()).append("');w.busy=d;");
Clients.response(new AuScript(script.toString()));
LayoutUtils.openOverlappedWindow(mask.getMaskComponent(), window, "middle_center");
}

View File

@ -723,6 +723,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
}
private void onCtrlKeyEvent(KeyEvent keyEvent) {
if (windowContent != null && windowContent.isBlock())
return;
ToolBarButton btn = null;
if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
{

View File

@ -25,6 +25,7 @@ import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -3312,6 +3313,27 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
Clients.response(new AuScript(script.toString()));
}
/**
*
* @return true if window is block by mask or highlighted window
*/
public boolean isBlock() {
if (mask != null && mask.getParent() != null) {
return true;
}
if (getComponent() != null && getComponent().getPage() != null) {
Collection<Component> roots = getComponent().getPage().getRoots();
for(Component comp : roots) {
if (comp instanceof org.zkoss.zul.Window) {
org.zkoss.zul.Window wnd = (org.zkoss.zul.Window) comp;
if (wnd.isVisible() && wnd.inHighlighted())
return true;
}
}
}
return false;
}
public void executeButtonProcess(final IProcessButton wButton,
final boolean startWOasking, final int table_ID, final int record_ID,
boolean isProcessMandatory) {

View File

@ -329,6 +329,9 @@ public class BreadCrumb extends Div implements EventListener<Event> {
if (windowContent != null && windowContent.getOpenQuickFormTabs().size() > 0)
return;
if (windowContent != null && windowContent.isBlock())
return;
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.isAltKey()) {
if (keyEvent.getKeyCode() == KeyEvent.LEFT) {

View File

@ -20,9 +20,11 @@ package org.adempiere.webui.component;
import java.util.List;
import org.adempiere.webui.AdempiereIdGenerator;
import org.adempiere.webui.LayoutUtils;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.IdSpace;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Comboitem;
@ -37,11 +39,24 @@ public class Combobox extends org.zkoss.zul.Combobox implements IdSpace
public Combobox() {
super();
override();
init();
}
public Combobox(String value) throws WrongValueException {
super(value);
override();
init();
}
private void init() {
this.setCtrlKeys("^#down");
this.addEventListener(Events.ON_CTRL_KEY, e -> {
if (this.isEnabled() && LayoutUtils.isReallyVisible(this)) {
if (!isOpen())
this.setOpen(true);
e.stopPropagation();
}
});
}
private void override() {
@ -172,4 +187,12 @@ public class Combobox extends org.zkoss.zul.Combobox implements IdSpace
AuScript response = new AuScript(script);
Clients.response(response);
}
/**
* add widget listener to auto scroll selected item to view (i.e make visible)
*/
public void addScrollSelectedIntoViewListener() {
String script = "var id='#'+this.uuid+'-pp .z-comboitem-selected';var selected=zk($(id));if(selected.jq.length==1)selected.scrollIntoView();";
setWidgetListener("onKeyUp", script);
}
}

View File

@ -30,6 +30,7 @@ import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zhtml.Text;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
@ -201,6 +202,11 @@ public class ProcessInfoDialog extends Window implements EventListener<Event> {
}
}
@Override
public void focus() {
btnOk.focus();
}
/**
* after run a process, call this function to show result in a dialog
* @param pi
@ -211,12 +217,13 @@ public class ProcessInfoDialog extends Window implements EventListener<Event> {
*/
public static void showProcessInfo (ProcessInfo pi, int windowNo, final Component comp, boolean needFillLogFromDb) {
ProcessInfoDialog dialog = new ProcessInfoDialog(AEnv.getDialogHeader(Env.getCtx(), windowNo),AEnv.getDialogHeader(Env.getCtx(), windowNo), pi, needFillLogFromDb);
final ISupportMask supportMask = LayoutUtils.showWindowWithMask(dialog, comp, LayoutUtils.OVERLAP_PARENT);;
final ISupportMask supportMask = LayoutUtils.showWindowWithMask(dialog, comp, LayoutUtils.OVERLAP_PARENT);
dialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
supportMask.hideMask();
}
});
});
Executions.schedule(comp.getDesktop(), e -> dialog.btnOk.focus(), new Event("onPostShowProcessInfoDialog"));
}
}

View File

@ -71,9 +71,7 @@ import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.sys.SessionCtrl;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.DesktopCleanup;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Menuitem;
@ -199,12 +197,13 @@ ContextMenuListener, IZoomableEditor
{
ZKUpdateUtil.setWidth(getComponent(), "200px");
getComponent().setAutocomplete(true);
getComponent().setAutodrop(true);
getComponent().setAutodrop(false);
getComponent().setInstantSelect(false);
getComponent().addEventListener(Events.ON_BLUR, this);
if (getComponent() instanceof EditorAutoComplete) {
;
} else {
getComponent().addEventListener(Events.ON_CHANGING, this);
getComponent().addScrollSelectedIntoViewListener();
}
boolean zoom= false;
@ -428,7 +427,7 @@ ContextMenuListener, IZoomableEditor
if (obj instanceof KeyNamePair)
{
KeyNamePair lookupKNPair = (KeyNamePair) obj;
getComponent().appendItem(lookupKNPair.getName(), lookupKNPair.getKey());
getComponent().appendItem(lookupKNPair.getName().length()==0 ? " " : lookupKNPair.getName(), lookupKNPair.getKey());
if (!found && oldValue != null && oldValue instanceof Integer &&
lookupKNPair.getKey() == (Integer)oldValue)
{
@ -438,7 +437,7 @@ ContextMenuListener, IZoomableEditor
else if (obj instanceof ValueNamePair)
{
ValueNamePair lookupKNPair = (ValueNamePair) obj;
getComponent().appendItem(lookupKNPair.getName(), lookupKNPair.getValue());
getComponent().appendItem(lookupKNPair.getName().length()==0 ? " " : lookupKNPair.getName(), lookupKNPair.getValue());
if (!found && oldValue != null && lookupKNPair.getValue().equals(oldValue.toString()))
{
found = true;
@ -447,7 +446,7 @@ ContextMenuListener, IZoomableEditor
else if (obj instanceof MLocator)
{
MLocator lookupKNPair = (MLocator) obj;
getComponent().appendItem(lookupKNPair.getValue(), lookupKNPair.getM_Locator_ID());
getComponent().appendItem(lookupKNPair.getValue().length()==0 ? " " : lookupKNPair.getValue(), lookupKNPair.getM_Locator_ID());
if (!found && oldValue != null && lookupKNPair.getM_Locator_ID() == (Integer) oldValue)
{
found = true;
@ -554,7 +553,7 @@ ContextMenuListener, IZoomableEditor
else
{
//on select not fire for empty label item
if (item.getLabel().equals(""))
if (Util.isEmpty(item.getLabel(),true))
{
Object newValue = getValue();
if (isValueChange(newValue)) {
@ -571,8 +570,6 @@ ContextMenuListener, IZoomableEditor
}
}
}
} else if (event.getName().equals(Events.ON_CHANGING)) {
onChanging((InputEvent) event);
} else if (event.getName().equals("onPostSelect")) {
if (getComponent().isOpen()) {
getComponent().select();
@ -582,24 +579,6 @@ ContextMenuListener, IZoomableEditor
}
}
private void onChanging(InputEvent event) {
String v = event.getValue();
if (!Util.isEmpty(v)) {
v = v.toLowerCase();
int count = getComponent().getItemCount();
for(int i = 0; i < count; i++) {
Comboitem item = getComponent().getItemAtIndex(i);
if(item.getLabel() != null && item.getLabel().toLowerCase().startsWith(v)) {
Clients.scrollIntoView(item);
break;
}
}
} else if (getComponent().getItemCount() > 0) {
Comboitem item = getComponent().getItemAtIndex(0);
Clients.scrollIntoView(item);
}
}
private boolean isValueChange(Object newValue) {
return (oldValue == null && newValue != null) || (oldValue != null && newValue == null)
|| ((oldValue != null && newValue != null) && !oldValue.equals(newValue));
@ -675,7 +654,7 @@ ContextMenuListener, IZoomableEditor
{
if (value instanceof Integer)
Record_ID = ((Integer)value).intValue();
else if (value != null && "".compareTo(value.toString())!= 0)
else if (!Util.isEmpty(value.toString(),true))
Record_ID = Integer.parseInt(value.toString());
}
@ -826,8 +805,7 @@ ContextMenuListener, IZoomableEditor
private WTableDirEditor editor;
private DesktopCleanup listener = null;
protected EditorCombobox() {
protected EditorCombobox() {
}
@Override
@ -885,7 +863,6 @@ ContextMenuListener, IZoomableEditor
private DesktopCleanup listener = null;
protected EditorAutoComplete() {
}
@Override
@ -937,7 +914,7 @@ ContextMenuListener, IZoomableEditor
public void setValue(String value)
{
setText(value);
if (Util.isEmpty(value)) {
if (Util.isEmpty(value,true)) {
refresh("");
}
}

View File

@ -1194,7 +1194,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
{
// 0 = Columns
ArrayList<ValueNamePair> items = new ArrayList<ValueNamePair>();
items.add(new ValueNamePair("", ""));
items.add(new ValueNamePair("", " "));
for (int c = 0; c < m_findFields.length; c++)
{
GridField field = m_findFields[c];
@ -1251,8 +1251,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
}
listColumn.setModel(columnListModel);
if (!isFilterColumnList()) {
String script = "var id='#'+this.uuid+'-pp .z-comboitem-selected';var selected=zk($(id));if(selected.jq.length==1)selected.scrollIntoView();";
listColumn.setWidgetListener("onKeyUp", script);
listColumn.addScrollSelectedIntoViewListener();
}
Events.sendEvent("onInitRender", listColumn, null);
if(fields == null)
@ -1459,7 +1458,8 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (listbox.getId().equals(listColumn.getId()))
{
Comboitem column = listColumn.getSelectedItem();
if (column != null && column.getValue().toString().length() > 0)
ValueNamePair selected = column.getValue();
if (column != null && selected.getValue().length() > 0)
{
addOperators(column, listOperator);
}

View File

@ -17,7 +17,7 @@ zk.override(zk.Widget.prototype, "canActivate",
var wgt = this;
while (wgt) {
if (wgt.busy) {
if (wgt.busy.className == 'zul.wnd.Window') {
if (wgt.busy.className) {
if (zUtl.isAncestor(wgt.busy, this)) {
return true;
} else {
@ -29,7 +29,7 @@ zk.override(zk.Widget.prototype, "canActivate",
jq.focusOut();
}
return false;
}
}
if (wgt.className == 'zul.wnd.Window') {
if (wgt.getMode() == 'overlapped') {
return true;