InputElement"
Line 317: | Line 317: | ||
| <center><tt>onChanging</tt></center> | | <center><tt>onChanging</tt></center> | ||
| '''Event:''' <javadoc>org.zkoss.zk.ui.event.InputEvent</javadoc> | | '''Event:''' <javadoc>org.zkoss.zk.ui.event.InputEvent</javadoc> | ||
− | Denotes that user is changing the content of an input component. Notice that the component's content (at the server) won't be changed until <tt>onChange</tt> is received. Thus, you have to invoke the <tt>getValue </tt> | + | Denotes that user is changing the content of an input component. Notice that the component's content (at the server) won't be changed until <tt>onChange</tt> is received. Thus, you have to invoke the <tt>InputEvent.getValue()</tt> to retrieve the changed value. |
|- | |- | ||
| <center><tt>onSelection</tt></center> | | <center><tt>onSelection</tt></center> | ||
Line 329: | Line 329: | ||
| <center><tt>onBlur</tt></center> | | <center><tt>onBlur</tt></center> | ||
| '''Event:''' <javadoc>org.zkoss.zk.ui.event.Event</javadoc> | | '''Event:''' <javadoc>org.zkoss.zk.ui.event.Event</javadoc> | ||
− | Denotes when a component loses the focus. Remember event listeners execute at the server, so the focus at the client might be changed when the | + | Denotes when a component loses the focus. Remember event listeners execute at the server, so the focus at the client might be already changed when executing the <tt>onBlur</tt> listener. |
|- | |- | ||
| <center><tt>onError</tt></center> | | <center><tt>onError</tt></center> |
Revision as of 03:20, 26 March 2021
Input Element
- Demonstration: N/A
- Java API: InputElement
- JavaScript API: InputWidget
Employment/Purpose
InputElement is a super class for components which prove user key input, such as textbox, intbox, decimalbox, doublebox, datebox, timebox, spinner, combobox, and bandbox.
Some features are implemented in this class, such as constraint, disabled, maxlength, name, readonly, and so on.
You should not use this class directly, please use the inherited class.
Example
<grid>
<rows>
<row>
UserName <textbox value="Jerry" width="150px" />
</row>
<row>
Password <textbox type="password" value="foo" width="150px" />
</row>
<row>
Phone: <intbox constraint="no negative,no zero" width="150px" value="12345678" />
</row>
<row>
Weight: <decimalbox format="###.##" value="154.32" width="150px" />
</row>
<row>
Birthday: <datebox id="db" width="150px" />
</row>
<row>
E-mail:
<textbox width="150px" value="zk@zkoss.org"
constraint="/.+@.+\.[a-z]+/: Please enter an e-mail address" />
</row>
</rows>
</grid>
Validation
There are two ways to validate the value entered by an user: implementing Constraint or throwing WrongValueException.
Constraint
An input element can be associated with a constraint (Constraint) to validate the value entered by an user. There is a default implementation called SimpleConstraint that can handle many conditions. If it is not enough, you can implement your own constraint, or throwing WrongValueException as described in the next sections.
Built-in Constraints
To use the default constraint, you could specify a list of conditions in InputElement.setConstraint(String), such as no positive and no empty. For example,
<textbox constraint="no empty"/>
<intbox constraint="no negative,no zero"/>
Condition | Description |
---|---|
no empty | Empty is not allowed. |
no future | Date in the future is not allowed. |
no negative | Negative numbers are not allowed. |
no past | Date in the past is not allowed. |
no positive | Postive numbers are not allowed. |
no today | Today is not allowed. |
no zero | Zero numbers are not allowed. |
between yyyyMMdd and yyyyMMdd | Date only allowed between the specified range. The format must be yyyyMMdd, such as
<datebox constraint="between 20071225 and 20071203"/>
|
after yyyyMMdd | Date only allowed after (and including) the specified date. The format must be yyyyMMdd, such as
<datebox constraint="after 20071225"/>
|
before yyyyMMdd | Date only allowed before (and including) the specified date. The format must be yyyyMMdd, such as
<datebox constraint="before 20071225"/>
|
end_before end_after after_start after_end ... |
Specifies the position of the error box. Please refer to Popup for all allowed position.
<textbox constraint="no empty, end_after"/>
<textbox constraint="no empty, start_before"/>
|
Regular Expression
To specify a regular expression, you could have to use / to enclose the regular expression as follows.
<textbox constraint="/.+@.+\.[a-z]+/"/>
Notice that the above statement is XML, so do not use \\ to specify a backslash. On the other hand, it is required, if writing in Java:
new Textbox().setContraint("/.+@.+\\.[a-z]+/");
Multiple Constraints
Notice that it is allowed to mix regular expression with other constraints by separating them with a comma.
If 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"/>
of course, it supports multiple custom messages
<intbox constraint="no negative: forbid negative, no positive: forbid positive" />
i18n Error Message
To support multilingual, you could use the l function as depicted in ZK Developer's Reference.
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<textbox constraint="/.+@.+\.[a-z]+/: ${c:l('err.email.required')}"/>
Escape a Comma
If you want to write a longer sentence with comma separator, you can enclose your customized sentence with curly braces.
[Since 8.0.0]
<textbox constraint="no empty: {Sorry, no empty allowed}, /.+@.+\.[a-z]+/: email only"></textbox>
Scrollable Error Messag
If you want to move an error message box by scrolling, please use data-scrollable attribute.
Custom Constraint
If you want a custom constraint, you could implement Constraint and specify it in the constraint property (InputElement.setConstraint(Constraint)).
public class EvenNumberConstraint implements Constraint {
public void validate(Component comp, Object value) throws WrongValueException {
if (value != null && new Integer(value.toString()).intValue() % 2 == 1)
throw new WrongValueException(comp, "Only even numbers are allowed, not "+value);
}
}
- Line 4: If the validation fails, just throw WrongValue. Notice that you have to specify which component causes the exception.
To specify it to the constraint property, you have to instantiate it first by use of the new function as shown below
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<textbox constraint="${c:new('foo.EventNumberConstraint')}"/>
Display Error Message in Custom Way
Instead of the default error box, you could provide a custom approach by implementing CustomConstraint (with Constraint). Then, CustomConstraint.showCustomError(Component, WrongValueException) will be invoked when an exception is caught. For 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>
<hlayout>
Enter a number at least 100:
<intbox constraint="${ctt}" />
<label id="errmsg" />
</hlayout>
</window>
And, here is the result
Validate at Client for Better Responsiveness
Responsiveness could be improved by validating more constraints at the client side[1]. To do it, you have to implement ClientConstraint (with Constraint).
- ↑ The default constraint (SimpleConstraint) validates all constraints at the client side
WrongValueException
In addition to throwing WrongValueException in Constraint.validate(Component, Object), you can throw WrongValueException in other situations. For example, you can validate the user name and password when the user presses the login button. For example,
public class FooComposer extends SelectorComposer {
@Wire
private Textbox username;
@Wire
private Textbox password;
@Listen("onClick = #login")
public void doLogin() {
username.clearErrorMessage(); //important to clear the previous error, if any
if (examine(username, password)) {
//success
} else {
throw new WrongValueException(username, "Not a valid username or password. Please retry.");
}
}
}
However, notice that you have to clear the error message manually by invoking InputElement.clearErrorMessage(). Otherwise, the error message will remain there unless Textbox.setValue(String) is called.
Properties
Inplace
All input elements can have the in-place-editing functionality, like the combobox, textbox, datebox, and so on.
<grid width="500px">
<rows>
<row>
Textbox:
<textbox inplace="true" value="Click me" />
</row>
<row>
Combobox:
<combobox inplace="true" value="Click me" />
</row>
</rows>
</grid>
Instant
since 6.0.0
When the instant mode is on, the onChange event will be fired as soon as possible as a user is typing in the input (like onChanging event). The value will also be updated to the component (server-side) immediately. Notice that it would automatically synchronize the value (including format) in the client and server. If you want to do something in the server while changing the value, please use onChanging event.
Placeholder
since 6.5.0
ZK 6.5 introduces support for HTML5 placeholder text, a very useful feature for telling users what they should enter in a textbox. This is a widely regarded UI pattern.
The following image and code show the look of the placeholder as well as the code to replicate it.
<textbox placeholder="Please type some text" />
InputAttributes
since 8.6.1
The feature is available since 8.6.1. All input elements can set some additional attributes to the input html tag in the component. The inputAttributes can take a Map with attribute names as the keys or a String separate by ";" and follow the name=value rule.
<bandbox inputAttributes="${map}"></bandbox>
<datebox inputAttributes="autocorrect=off;spellcheck=ture"></datebox>
Supported Events
Event: InputEvent
Denotes the content of an input component has been modified by the user. | |
Event: InputEvent
Denotes that user is changing the content of an input component. Notice that the component's content (at the server) won't be changed until onChange is received. Thus, you have to invoke the InputEvent.getValue() to retrieve the changed value. | |
Event: SelectionEvent
Denotes that user is selecting a portion of the text of an input component. You can retrieve the start and end position of the selected text by use of the getStart and getEnd methods. | |
Event: Event
Denotes when a component gets the focus. Remember event listeners execute at the server, so the focus at the client might be changed when the event listener for onFocus got executed. | |
Event: Event
Denotes when a component loses the focus. Remember event listeners execute at the server, so the focus at the client might be already changed when executing the onBlur listener. | |
Event: ErrorEvent
Denotes when a component caused a validation error. |
Supported Children
*None
Use cases
Version | Description | Example Location |
---|---|---|
Browser Limitations
Browser | description |
---|---|
iOS Safari / Chrome |
<textbox id="test"/>
<button label="java focus (no keyboard)" onClick="test.focus()"></button>
<button xmlns:w="client" label="client focus" w:onClick="zk.Widget.$('$test').focus();"></button>
In mobile Safari, the user must explicitly tap the elements in the web view to display the keyboard. |
Version History
Version | Date | Content |
---|---|---|
5.0.8 | June, 2011 | Allow user to specify the position of error-box |
6.0.0 | Sep, 2011 | Add instant mode, which sends onChange event and update value to component as soon as possible. |
6.5.0 | Sep, 2012 | Support HTML5 placeholder attribute for input elements |
8.5.2 | May, 2018 | ZK-3774: focus() doesn't work on mobile device |
8.6.1 | Jan, 2019 | ZK-4111: Add autocorrect and spellcheck DOM attributes toggles to input-based components |