IDEMPIERE-762 Zk: Grid line editing enhancement.
This commit is contained in:
parent
5e30569fc8
commit
fc083ca2d8
|
@ -114,7 +114,7 @@ import org.zkoss.zul.impl.XulElement;
|
|||
* @author Low Heng Sin
|
||||
*/
|
||||
public class ADTabpanel extends Div implements Evaluatee, EventListener<Event>,
|
||||
DataStatusListener, IADTabpanel, IdSpace
|
||||
DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||
{
|
||||
private static final String ON_SAVE_OPEN_PREFERENCE_EVENT = "onSaveOpenPreference";
|
||||
|
||||
|
@ -923,7 +923,7 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
} else {
|
||||
if (activate) {
|
||||
formContainer.setVisible(activate);
|
||||
setFocusToField();
|
||||
focusToFirstEditor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -938,7 +938,8 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
/**
|
||||
* set focus to first active editor
|
||||
*/
|
||||
private void setFocusToField() {
|
||||
@Override
|
||||
public void focusToFirstEditor() {
|
||||
WEditor toFocus = null;
|
||||
for (WEditor editor : editors) {
|
||||
if (editor.isHasFocus() && editor.isVisible() && editor.getComponent().getParent() != null) {
|
||||
|
@ -954,14 +955,7 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
}
|
||||
}
|
||||
if (toFocus != null) {
|
||||
Component c = toFocus.getComponent();
|
||||
if (c instanceof EditorBox) {
|
||||
c = ((EditorBox)c).getTextbox();
|
||||
} else if (c instanceof NumberBox) {
|
||||
c = ((NumberBox)c).getDecimalbox();
|
||||
}
|
||||
|
||||
Clients.response(new AuFocus(c));
|
||||
focusToEditor(toFocus);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1302,7 +1296,7 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
@Override
|
||||
public void focus() {
|
||||
if (formContainer.isVisible())
|
||||
this.setFocusToField();
|
||||
this.focusToFirstEditor();
|
||||
else
|
||||
listPanel.focus();
|
||||
}
|
||||
|
@ -1477,5 +1471,36 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
|
||||
return detailPane != null && detailPane.getTabcount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* set focus to next readwrite editor from ref
|
||||
* @param ref
|
||||
*/
|
||||
@Override
|
||||
public void focusToNextEditor(WEditor ref) {
|
||||
boolean found = false;
|
||||
for (WEditor editor : editors) {
|
||||
if (editor == ref) {
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
if (found) {
|
||||
if (editor.isVisible() && editor.isReadWrite()) {
|
||||
focusToEditor(editor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void focusToEditor(WEditor toFocus) {
|
||||
Component c = toFocus.getComponent();
|
||||
if (c instanceof EditorBox) {
|
||||
c = ((EditorBox)c).getTextbox();
|
||||
} else if (c instanceof NumberBox) {
|
||||
c = ((NumberBox)c).getDecimalbox();
|
||||
}
|
||||
((HtmlBasedComponent)c).focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,12 +44,14 @@ import org.compiere.util.CLogger;
|
|||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zk.au.out.AuScript;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
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.KeyEvent;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
import org.zkoss.zul.Space;
|
||||
|
||||
/**
|
||||
|
@ -504,6 +506,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
|||
keyEvent.stopPropagation();
|
||||
if (!btn.isDisabled() && btn.isVisible()) {
|
||||
Events.sendEvent(btn, new Event(Events.ON_CLICK, btn));
|
||||
//client side script to close combobox popup
|
||||
String script = "var w=zk.Widget.$('#" + btn.getUuid()+"'); " +
|
||||
"zWatch.fire('onFloatUp', w);";
|
||||
Clients.response(new AuScript(script));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1916,6 +1916,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
}
|
||||
|
||||
if (dirtyTabpanel != null && dirtyTabpanel.getGridTab().isDetail()) {
|
||||
Executions.getCurrent().setAttribute("adtabpane.saved", dirtyTabpanel);
|
||||
dirtyTabpanel.getGridTab().refreshParentTabs();
|
||||
}
|
||||
|
||||
|
@ -1945,9 +1946,18 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
|
|||
if(result)
|
||||
{
|
||||
adTabbox.getSelectedGridTab().dataRefreshAll(true, true);
|
||||
IADTabpanel dirtyTabpanel = (IADTabpanel) Executions.getCurrent().removeAttribute("adtabpane.saved");
|
||||
if (dirtyTabpanel != null && dirtyTabpanel.getGridTab().isDetail()) {
|
||||
try {
|
||||
adTabbox.getSelectedTabpanel().getDetailPane().onNew();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
onNew();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -258,8 +258,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
|||
button.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
Event openEvent = new Event(ON_NEW_EVENT, DetailPane.this);
|
||||
eventListener.onEvent(openEvent);
|
||||
onNew();
|
||||
}
|
||||
});
|
||||
button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New")));
|
||||
|
@ -709,4 +708,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onNew() throws Exception {
|
||||
Event openEvent = new Event(ON_NEW_EVENT, DetailPane.this);
|
||||
eventListener.onEvent(openEvent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.util.GridRowCtx;
|
||||
import org.adempiere.webui.component.Checkbox;
|
||||
|
@ -37,7 +38,6 @@ import org.compiere.util.DisplayType;
|
|||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
import org.zkoss.zk.au.out.AuFocus;
|
||||
import org.zkoss.zk.au.out.AuScript;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.HtmlBasedComponent;
|
||||
|
@ -397,6 +397,8 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
|||
else if (DisplayType.isNumeric(gridPanelFields[i].getDisplayType())) {
|
||||
divStyle = CELL_DIV_STYLE_ALIGN_RIGHT;
|
||||
}
|
||||
GridRowCtx ctx = new GridRowCtx(Env.getCtx(), gridTab, rowIndex);
|
||||
component.setVisible(gridPanelFields[i].isDisplayed(ctx, true));
|
||||
}
|
||||
div.setStyle(divStyle);
|
||||
div.setWidth("100%");
|
||||
|
@ -498,8 +500,12 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
|||
popupMenu.addContextElement((XulElement) editor.getComponent());
|
||||
}
|
||||
|
||||
|
||||
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab, gridTab.getCurrentRow())
|
||||
: gridPanelFields[i].getVO().ctx;
|
||||
//check context
|
||||
if (!gridPanelFields[i].isDisplayedGrid())
|
||||
if (!gridPanelFields[i].isDisplayedGrid() ||
|
||||
!gridPanelFields[i].isDisplayed(ctx, true))
|
||||
{
|
||||
editor.setVisible(false);
|
||||
}
|
||||
|
@ -514,6 +520,17 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isDetailPane() {
|
||||
Component parent = grid.getParent();
|
||||
while (parent != null) {
|
||||
if (parent instanceof DetailPane) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RowRendererExt#getControls()
|
||||
*/
|
||||
|
@ -556,7 +573,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
|||
/**
|
||||
* set focus to first active editor
|
||||
*/
|
||||
public void setFocusToEditor() {
|
||||
public void focusToFirstEditor() {
|
||||
if (currentRow != null && currentRow.getParent() != null) {
|
||||
WEditor toFocus = null;
|
||||
WEditor firstEditor = null;
|
||||
|
@ -575,21 +592,39 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
|||
}
|
||||
}
|
||||
if (toFocus != null) {
|
||||
focusToEditor(toFocus);
|
||||
} else if (firstEditor != null) {
|
||||
focusToEditor(firstEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void focusToEditor(WEditor toFocus) {
|
||||
Component c = toFocus.getComponent();
|
||||
if (c instanceof EditorBox) {
|
||||
c = ((EditorBox)c).getTextbox();
|
||||
} else if (c instanceof NumberBox) {
|
||||
c = ((NumberBox)c).getDecimalbox();
|
||||
}
|
||||
Clients.response(new AuFocus(c));
|
||||
} else if (firstEditor != null) {
|
||||
Component c = firstEditor.getComponent();
|
||||
if (c instanceof EditorBox) {
|
||||
c = ((EditorBox)c).getTextbox();
|
||||
} else if (c instanceof NumberBox) {
|
||||
c = ((NumberBox)c).getDecimalbox();
|
||||
((HtmlBasedComponent)c).focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* set focus to next readwrite editor from ref
|
||||
* @param ref
|
||||
*/
|
||||
public void focusToNextEditor(WEditor ref) {
|
||||
boolean found = false;
|
||||
for (WEditor editor : getEditors()) {
|
||||
if (editor == ref) {
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
if (found) {
|
||||
if (editor.isVisible() && editor.isReadWrite()) {
|
||||
focusToEditor(editor);
|
||||
break;
|
||||
}
|
||||
Clients.response(new AuFocus(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@ import java.util.Comparator;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import org.adempiere.model.MTabCustomization;
|
||||
import org.adempiere.util.GridRowCtx;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.component.Columns;
|
||||
import org.adempiere.webui.component.EditorBox;
|
||||
|
@ -60,7 +62,7 @@ import org.zkoss.zul.event.ZulEvents;
|
|||
* @author Low Heng Sin
|
||||
*
|
||||
*/
|
||||
public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
||||
public class GridView extends Vbox implements EventListener<Event>, IdSpace, IFieldEditorContainer
|
||||
{
|
||||
private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;";
|
||||
|
||||
|
@ -529,7 +531,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
if (columnName != null && columnName.trim().length() > 0)
|
||||
setFocusToField(columnName);
|
||||
else
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -587,7 +589,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
setFocusToField(columnOnClick);
|
||||
columnOnClick = null;
|
||||
} else {
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
} else {
|
||||
focusToRow(row);
|
||||
|
@ -610,7 +612,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
setFocusToField(columnOnClick);
|
||||
columnOnClick = null;
|
||||
} else {
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
} else {
|
||||
focusToRow(row);
|
||||
|
@ -631,7 +633,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
setFocusToField(columnOnClick);
|
||||
columnOnClick = null;
|
||||
} else {
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
} else {
|
||||
Component cmp = null;
|
||||
|
@ -744,11 +746,25 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
comp.setReadWrite(rw);
|
||||
}
|
||||
|
||||
comp.setVisible(mField.isDisplayedGrid());
|
||||
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab, gridTab.getCurrentRow())
|
||||
: mField.getVO().ctx;
|
||||
|
||||
comp.setVisible(mField.isDisplayedGrid() && mField.isDisplayed(ctx, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDetailPane() {
|
||||
Component parent = this.getParent();
|
||||
while (parent != null) {
|
||||
if (parent instanceof DetailPane) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param windowNo
|
||||
|
@ -760,7 +776,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
@Override
|
||||
public void focus() {
|
||||
if (renderer != null && renderer.isEditing()) {
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -770,7 +786,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
public boolean onEnterKey() {
|
||||
if (!modeless && renderer != null && !renderer.isEditing()) {
|
||||
renderer.editCurrentRow();
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -827,9 +843,34 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
}
|
||||
|
||||
public void onEditCurrentRow() {
|
||||
onEditCurrentRow(null);
|
||||
}
|
||||
|
||||
public void onEditCurrentRow(Event event) {
|
||||
if (!renderer.isEditing()) {
|
||||
Row currentRow = renderer.getCurrentRow();
|
||||
if (currentRow == null || currentRow.getParent() == null || !currentRow.isVisible()) {
|
||||
if (event == null) {
|
||||
Events.postEvent("onEditCurrentRow", this, null);
|
||||
}
|
||||
} else {
|
||||
renderer.editCurrentRow();
|
||||
renderer.setFocusToEditor();
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusToFirstEditor() {
|
||||
if (renderer.isEditing()) {
|
||||
renderer.focusToFirstEditor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusToNextEditor(WEditor ref) {
|
||||
if (renderer.isEditing()) {
|
||||
renderer.focusToNextEditor(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.adwindow;
|
||||
|
||||
import org.adempiere.webui.editor.WEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public interface IFieldEditorContainer {
|
||||
/**
|
||||
* focus to first field editor
|
||||
*/
|
||||
public void focusToFirstEditor();
|
||||
|
||||
/**
|
||||
* focus to next field editor from ref
|
||||
* @param ref
|
||||
*/
|
||||
public void focusToNextEditor(WEditor ref);
|
||||
}
|
|
@ -29,6 +29,7 @@ import java.util.logging.Level;
|
|||
import org.adempiere.util.Callback;
|
||||
import org.adempiere.webui.ValuePreference;
|
||||
import org.adempiere.webui.adwindow.ADWindow;
|
||||
import org.adempiere.webui.adwindow.IFieldEditorContainer;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.component.Searchbox;
|
||||
import org.adempiere.webui.event.ContextMenuEvent;
|
||||
|
@ -55,11 +56,14 @@ import org.compiere.util.DB;
|
|||
import org.compiere.util.DisplayType;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.zkoss.zk.au.out.AuScript;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
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.util.Clients;
|
||||
|
||||
/**
|
||||
* Search Editor for web UI.
|
||||
|
@ -405,6 +409,22 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
|
|||
|
||||
actionCombo(new Integer(id)); // data binding
|
||||
|
||||
Searchbox comp = getComponent();
|
||||
Component parent = comp.getParent();
|
||||
while (parent != null) {
|
||||
if (parent instanceof IFieldEditorContainer) {
|
||||
((IFieldEditorContainer) parent).focusToNextEditor(this);
|
||||
break;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
//safety check: if focus is going no where, focus back to self
|
||||
String uid = getComponent().getTextbox().getUuid();
|
||||
String script = "setTimeout(function(){try{var e = zk.Widget.$('#" + uid +
|
||||
"').$n(); if (jq(':focus').size() == 0) e.focus();} catch(error){}}, 100);";
|
||||
Clients.response(new AuScript(script));
|
||||
|
||||
resetButtonState();
|
||||
} // actionText
|
||||
|
||||
|
@ -563,6 +583,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
|
|||
{
|
||||
if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - Result = null (not cancelled)");
|
||||
}
|
||||
getComponent().getTextbox().focus();
|
||||
}
|
||||
});
|
||||
ip.setId(ip.getTitle()+"_"+ip.getWindowNo());
|
||||
|
|
Loading…
Reference in New Issue