0

Input masks with jQuery and data binder not playing nice together

asked 2010-04-05 08:54:08 +0800

fmcypriano gravatar image fmcypriano
612 1 7
http://felipecypriano.com...

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,

delete flag offensive retag edit

9 Replies

Sort by ยป oldest newest

answered 2010-04-05 14:59:05 +0800

gyowanny gravatar image gyowanny
283 1 2 6

updated 2010-04-05 15:00:12 +0800

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

link publish delete flag offensive edit

answered 2010-04-05 15:45:52 +0800

fmcypriano gravatar image fmcypriano
612 1 7
http://felipecypriano.com...

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.

link publish delete flag offensive edit

answered 2010-04-05 20:11:12 +0800

samchuang gravatar image samchuang
4084 4

Hi

you could try to set Constraint attribute on textbox, it support regex . please refre to Constraints

link publish delete flag offensive edit

answered 2010-04-06 06:57:39 +0800

fmcypriano gravatar image fmcypriano
612 1 7
http://felipecypriano.com...

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.

link publish delete flag offensive edit

answered 2010-04-06 13:59:17 +0800

fmcypriano gravatar image fmcypriano
612 1 7
http://felipecypriano.com...

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.

link publish delete flag offensive edit

answered 2010-04-06 19:57:40 +0800

samchuang gravatar image samchuang
4084 4

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

link publish delete flag offensive edit

answered 2010-04-07 06:25:32 +0800

fmcypriano gravatar image fmcypriano
612 1 7
http://felipecypriano.com...

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?

link publish delete flag offensive edit

answered 2010-04-11 20:05:42 +0800

samchuang gravatar image samchuang
4084 4

Hi

yes,
your code looks like a workaround

link publish delete flag offensive edit

answered 2010-04-11 20:27:19 +0800

henrichen gravatar image henrichen
3869 2
ZK Team

@ 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>
...

PhoneNumberConverter.java
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;
  }
  ...
}

http://www.zkoss.org/javadoc/5.0/zk/org/zkoss/zkplus/databind/TypeConverter.html

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-04-05 08:54:08 +0800

Seen: 1,710 times

Last updated: Apr 11 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More