Foreword

This small talk will introduce a feature of ZK MVVM called form binding. This feature will be demonstrated by rewriting the example application in the article: MVVM in ZK 6 - Design CRUD page by MVVM pattern. We suggest you to read the previous article first for better understanding.

The “Property binding” resort saves user input to a property right after a component fires an onChange event (Users change cursor’s focus to another component). So the user input is validated immediately for single field but not validated when clicking the “Save” button

Validation after focus change in property binding

The “save before command” resort solves some issues which are caused by property binding, for example, saving a new item with invalid value. Since saving before a command invokes validators before executing a command, if validation fails, it does not save the invalid value into a property. However, at the same time, we also lose immediate validation on single field feature which means that if users enter an invalid quantity value e.g. zero, they won't get an error message immediately when they continue to fill in the next field.

Validation before a command in property binding

So now what we need is a mechanism that is able to validate input twice at different time frames. One is when users finish typing their input and the other is when users click the ‘save’ button. By choosing one of the two resorts above cannot solve our problem, because each of them only validates once at a particular moment i.e. the moment of saving input into properties.

Save value directly to the bean - might mislead users that an item is persisted

No immediate validation of single fields after users' input

Lengthy syntax to write for each component

Using Form Binding – Introduction to a Middle Object

It seems that we can’t have our cake and eat it too, really? Like Barack Obama said: “Yes we can”. With ZK MVVM form binding, you can have the cake and eat it too! Using form binding, we can validate single fields immediately after users enter the value and then validate once again when users click the “Save” button to batch save.

Line 5: To use form binding, we annotate “form” attribute of the groupbox with @id(‘fx’) .

Line 18,21,27,31,34,40: fx represents the loaded object which is vm.selected in this case. Developers can treat fx as a middle object which contains duplicated properties of the original object vm.selected and plays a role like a cache. Before clicking button to execute the ‘saveOrder’ command, ZK saves the input data into the middle object fx instead of real target object vm.selected .

To gain batch saving feature, simply specify the command in @save() to before=‘saveOrder’. With this feature, a ‘’command’’ must be specified to @save(), either before='saveOrder' or after='saveOrder'

Note that when you are not using “form binding”, you can choose whether or not to rely on a ‘command’ to execute the saving process.

But the issue is, expressions like @save(vm.selected.description,before='saveOrder') lacks the ability to validate single fields right after users’ input. Validation is performed only when the binder tries to save the input value into a bean’s property. On the other hand, specifying expressions like @save(vm.selected.description,before='saveOrder') on each input component doesn’t save value immediately after users change focus (onChange event fires), thus no validation occurs. Hence, after we remove the before = 'a-command' expression from each input component, the input data are now saved to properties of fx, the middle object, as an onChange event fires. So every time after users inputs data in a field and changes the focus, ZK saves the value immediately into the middle object thus invoking the validation of that field and as a result achieves immediate validation of a single field.

The interaction among ZUL, middle object, and the target object is illustrated below:

The arrow indicates the data flow, it flows to its target when a particular event fires.

"Form binding" is a very convenient form of databinding if a developer wishes to keep the domain object from dirty (unconfirmed) data and to store temporary user input before user confirmation (i.e. by clicking a button). It saves users’ modification in a middle object i.e. 'fx' without affecting the real target object. When users confirm by clicking the save button (or executing a command abstractly), it saves those data into the real target object. If users cancels their modification, there is also no need for developers to clear the dirty data from target object thus reducing maintenance burden.

Form Validator – Validate upon Multiple Fields

After the expression before='saveOrder' has been removed from each input component, the original shipping date validator will no longer work as the following code will also be modified:

OrderVM2.java

Date creation = (Date)ctx.getProperties("creationDate")[0].getValue()

ValidationContext no longer contains “creationDate” property as it is now not saved by the command.

In order to get multiple properties’ value, we have to specify shipping date validator as the form’s validator and change the implementation.

The method of getting main property, ctx.getProperty().getValue() , return a Form object instead of a specific property.

Form Dirty Status: Indicate Modification Status

It’s a common requirement for users to know that whether they have modified a form’s data (dirty status) or not, developers therefore adds a feature that would remind users of this with an UI effect. For example, some text editors appends a star symbol ‘*’ on the title bar to remind users of modified text file. "Form binding" preserves the dirty status in an internal variable which we will talk about in the next section.