-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello,
I followed the small talk Applying Input Masks With jQuery, to mask some fields on my form. But this form uses data binding, and when the mask is applied to the input (the input gets focus) the data binder sets the mask as the value on the object. Example:
form.zul (from the small talk, but with data binder)
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?> <zk> <!-- Loading all the scripts necessary to apply the input masks to the fields --> <?script type="text/javascript" src="/js/jquery.js"?> <?script type="text/javascript" src="/js/jquery.maskedinput.js"?> <?script type="text/javascript" src="/js/common.js"?> <window width="100%" title="Input Mask Example" border="normal"> <attribute name="onCreate"> String command = "applyPhoneMask('"+phoneNumber.getUuid()+"');applyZipCodeMask('"+zipCode.getUuid()+"')"; Clients.evalJavaScript(command); </attribute> <vbox> <hbox>Phone Numer: <textbox id="phoneNumber" value="@{customer.phone} /></hbox> <hbox>ZIP Code: <textbox id="zipCode" value="@{customer.zipCode}" /></hbox> </vbox> </window> </zk>
When the user focus on any of the two textboxes the mask is applied by jQuery, the problem is that the data binder thinks that the mask is an value entered by the user and sets the mask on the customer object.
customer.getPhone(); // returns (__) ____-____ customer.getZipCode(); // returns __.___-___
Is there a way to prevent theses values to be setted?
Regards,
Hi fmcypriano,
I sent you an email with some thoughts.
Anyway, ZK's data binder just get the data from fields no matter what are the values. So there are no interaction between jQuery and the data binder.
I think you should try something on the Databinder's side like a regex or something like that.
It's really sad to see that ZK does not provide input mask support.
Please let us know what you found.
Thank you
Gyo
I'm looking ZK's source code for binding, trying to find some extension point that I could use to implement a behavior on binding that allow me to specify a regex and if this is regex matches the binder shouldn't set the value on the bean.
Any tips or ideas about how to accomplish this is very welcome. Since I'm not closer to a solution.
Hi
you could try to set Constraint attribute on textbox, it support regex . please refre to Constraints
Ok, I can do a constraint for phone number like these:
<!-- matches the mask (99) 9999-9999 --> <textbox id="txtPhone" cols="20" value="@{customer.phone}" constraint="/\(\d{2}\)\s\d{4}-\d{4}/:Can't be only mask" />
But, when the user keeps this textbox blank they get an error telling "Can't be only mask". Constraints mean to validate user input and mask aren't user input, I don't think using constraint is the right choice.
For now the only solution I see is to be able to tell the binder when to not save (set) the value.
It's insanely hard to extend ZK's classes. Everything is private without get method, even protected ones.
I'm trying to extend AnnotateDataBinder, AnnotateDataBinderInit and Binding. It's being very unpleasant.
Hi
I look at AnnotateDataBinder source code, find out there could be another way to do it.
componentX attrY="@{bean's value,[tag='expression']
textbox id="firstName" value="@{person.firstName, save-when='self.onChange'}
the tag='expression' specify when to do the databinding, so maybe you could post a event after input mask has done the validation. use this event to do databinding.
i think the current unknown will be what kind of event is the right choice , or maybe we have to custom our own event ? and when to post the event ?
these questions may need to understand the input mask source code, when does input mask done validation and accept the value, which event will post? I am guessing onChange
The input mask is applied at the client, by jQuery. The idea is to use textbox's onChange event to see if the value isn't only the mask characters?
Something like:
public void onChange$phoneNumber(InputEvent event){ if ("(__) ____-____".equals(phoneNumber.getValue())){ phoneNumber.setValue(null); } }
Did I understand correctly? The binder gets the component's value after the onChange event completes?
@ fmcypriano,
You can write a TypeConverter to "filter" the value what the DataBinder is going to "save".
xxx.zul
... <hbox>Phone Numer: <textbox id="phoneNumber" value="@{customer.phone, converter='com.mypackage.PhoneNumberConverter'} /></hbox> ...
public class PhoneNumberConverter implements TypeConverter { public Object coerceToBean(java.lang.Object val, Component comp) { if ("(__) ____-____".equals(val)) { return null; //or TypeConverter.IGNORE <-- will not do the "save" at all } return val; } ... }
Asked: 2010-04-05 08:54:08 +0800
Seen: 1,710 times
Last updated: Apr 11 '10