IDEMPIERE-2003 Capturing wrong numbers with numeric keypad when decimal separator is not dot

This commit is contained in:
Carlos Ruiz 2014-07-11 20:11:30 -05:00
parent 7bf148926e
commit c3f9e44ca0
3 changed files with 92 additions and 41 deletions

View File

@ -42,7 +42,7 @@ 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 PDF_FONT_DIR = "PDF_FONT_DIR";
public final static String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS"; public final static String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS";
@ -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 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 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 VALIDATE_MATCHING_TO_ORDERED_QTY = "VALIDATE_MATCHING_TO_ORDERED_QTY";
public static final String ZK_DECIMALBOX_PROCESS_DOTKEYPAD = "ZK_DECIMALBOX_PROCESS_DOTKEYPAD";
/** /**
* Standard Constructor * Standard Constructor

View File

@ -23,6 +23,7 @@ import java.text.ParseException;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.theme.ThemeManager;
import org.compiere.model.MSysConfig;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.zkoss.zk.ui.Page; 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(); private Textbox txtCalc = new Textbox();
@ -84,6 +85,39 @@ public class NumberBox extends Div
decimalBox.setStyle("display: inline-block;text-align:right"); decimalBox.setStyle("display: inline-block;text-align:right");
decimalBox.setHflex("0"); decimalBox.setHflex("0");
decimalBox.setSclass("editor-input"); decimalBox.setSclass("editor-input");
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); appendChild(decimalBox);
btn = new Button(); btn = new Button();
@ -197,13 +231,35 @@ public class NumberBox extends Div
Vbox vbox = new Vbox(); Vbox vbox = new Vbox();
char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator(); char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator();
String separator = Character.toString(separatorChar);
txtCalc = new Textbox(); txtCalc = new Textbox();
decimalBox.setId(decimalBox.getUuid()); decimalBox.setId(decimalBox.getUuid());
txtCalc.setId(txtCalc.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() decimalBox.getId() + "','" + txtCalc.getId()
+ "'," + integral + "," + (int)separatorChar + ", event);"); + "'," + integral + "," + (int)separatorChar + ", event);");
txtCalc.setMaxlength(250); txtCalc.setMaxlength(250);
@ -323,7 +379,6 @@ public class NumberBox extends Div
btn0.setLabel("0"); btn0.setLabel("0");
btn0.setWidgetListener("onClick", "calc.append('" + txtCalcId + "', '0')"); btn0.setWidgetListener("onClick", "calc.append('" + txtCalcId + "', '0')");
String separator = Character.toString(separatorChar);
Button btnDot = new Button(); Button btnDot = new Button();
btnDot.setWidth("30px"); btnDot.setWidth("30px");
btnDot.setLabel(separator); btnDot.setLabel(separator);

View File

@ -1,13 +1,14 @@
function Calc() function Calc()
{ {
this.validate = validate; this.validateUp = validateUp;
this.validatePress = validatePress;
this.clear = clear; this.clear = clear;
this.clearAll = clearAll; this.clearAll = clearAll;
this.evaluate = evaluate; this.evaluate = evaluate;
this.append = append; this.append = append;
function validate(displayTextId, calcTextId, integral, separatorKey, e) function validatePress(displayTextId, calcTextId, integral, separatorKey, e)
{ {
var key; var key;
@ -15,43 +16,29 @@ function Calc()
key = e.keyCode; //IE key = e.keyCode; //IE
else else
key = e.which; //Firefox key = e.which; //Firefox
// console.log("validatePress: " + displayTextId + " / " + calcTextId + " / " + integral + " / " + separatorKey + " / " + key);
if(key == 13 || key == 61) // Enter, = if (key == 61) // =
{ {
evaluate(displayTextId, calcTextId, String.fromCharCode(separatorKey)); evaluate(displayTextId, calcTextId, String.fromCharCode(separatorKey));
return false;
} }
else if (key == 0) // control, delete, ... }
function validateUp(displayTextId, calcTextId, integral, separatorKey, e, processDotKeypad)
{ {
return true; var key;
} if(window.event)
else if (key == 8) // backspace key = e.keyCode; //IE
{
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;
}
else 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) function evaluate(displayTextId, calcTextId, separator)
{ {
// console.log("evaluate: " + displayTextId + " / " + calcTextId + " / " + separator);
var newValue = "error";
try try
{ {
var id = "$".concat(calcTextId); var id = "$".concat(calcTextId);
@ -99,6 +88,11 @@ function Calc()
var re = new RegExp("[" + separator + "]", "g"); var re = new RegExp("[" + separator + "]", "g");
value = value.replace(re,'.'); 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); var result = "" + eval(value);
if (separator != '.') if (separator != '.')
{ {
@ -117,6 +111,7 @@ function Calc()
} }
catch (err) catch (err)
{ {
calcText.value = newValue;
} }
} }