Introduction
Currently ZK Decimalbox does not support scientific notation, this article describe how to customize it to support scientific notation.
Result
View demo online
http://screencast.com/t/ZtbTj0H2M
Pre-request
Extending and Customizing ZK Component as Separate Component
http://ben-bai.blogspot.tw/2013/01/extending-and-customizing-zk-component.html
Program
support_scientific_notation.zul
<zk>
decimalbox:
<decimalbox constraint="no empty"
textAlign="right">
<attribute name="onChange"><![CDATA[
lb.setValue(self.getValue() + "");
lbTwo.setValue(self.getValue().intValue() + "");
]]></attribute>
<attribute name="onScientificNotation"><![CDATA[
lb.setValue(self.getValue() + "");
lbTwo.setValue(self.getValue().intValue() + "");
]]></attribute>
</decimalbox>
<div />
BigDecimal value: <label id="lb" />
<div />
int value: <label id="lbTwo" />
<div style="margin-top: 30px;" />
rounded decimalbox
<decimalbox mold="rounded" constraint="no empty"
textAlign="right">
<attribute name="onChange"><![CDATA[
lbThree.setValue(self.getValue() + "");
lbFour.setValue(self.getValue().intValue() + "");
]]></attribute>
<attribute name="onScientificNotation"><![CDATA[
lbThree.setValue(self.getValue() + "");
lbFour.setValue(self.getValue().intValue() + "");
]]></attribute>
</decimalbox>
<div />
BigDecimal value: <label id="lbThree" />
<div />
int value: <label id="lbFour" />
</zk>
Decimalbox.java
Custom java class for decimalbox, support scientific notation, also support text align attribute.
package test.components;
import java.math.BigDecimal;
import java.util.Map;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.util.Clients;
/** Tested with ZK 6.0.2
*
* @author benbai123
*
*/
public class Decimalbox extends org.zkoss.zul.Decimalbox {
private String _textAlign = "left";
private static final long serialVersionUID = -4797186118579295417L;
static {
// listen custom event
addClientEvent(Decimalbox.class, "onCheckErrorValue", CE_IMPORTANT | CE_DUPLICATE_IGNORE | CE_NON_DEFERRABLE);
}
public void setTextAlign (String textAlign) {
// update if there is a different value
if (textAlign != null // no null
&& !textAlign.isEmpty() // no empty
&& !textAlign.equals(_textAlign)) { // value is changed
_textAlign = textAlign;
smartUpdate("textAlign", _textAlign);
}
}
public String getTextAlign () {
return _textAlign;
}
// override
// process client event
public void service(org.zkoss.zk.au.AuRequest request, boolean everError) {
final String cmd = request.getCommand();
// process custom event
if (cmd.equals("onCheckErrorValue")) {
// get data map
Map<String, Object> data = request.getData();
// get value
String value = (String)data.get("value");
boolean valid = true;
BigDecimal val = null;
// try create a BigDecimal with the wrong value
try {
val = new BigDecimal(value);
} catch (Exception e) {
// failed to create BigDecimal, not valid
valid = false;
}
if (valid) {
// it is valid for BigDecimal
setValueDirectly(val);
// post onScientificNotation event
Events.postEvent("onScientificNotation", this, null);
// clear the error status if any
clearErrorMessage();
Clients.clearWrongValue(this);
} else {
// it is invalid for BigDecimal
// really do _markError at client side
// the code below will call function _realMarkError
// of the widget class at client side
response("DecimalboxSupportScientificNotation", new AuInvoke(this, "_realMarkError", (String[])null));
}
} else
super.service(request, everError);
}
protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer)
throws java.io.IOException {
super.renderProperties(renderer);
if (!"left".equals(_textAlign)) {
render(renderer, "textAlign", _textAlign);
}
}
}
Decimalbox.js
Custom widget class for decimalbox, will ask server at first while do _maskError.
test.components.Decimalbox = zk.$extends(zul.inp.Decimalbox, {
_textAlign: 'left',
setTextAlign: function (v) {
if (v != this._textAlign) {
this._textAlign = v;
var inp = this.getInputNode();
if (inp)
jq(inp).css('text-align', this._textAlign);
}
},
bind_: function () {
this.$supers('bind_', arguments);
jq(this.getInputNode()).css('text-align', this._textAlign);
},
getAllowedKeys_: function () {
// add 'E' into allowed keys
return this.$supers('getAllowedKeys_', arguments) + 'E';
},
_markError: function (msg, val, noOnError, doDirectly) {
if (doDirectly) {
// do it without server confirmation
this.$supers('_markError', arguments);
} else {
// store info only, waiting for server confirmation
this._markErrorInfo = {msg: msg, val: val, noOnError: noOnError};
// ask server side custom validation
var wgt = this,
timer = this._onCheckErrorValueTimer;
// prevent duplicated event
if (timer)
clearTimeout(timer);
this._onCheckErrorValueTimer = setTimeout (function () {
wgt.fire('onCheckErrorValue', {value: jq(wgt.getInputNode()).val()});
}, 300);
}
},
// called by server
// do _markError directly with the stored information
_realMarkError: function () {
var info = this._markErrorInfo;
if (info) {
this._markError(info.msg, info.val, info.noOnError, true);
this._markErrorInfo = null;
}
}
});
zk.xml
Specify lang-addon.xml
<zk>
<language-config>
<addon-uri>/WEB-INF/lang-addon.xml</addon-uri>
</language-config>
</zk>
lang-addon.xml
Define the customized decimalbox
<language-addon>
<addon-name>decimalboxcustomization</addon-name>
<language-name>xul/html</language-name>
<!-- extends ZK Decimalbox and use custom classes -->
<component>
<component-name>decimalbox</component-name>
<component-class>test.components.Decimalbox</component-class>
<widget-class>test.components.Decimalbox</widget-class>
<mold>
<mold-name>default</mold-name>
</mold>
<mold>
<mold-name>rounded</mold-name>
</mold>
</component>
</language-addon>
zk.wpd
Used to load widget class.
<package name="test.components" language="xul/html" depends="zul.inp">
<widget name="Decimalbox" />
</package>
References
InputWidget.js
https://github.com/zkoss/zk/blob/master/zul/src/archive/web/js/zul/inp/InputWidget.js
InputElement.java
https://github.com/zkoss/zk/blob/master/zul/src/org/zkoss/zul/impl/InputElement.java
Download
how to work with focus?http://stackoverflow.com/questions/17424124/zk-why-zk-drop-getfocus-or-isfocus
ReplyDelete