diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index abd2e268b4..7fb0174fae 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -42,8 +42,8 @@ public class MSysConfig extends X_AD_SysConfig /** * */ - private static final long serialVersionUID = 4741060210080877182L; - + private static final long serialVersionUID = 8421477785276068578L; + public final static String PDF_FONT_DIR = "PDF_FONT_DIR"; public final static String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS"; public static final String ZK_DESKTOP_CLASS = "ZK_DESKTOP_CLASS"; @@ -122,6 +122,7 @@ public class MSysConfig extends X_AD_SysConfig public static final String TAX_SAVE_REQUEST_RESPONSE_LOG = "TAX_SAVE_REQUEST_RESPONSE_LOG"; public static final String ADDRESS_SAVE_REQUEST_RESPONSE_LOG = "ADDRESS_SAVE_REQUEST_RESPONSE_LOG"; public static final String VALIDATE_MATCHING_TO_ORDERED_QTY = "VALIDATE_MATCHING_TO_ORDERED_QTY"; + public static final String ZK_DECIMALBOX_PROCESS_DOTKEYPAD = "ZK_DECIMALBOX_PROCESS_DOTKEYPAD"; /** * Standard Constructor diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java index 72455afab2..269f59d9e5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java @@ -23,6 +23,7 @@ import java.text.ParseException; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.theme.ThemeManager; +import org.compiere.model.MSysConfig; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.zkoss.zk.ui.Page; @@ -47,7 +48,7 @@ public class NumberBox extends Div /** * */ - private static final long serialVersionUID = -3548087521669052891L; + private static final long serialVersionUID = 8543853599051754172L; private Textbox txtCalc = new Textbox(); @@ -84,7 +85,40 @@ public class NumberBox extends Div decimalBox.setStyle("display: inline-block;text-align:right"); decimalBox.setHflex("0"); decimalBox.setSclass("editor-input"); - appendChild(decimalBox); + decimalBox.setId(decimalBox.getUuid()); + + char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator(); + String separator = Character.toString(separatorChar); + boolean processDotKeypad = MSysConfig.getBooleanValue(MSysConfig.ZK_DECIMALBOX_PROCESS_DOTKEYPAD, true, Env.getAD_Client_ID(Env.getCtx())); + if (".".equals(separator)) + processDotKeypad = false; + if (processDotKeypad) { + StringBuffer funct = new StringBuffer(); + funct.append("function(evt)"); + funct.append("{"); + // ignore dot and process it on key up + funct.append(" if (!this._shallIgnore(evt, '0123456789-%").append(separator).append("'))"); + funct.append(" {"); + funct.append(" this.$doKeyPress_(evt);"); + funct.append(" }"); + funct.append("}"); + decimalBox.setWidgetOverride("doKeyPress_", funct.toString()); + funct = new StringBuffer(); + // not working correctly on opera + funct.append("if (window.event)"); + funct.append(" key = event.keyCode;"); + funct.append("else"); + funct.append(" key = event.which;"); + funct.append("if ((key == 110 || key == 190) && !window.opera) {"); + funct.append(" var id = '$'.concat('").append(decimalBox.getId()).append("');"); + funct.append(" var calcText = jq(id)[0];"); + funct.append(" calcText.value += '").append(separator).append("';"); + funct.append(" event.stop;"); + funct.append("};"); + decimalBox.setWidgetListener("onKeyUp", funct.toString()); + } + + appendChild(decimalBox); btn = new Button(); btn.setImage(ThemeManager.getThemeResource("images/Calculator16.png")); @@ -197,13 +231,35 @@ public class NumberBox extends Div Vbox vbox = new Vbox(); char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator(); + String separator = Character.toString(separatorChar); txtCalc = new Textbox(); decimalBox.setId(decimalBox.getUuid()); txtCalc.setId(txtCalc.getUuid()); - - txtCalc.setWidgetListener("onKeyUp", "return calc.validate('" + + + boolean processDotKeypad = MSysConfig.getBooleanValue(MSysConfig.ZK_DECIMALBOX_PROCESS_DOTKEYPAD, true, Env.getAD_Client_ID(Env.getCtx())); + if (".".equals(separator)) + processDotKeypad = false; + + // restrict allowed characters + String decimalSep = separator; + if (!processDotKeypad && !".".equals(separator)) + decimalSep += "."; + StringBuffer funct = new StringBuffer(); + funct.append("function(evt)"); + funct.append("{"); + funct.append(" if (!this._shallIgnore(evt, '= -/()*%+0123456789").append(decimalSep).append("'))"); + funct.append(" {"); + funct.append(" this.$doKeyPress_(evt);"); + funct.append(" }"); + funct.append("}"); + txtCalc.setWidgetOverride("doKeyPress_", funct.toString()); + + txtCalc.setWidgetListener("onKeyUp", "calc.validateUp('" + + decimalBox.getId() + "','" + txtCalc.getId() + + "'," + integral + "," + (int)separatorChar + ", event, " + ( processDotKeypad ? "true" : "false" ) + ");"); + txtCalc.setWidgetListener("onKeyPress", "calc.validatePress('" + decimalBox.getId() + "','" + txtCalc.getId() + "'," + integral + "," + (int)separatorChar + ", event);"); txtCalc.setMaxlength(250); @@ -323,7 +379,6 @@ public class NumberBox extends Div btn0.setLabel("0"); btn0.setWidgetListener("onClick", "calc.append('" + txtCalcId + "', '0')"); - String separator = Character.toString(separatorChar); Button btnDot = new Button(); btnDot.setWidth("30px"); btnDot.setLabel(separator); diff --git a/org.adempiere.ui.zk/js/calc.js b/org.adempiere.ui.zk/js/calc.js index ee35c0b3ed..40e0904160 100644 --- a/org.adempiere.ui.zk/js/calc.js +++ b/org.adempiere.ui.zk/js/calc.js @@ -1,13 +1,14 @@ function Calc() { - this.validate = validate; + this.validateUp = validateUp; + this.validatePress = validatePress; this.clear = clear; this.clearAll = clearAll; this.evaluate = evaluate; this.append = append; - function validate(displayTextId, calcTextId, integral, separatorKey, e) + function validatePress(displayTextId, calcTextId, integral, separatorKey, e) { var key; @@ -15,43 +16,29 @@ function Calc() key = e.keyCode; //IE else key = e.which; //Firefox - - if(key == 13 || key == 61) // Enter, = + // console.log("validatePress: " + displayTextId + " / " + calcTextId + " / " + integral + " / " + separatorKey + " / " + key); + if (key == 61) // = { evaluate(displayTextId, calcTextId, String.fromCharCode(separatorKey)); - return false; - } - else if (key == 0) // control, delete, ... - { - return true; - } - else if (key == 8) // backspace - { - return true; - } - else if (key >= 17 && key <= 20) // Control - { - return true; - } - else if (key == 32) // space - { - return true; - } - else if (key >= 48 && key <= 57) // 0 - 9 - { - return true; - } - else if (key == 42 || key == 43 || key == 45 || key == 47) // *, +, -, / - { - return true; - } - else if ( key == separatorKey && !integral) - { - return true; } + } + + function validateUp(displayTextId, calcTextId, integral, separatorKey, e, processDotKeypad) + { + var key; + if(window.event) + key = e.keyCode; //IE else + key = e.which; //Firefox + // console.log("validateUp: " + displayTextId + " / " + calcTextId + " / " + integral + " / " + separatorKey + " / " + key + " / " + processDotKeypad); + if (key == 13) // Enter { - return false; + evaluate(displayTextId, calcTextId, String.fromCharCode(separatorKey)); + } + else if (processDotKeypad && separatorKey != 46 && (key == 110 || key == 190) && !window.opera) // numeric dot on keypad (not working for opera) + { + append(calcTextId, String.fromCharCode(separatorKey)); + e.stop; } } @@ -89,6 +76,8 @@ function Calc() function evaluate(displayTextId, calcTextId, separator) { + // console.log("evaluate: " + displayTextId + " / " + calcTextId + " / " + separator); + var newValue = "error"; try { var id = "$".concat(calcTextId); @@ -99,6 +88,11 @@ function Calc() var re = new RegExp("[" + separator + "]", "g"); value = value.replace(re,'.'); } + var reclean = new RegExp("[^1234567890+-/*%() ]", "g"); // sanitize + value = value.replace(reclean,''); + var reperc = new RegExp("[%]", "g"); // percentage + value = value.replace(reperc,'/100 '); + newValue = value; var result = "" + eval(value); if (separator != '.') { @@ -117,6 +111,7 @@ function Calc() } catch (err) { + calcText.value = newValue; } }