IDEMPIERE-762 Zk: Grid line editing enhancement.

This commit is contained in:
Heng Sin Low 2013-03-18 15:23:07 +08:00
parent 5e30569fc8
commit fc083ca2d8
8 changed files with 217 additions and 41 deletions

View File

@ -114,7 +114,7 @@ import org.zkoss.zul.impl.XulElement;
* @author Low Heng Sin * @author Low Heng Sin
*/ */
public class ADTabpanel extends Div implements Evaluatee, EventListener<Event>, 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"; private static final String ON_SAVE_OPEN_PREFERENCE_EVENT = "onSaveOpenPreference";
@ -923,7 +923,7 @@ DataStatusListener, IADTabpanel, IdSpace
} else { } else {
if (activate) { if (activate) {
formContainer.setVisible(activate); formContainer.setVisible(activate);
setFocusToField(); focusToFirstEditor();
} }
} }
@ -938,7 +938,8 @@ DataStatusListener, IADTabpanel, IdSpace
/** /**
* set focus to first active editor * set focus to first active editor
*/ */
private void setFocusToField() { @Override
public void focusToFirstEditor() {
WEditor toFocus = null; WEditor toFocus = null;
for (WEditor editor : editors) { for (WEditor editor : editors) {
if (editor.isHasFocus() && editor.isVisible() && editor.getComponent().getParent() != null) { if (editor.isHasFocus() && editor.isVisible() && editor.getComponent().getParent() != null) {
@ -954,14 +955,7 @@ DataStatusListener, IADTabpanel, IdSpace
} }
} }
if (toFocus != null) { if (toFocus != null) {
Component c = toFocus.getComponent(); focusToEditor(toFocus);
if (c instanceof EditorBox) {
c = ((EditorBox)c).getTextbox();
} else if (c instanceof NumberBox) {
c = ((NumberBox)c).getDecimalbox();
}
Clients.response(new AuFocus(c));
} }
} }
@ -1302,7 +1296,7 @@ DataStatusListener, IADTabpanel, IdSpace
@Override @Override
public void focus() { public void focus() {
if (formContainer.isVisible()) if (formContainer.isVisible())
this.setFocusToField(); this.focusToFirstEditor();
else else
listPanel.focus(); listPanel.focus();
} }
@ -1477,5 +1471,36 @@ DataStatusListener, IADTabpanel, IdSpace
return detailPane != null && detailPane.getTabcount() > 0; 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();
}
} }

View File

@ -44,12 +44,14 @@ import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.zkoss.image.AImage; import org.zkoss.image.AImage;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Space; import org.zkoss.zul.Space;
/** /**
@ -504,6 +506,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
keyEvent.stopPropagation(); keyEvent.stopPropagation();
if (!btn.isDisabled() && btn.isVisible()) { if (!btn.isDisabled() && btn.isVisible()) {
Events.sendEvent(btn, new Event(Events.ON_CLICK, btn)); 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));
} }
} }
} }

View File

@ -1916,6 +1916,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
} }
if (dirtyTabpanel != null && dirtyTabpanel.getGridTab().isDetail()) { if (dirtyTabpanel != null && dirtyTabpanel.getGridTab().isDetail()) {
Executions.getCurrent().setAttribute("adtabpane.saved", dirtyTabpanel);
dirtyTabpanel.getGridTab().refreshParentTabs(); dirtyTabpanel.getGridTab().refreshParentTabs();
} }
@ -1945,7 +1946,16 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if(result) if(result)
{ {
adTabbox.getSelectedGridTab().dataRefreshAll(true, true); adTabbox.getSelectedGridTab().dataRefreshAll(true, true);
onNew(); 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();
}
} }
} }
}); });

View File

@ -258,8 +258,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
button.addEventListener(Events.ON_CLICK, new EventListener<Event>() { button.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
Event openEvent = new Event(ON_NEW_EVENT, DetailPane.this); onNew();
eventListener.onEvent(openEvent);
} }
}); });
button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New"))); button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New")));
@ -709,4 +708,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
} }
return null; return null;
} }
public void onNew() throws Exception {
Event openEvent = new Event(ON_NEW_EVENT, DetailPane.this);
eventListener.onEvent(openEvent);
}
} }

View File

@ -17,6 +17,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Properties;
import org.adempiere.util.GridRowCtx; import org.adempiere.util.GridRowCtx;
import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Checkbox;
@ -37,7 +38,6 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuFocus;
import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.HtmlBasedComponent;
@ -397,6 +397,8 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
else if (DisplayType.isNumeric(gridPanelFields[i].getDisplayType())) { else if (DisplayType.isNumeric(gridPanelFields[i].getDisplayType())) {
divStyle = CELL_DIV_STYLE_ALIGN_RIGHT; 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.setStyle(divStyle);
div.setWidth("100%"); div.setWidth("100%");
@ -498,8 +500,12 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
popupMenu.addContextElement((XulElement) editor.getComponent()); popupMenu.addContextElement((XulElement) editor.getComponent());
} }
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab, gridTab.getCurrentRow())
: gridPanelFields[i].getVO().ctx;
//check context //check context
if (!gridPanelFields[i].isDisplayedGrid()) if (!gridPanelFields[i].isDisplayedGrid() ||
!gridPanelFields[i].isDisplayed(ctx, true))
{ {
editor.setVisible(false); 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() * @see RowRendererExt#getControls()
*/ */
@ -556,7 +573,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
/** /**
* set focus to first active editor * set focus to first active editor
*/ */
public void setFocusToEditor() { public void focusToFirstEditor() {
if (currentRow != null && currentRow.getParent() != null) { if (currentRow != null && currentRow.getParent() != null) {
WEditor toFocus = null; WEditor toFocus = null;
WEditor firstEditor = null; WEditor firstEditor = null;
@ -575,21 +592,39 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
} }
} }
if (toFocus != null) { if (toFocus != null) {
Component c = toFocus.getComponent(); focusToEditor(toFocus);
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) { } else if (firstEditor != null) {
Component c = firstEditor.getComponent(); focusToEditor(firstEditor);
if (c instanceof EditorBox) { }
c = ((EditorBox)c).getTextbox(); }
} else if (c instanceof NumberBox) { }
c = ((NumberBox)c).getDecimalbox();
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();
}
/**
* 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));
} }
} }
} }

View File

@ -18,10 +18,12 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import org.adempiere.model.MTabCustomization; import org.adempiere.model.MTabCustomization;
import org.adempiere.util.GridRowCtx;
import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Columns;
import org.adempiere.webui.component.EditorBox; import org.adempiere.webui.component.EditorBox;
@ -60,7 +62,7 @@ import org.zkoss.zul.event.ZulEvents;
* @author Low Heng Sin * @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;"; 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) if (columnName != null && columnName.trim().length() > 0)
setFocusToField(columnName); setFocusToField(columnName);
else else
renderer.setFocusToEditor(); renderer.focusToFirstEditor();
} }
} }
else else
@ -587,7 +589,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
setFocusToField(columnOnClick); setFocusToField(columnOnClick);
columnOnClick = null; columnOnClick = null;
} else { } else {
renderer.setFocusToEditor(); renderer.focusToFirstEditor();
} }
} else { } else {
focusToRow(row); focusToRow(row);
@ -610,7 +612,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
setFocusToField(columnOnClick); setFocusToField(columnOnClick);
columnOnClick = null; columnOnClick = null;
} else { } else {
renderer.setFocusToEditor(); renderer.focusToFirstEditor();
} }
} else { } else {
focusToRow(row); focusToRow(row);
@ -631,7 +633,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
setFocusToField(columnOnClick); setFocusToField(columnOnClick);
columnOnClick = null; columnOnClick = null;
} else { } else {
renderer.setFocusToEditor(); renderer.focusToFirstEditor();
} }
} else { } else {
Component cmp = null; Component cmp = null;
@ -744,11 +746,25 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
comp.setReadWrite(rw); 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 * @param windowNo
@ -760,7 +776,7 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
@Override @Override
public void focus() { public void focus() {
if (renderer != null && renderer.isEditing()) { 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() { public boolean onEnterKey() {
if (!modeless && renderer != null && !renderer.isEditing()) { if (!modeless && renderer != null && !renderer.isEditing()) {
renderer.editCurrentRow(); renderer.editCurrentRow();
renderer.setFocusToEditor(); renderer.focusToFirstEditor();
return true; return true;
} }
return false; return false;
@ -827,9 +843,34 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
} }
public void onEditCurrentRow() { public void onEditCurrentRow() {
onEditCurrentRow(null);
}
public void onEditCurrentRow(Event event) {
if (!renderer.isEditing()) { if (!renderer.isEditing()) {
renderer.editCurrentRow(); Row currentRow = renderer.getCurrentRow();
renderer.setFocusToEditor(); if (currentRow == null || currentRow.getParent() == null || !currentRow.isVisible()) {
if (event == null) {
Events.postEvent("onEditCurrentRow", this, null);
}
} else {
renderer.editCurrentRow();
renderer.focusToFirstEditor();
}
}
}
@Override
public void focusToFirstEditor() {
if (renderer.isEditing()) {
renderer.focusToFirstEditor();
}
}
@Override
public void focusToNextEditor(WEditor ref) {
if (renderer.isEditing()) {
renderer.focusToNextEditor(ref);
} }
} }
} }

View File

@ -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);
}

View File

@ -29,6 +29,7 @@ import java.util.logging.Level;
import org.adempiere.util.Callback; import org.adempiere.util.Callback;
import org.adempiere.webui.ValuePreference; import org.adempiere.webui.ValuePreference;
import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.adwindow.ADWindow;
import org.adempiere.webui.adwindow.IFieldEditorContainer;
import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Searchbox; import org.adempiere.webui.component.Searchbox;
import org.adempiere.webui.event.ContextMenuEvent; import org.adempiere.webui.event.ContextMenuEvent;
@ -55,11 +56,14 @@ import org.compiere.util.DB;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Util; 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.Executions;
import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
/** /**
* Search Editor for web UI. * Search Editor for web UI.
@ -405,6 +409,22 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
actionCombo(new Integer(id)); // data binding 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(); resetButtonState();
} // actionText } // 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)"); if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - Result = null (not cancelled)");
} }
getComponent().getTextbox().focus();
} }
}); });
ip.setId(ip.getTitle()+"_"+ip.getWindowNo()); ip.setId(ip.getTitle()+"_"+ip.getWindowNo());