Introduction
This article describe how to use Validator with Form Binding in ZK MVVM.
The Result
View demo on line
http://screencast.com/t/caPtmte73J
Pre-request
ZK MVVM: Form Binding
http://ben-bai.blogspot.tw/2013/04/zk-mvvm-form-binding.html
The Program
MVVM_FormBinding.zul
The inner div bind to vm.person, i.e., use vm.person as a form object. It will save form content before savePerson command and use vm.formValidator as the validator to do validation of form fields.
The validator will store error message in validationMessages map with the specified id 'vmsgs'
<zk>
<!--
tested with ZK 6.0.2
validationMessages="@id('vmsgs')"
means all validation message will be stored in a map
that mapped by the id 'vmsgs'
i.e., you can get messages from that map by
@bind(vmsgs['keyOfMessageContent'])
-->
<div apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('blog.ben.test.mvvm.formbinding.FormBindingWithValidatorTestVM')"
validationMessages="@id('vmsgs')">
<!--
@validator(vm.formValidator)
do validation before save form with this validator
-->
<div form="@id('fx') @load(vm.person) @save(vm.person, before='savePerson') @validator(vm.formValidator)">
<vlayout>
<hlayout>
<label value="First Name" />
<textbox value="@bind(fx.firstName)" />
<!--
@bind(vmsgs['firstNameContentError'])
show error message of the key 'firstNameContentError' in
vmsgs map after form validation as needed
-->
<label value="@bind(vmsgs['firstNameContentError'])" style="color: red;" />
<label value="@bind(vmsgs['firstNameError'])" style="color: red;" />
</hlayout>
<hlayout>
<label value="Last Name" />
<textbox value="@bind(fx.lastName)" />
<label value="@bind(vmsgs['lastNameContentError'])" style="color: red;" />
<label value="@bind(vmsgs['lastNameError'])" style="color: red;" />
</hlayout>
<hlayout>
<label value="Age" />
<intbox value="@bind(fx.age)" />
<label value="@bind(vmsgs['ageContentError'])" style="color: red;" />
<label value="@bind(vmsgs['ageTooSmallError'])" style="color: red;" />
<label value="@bind(vmsgs['ageTooLargeError'])" style="color: red;" />
</hlayout>
</vlayout>
</div>
<button label="save" onClick="@command('savePerson')" />
<label value="@load(vm.personContent)" />
</div>
</zk>
FormBindingTestVM.java
Simple vm, contains getter, command and a validator
package blog.ben.test.mvvm.formbinding;
import org.zkoss.bind.ValidationContext;
import org.zkoss.bind.Validator;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.bind.validator.AbstractValidator;
/**
* tested with ZK 6.0.2
* @author benbai123
*
*/
public class FormBindingWithValidatorTestVM {
private Person _person;
public Person getPerson () {
if (_person == null) {
_person = new Person("Ben", "Bai", 123); // fake
}
return _person;
}
public String getPersonContent () {
return _person.getFirstName() + " " + _person.getLastName() + ", age = " + _person.getAge();
}
/**
* empty function as a command for
* save in form binding and update personContent
*/
@Command
@NotifyChange("personContent")
public void savePerson () {
}
/**
* get the validator that will do validation while save
* @return
*/
public Validator getFormValidator(){
return new AbstractValidator() {
public void validate(ValidationContext ctx) {
// get value from form context,
// ctx.getProperties("firstName")[0].getValue() will
// get the value that bind with @bind(fx.firstName)
// in zul page
String firstName = (String)ctx.getProperties("firstName")[0].getValue();
String lastName = (String)ctx.getProperties("lastName")[0].getValue();
Integer age = (Integer)ctx.getProperties("age")[0].getValue();
if (firstName == null || firstName.isEmpty()) {
// put error message into validationMessages map
addInvalidMessage(ctx, "firstNameContentError", "firstName is required ");
} else if (firstName.length() < 3) {
addInvalidMessage(ctx, "firstNameError", "firstName at least 3 chars ");
}
if (lastName == null || lastName.isEmpty()) {
addInvalidMessage(ctx, "lastNameContentError", "lastName is required");
} else if (lastName.length() < 3) {
addInvalidMessage(ctx, "lastNameError", "lastName at least 3 chars ");
}
if (age == null) {
addInvalidMessage(ctx, "ageContentError", "age is required");
} else {
if (age < 0) {
addInvalidMessage(ctx, "ageTooSmallError", "age should not be negative");
}
if (age > 130) {
addInvalidMessage(ctx, "ageTooLargeError", "age should smaller than 130");
}
}
}
};
}
}
Person.java
Simple pojo contains data of a person
package blog.ben.test.mvvm.formbinding;
public class Person {
String _firstName;
String _lastName;
Integer _age;
public Person (String firstName, String lastName, Integer age) {
_firstName = firstName;
_lastName = lastName;
_age = age;
}
public void setFirstName (String firstName) {
_firstName = firstName;
}
public void setLastName (String lastName) {
_lastName = lastName;
}
public void setAge (int age) {
_age = age;
}
public String getFirstName () {
return _firstName;
}
public String getLastName () {
return _lastName;
}
public Integer getAge () {
return _age;
}
}
Reference
MVVM > Data Binding > Validator
http://books.zkoss.org/wiki/ZK_Developer's_Reference/MVVM/Data_Binding/Validator
Download
MVVM_FormBinding_with_Validator.zul
https://github.com/benbai123/ZK_Practice/blob/master/Pattern/MVVM/AdvancedMVVM/WebContent/MVVM_FormBinding_with_Validator.zul
FormBindingWithValidatorTestVM.java
https://github.com/benbai123/ZK_Practice/blob/master/Pattern/MVVM/AdvancedMVVM/src/blog/ben/test/mvvm/formbinding/FormBindingWithValidatorTestVM.java
Person.java
https://github.com/benbai123/ZK_Practice/blob/master/Pattern/MVVM/AdvancedMVVM/src/blog/ben/test/mvvm/formbinding/Person.java
Demo Flash
https://github.com/benbai123/ZK_Practice/blob/master/demo_src/swf/Pattern/MVVM/MVVM_FormBinding_with_Validator.swf
No comments:
Post a Comment