Input Controls

A set of input controls are supported in the XUL component set: textbox, intbox, decimalbox, doublebox, datebox, combobox, and bandbox. They are used to let users input different types of data.

<zk>
    <textbox/>    
    <datebox/>    
</zk>

Tip: combobox and bandbox are special input boxes. They shares the common properties described here. Their unique features will be discussed later in the Comboboxes and Bandboxes section.

The type Property

You could specify the type property with password for the textbox components, such that what user has entered won't be shown.

Username: <textbox/>
Password: <textbox type="password"/>

The format Property

You could control the format of an input control by the format filed. The default is null. For datebox, it means yyyy/MM/dd. For intbox and decimalbox, it means no formating at all.

<datebox format="MM/dd/yyyy"/>
<decimalbox format="#,##0.##"/>

Like any other properties, you could change the format dynamically, as depicted below.

<datebox id="db"/><button label="set MM-dd-yyyy" onClick="db.setFormat(&quot;MM-dd-yyyy&quot;)"/>

Mouseless Entrydatebox

  • Alt+DOWN to pop up the calendar.

  • LEFT, RIGHT, UP and DOWN to change the selected day from the calendar.

  • ENTER to activate the selection by copying the selected day to the datebox control.

  • Alt+UP or ESC to give up the selection and close the calendar.

Constraints

You could specify what value to accept for input controls by use of the constraint property. It could a combination of no positive, no negative, no zero, no empty, no future, no past, no today, and a regular expression. The first three constraints are applicable only to intbox and decimalbox. The constraints of no future, no past, and no today are applicable only to datebox. The constraint of no empty is applicable to any type of components. The constraint of regular expressions is applicable only to String-type input components, such as textbox., combobox and bandbox.

To specify two or more constraints, use comma to separate them as follows.

<intbox constraint="no negative,no zero"/>

To specify a regular expression, you could have to use / to enclose the regular expression as follows.

<textbox constraint="/.+@.+\.[a-z]+/"/>

Notes:

  • The above statement is XML, so do not use \\ to specify a backslash. On the other hand, it is necessary, if writing in Java.

new Textbox().setContraint("/.+@.+\\.[a-z]+/");
  • It is allowed to mix regular expression with other constraints by separating them with comma.

You prefer to display an application dependent message instead of default one, you could append the constraint with colon and the message you want to display when failed.

<textbox constraint="/.+@.+\.[a-z]+/: e-mail address only"/>

<datebox constraint="no empty, no future: now or never"/>

Notes:

  • The error message, if specified, must be the last element and start with colon.

  • To support multilingual, you could use the l function as depicted in the Internationalization chapter.

<textbox constraint="/.+@.+\.[a-z]+/: ${c:l('err.email.required')}"/>

Constraints for Datebox

In addition to the constraints described in the above section (such as no future and regular expressions), datebox supports a range of dates. For example,

<datebox constraint="between 20071225 and 20071203"/>
<datebox constraint="before 20071225"/>
<datebox constraint="after 20071225"/>

Notices

  1. The format of the date in the constraint is yyyMMdd. It is independent of the locale.

  2. The date specified in the constraint is included. For example, "before 20071225" includes December 25, 2007 and every days before it.

  3. The constraint is actually represented with an instance of the org.zkoss.zul.SimpleDateConstraint class. You can retrieve the parsed beginning and ending date with the getBeginDate and getEndDate methods.

((SimpleDateConstraint)datebox.getConstraint()).getBeginDate();

Custom Constraints

If you want more sophisticated constraint, you could specify an object which implements the org.zkoss.zul.Constraint interface.

<window title="Custom Constraint">
    <zscript><![CDATA[    
Constraint ctt = new Constraint() {
    public void validate(Component comp, Object value) throws WrongValueException {    
        if (value =e= null || ((Integer)value).intValue() < 100)        
            throw new WrongValueException(comp, "At least 100 must be specified");            
    }    
}
    ]]></zscript>    
    <intbox constraint="${ctt}"/>    
</window>

You could implement your constraint into a Java class, say my.EmailValidator, then:

<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<textbox constraint="${c:new('my.EmailValidator')}"/>
org.zkoss.zk.ui.WrongValueException

In the above example, we use org.zkoss.zk.ui.WrongValueException to denote an error. As depicted, you have to specify the first argument with the component that causes the error, and then the second argument with the error message.

You could throw this exception anytime, such as when an onChange event is received as follows.

<textbox>
    <attribute name="onChange">    
        if (!self.value.equals("good")) {        
            self.value = "try again";            
            throw new WrongValueException(self, "Not a good answer!");            
        }        
    </attribute>    
</textbox>
Custom Way to Display the Error Messages

Instead of the default error box as shown in the previous example, you can provide a custom look by implementing the org.zkoss.zul.CustomConstraint interface with Constraint. CustomConstraint has one method, showCustomError, which is called when an exception is thrown or when the validation is correct. Here is an example,

<window title="Custom Constraint" border="normal">
    <zscript><![CDATA[    
class MyConst implements Constraint, CustomConstraint {
    //Constraint//    
    public void validate(Component comp, Object value) {    
        if (value == null || ((Integer)value).intValue() < 100)        
            throw new WrongValueException(comp, "At least 100 must be specified");            
    }    
    //CustomConstraint//    
    public void showCustomError(Component comp, WrongValueException ex) {    
        errmsg.setValue(ex != null ? ex.getMessage(): "");        
    }    
}
Constraint ctt = new MyConst();
    ]]></zscript>    
    <hbox>    
        Enter a number at least 100:        
        <intbox constraint="${ctt}"/>        
        <label id="errmsg"/>        
    </hbox>    
</window>
Improve Responsiveness

The responsiveness can be improved by validating more constraints at the client. To do this, you have to implement the org.zkoss.zul.ClientConstraint interface with Constraint. If you have done all validations at the client, you can return true for the isClientComplete method, and then there will be no server callback at all.

You can also customize the display of the error message with pure JavaScript codes a the client by providing a function called Validate_errorbox. For example,

<script type="text/javascript"><![CDATA[
    //Running at the browser    
    window.Validate_errorbox = function (id, boxid, msg) {    
        var html = '<div style="display:none;position:absolute" id="'        

+boxid+'">'+zk.encodeXML(msg, true)+'</div>';

            document.body.insertAdjacentHTML("afterbegin", html);return $e(boxid);}            
]]></script>

Note: script specifies the script codes running at the browser, while zscript specifies codes running at the server.

Note: If CustomConstraint is also implemented, ClientConstraint will be ignored since all validations are done at the server. In other words, if you want to use ClientConstraint to improve responsiveness, overriding Validate_errorbox is the only way to customize the display of the error messsage.

The onChange Event

An input control notifies the application with the onChange event if its content is changed by the user.

Notice that, when the onChange's event listener is invoked, the value has been set. Thus, it is too late if you want to reject illegal value in the onChange's event listener, unless you restore the value properly. Rather, it is recommended to use a constraint as described in the Custom Constraints section.

The onChanging event

An input control also notifies the application with the onChanging event, when user is changing the content.

Notice that, when the onChanging's listener is invoked, the value is not set yet. In other worlds, the value property still remain in the old value. To retrieve what the user is entering, you have to access the value property of the event as follows.

<grid>
    <rows>    
        <row>The onChanging textbox:         
            <textbox onChanging="copy.value = event.value"/></row>            
        <row>Instant copy:        
            <textbox id="copy" readonly="true"/></row>            
    </rows>    
</grid>

It is too early if you want to reject illegal value in the onChanging's event listener, because user may not complete the change yet. Rather, it is recommended to use a constraint as described in the Custom Constraints section.