Friday, April 26, 2013

ZK MVVM: Form Binding


Introduction

This article describe how to do Form Binding in ZK MVVM.

The Result

View demo on line
http://screencast.com/t/yAE1f4wTALNr

Pre-request

ZK Basic MVVM Pattern
http://ben-bai.blogspot.tw/2012/12/zk-basic-mvvm-pattern.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.

<zk>
    <!-- 
        tested with ZK 6.0.2
     -->
    <div apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('blog.ben.test.mvvm.formbinding.FormBindingTestVM')">
        <!-- form binding,
            @id('fx') @load(vm.person)
            here the id (fx) is mapping to vm.person

            @save(vm.person, before='savePerson')"
            save to vm.person before savePerson command
            the before/after in @save is required,
            you should always indicate when (before/after a command)
            to save form content

            save to vm.person means
            call vm.getPerson().setFirstName() to save firstName
        -->
        <div form="@id('fx') @load(vm.person) @save(vm.person, before='savePerson')">
            <vlayout>
                <!-- fx.firstName, i.e., vm.person.firstName -->
                <hlayout>
                    <label value="First Name" />
                    <textbox value="@bind(fx.firstName)" />
                </hlayout>
                <hlayout>
                    <label value="Last Name" />
                    <textbox value="@bind(fx.lastName)" />
                </hlayout>
                <hlayout>
                    <label value="Age" />
                    <intbox value="@bind(fx.age)" />
                </hlayout>
            </vlayout>
        </div>
        <!-- click this button will execute savePerson() method in vm
            and trigger save action of the form above -->
        <button label="save" onClick="@command('savePerson')" />
        <!-- show content of person,
            will be updated after savePerson command -->
        <label value="@load(vm.personContent)" />
    </div>
</zk>


FormBindingTestVM.java

Simple vm, contains getter and command

package blog.ben.test.mvvm.formbinding;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
/**
 * tested with ZK 6.0.2
 * @author benbai123
 *
 */
public class FormBindingTestVM {
    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 () {
    }
}


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 > Form Binding
http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/MVVM/Data%20Binding/Form%20Binding

Download

MVVM_FormBinding.zul
https://github.com/benbai123/ZK_Practice/blob/master/Pattern/MVVM/AdvancedMVVM/WebContent/MVVM_FormBinding.zul

FormBindingTestVM.java
https://github.com/benbai123/ZK_Practice/blob/master/Pattern/MVVM/AdvancedMVVM/src/blog/ben/test/mvvm/formbinding/FormBindingTestVM.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.swf

26 comments:

  1. is it possible to customize tab scroll?

    i have a tab pannels which is dynamic tab it may be up to 100.when maximum tab show then it shows tab scroll in tab toolbar.but my requirement is the first tab shows constant and another tab will be scroll in tab toolbar.

    ReplyDelete
    Replies
    1. Yes, it is possible, a simple sample:

      http://zkfiddle.org/sample/3k9t8ee/1-fixed-first-tab

      References:

      Tabs.js

      https://github.com/zkoss/zk/blob/master/zul/src/archive/web/js/zul/tab/Tabs.js

      Delete
    2. No problem, you're welcome.

      Delete
    3. Please help me above code how to implement in java code. fixed tab may be first,second,third it's fully customize tab.

      Delete
    4. do you mean work as the 'frozen' of grid?

      Delete

    5. Just tried it:

      http://zkfiddle.org/sample/37998l0/1-Frozen-Tabs

      Delete
    6. thank you for your help.
      the first solution fine for me but when i create tab with java code then it's not working. we are populate tab in java code according user customization.

      Delete

    7. fixed, refer to the updated bind_ function

      http://zkfiddle.org/sample/37998l0/3-Frozen-Tabs

      Delete
    8. thanks, it's working fine for forzon=1.
      but when i set forzon=2 not working good.
      when i set first tab visible false then forzon= 1 not working.
      when set forzon=2 then 2nd tab not clickble.

      please find updated url

      http://zkfiddle.org/sample/37998l0/4-Frozen-Tabs

      Delete
    9. What is the expected spec here? Should the second tab be the frozen tab when the first tab is invisible and frozen="1"? Or just skip the invisible tabs (i.e., froaen="2" but first tab is invisible, then just frozen second tab)?

      Delete
    10. thanks,
      frozen=1 or foezon=2 working good after first tab inivisible. but which tab coming after fixed tab it should not be disable.

      now check the example and select all tab one by one you will find the issue.
      http://zkfiddle.org/sample/37998l0/4-Frozen-Tabs

      sorry for my bad english.

      Delete

    11. No problem.
      I still cannot understand the spec here.

      Assume there are three tabs, tabOne, tabTwo and tabThree.
      the first tab (tabOne) is invisible (with visible="false")
      and frozen="2"

      Should only second tab (tabTwo) be frozen? Or both tabTwo and tabThree should be frozen?

      Delete
    12. watch this youtube video you can easily find out.

      https://www.youtube.com/watch?v=HrCzhosGDQo

      Delete
    13. The demo video shows the issue that you mentioned above, but what I asked is the specification of your requirement.

      What should it work when there is an invisible tab?
      1.
      Simply ignore it (i.e., make third tab frozen when frozen="2" and one of the first two tabs is invisible),

      or

      2.
      count as a frozen one (i.e., make only one tab frozen when frozen="2" and one of the first two tabs is invisible)?

      Delete
    14. Let me try to explain one more time,When one tab is disable like i did in my code
      Tab tab= new Tab("disable");
      tab.setParent(self);
      tab.setVisible(true);
      then i am getting issue the tab after frozen tab is not clickble or tabs after frozen tab upto some specific area not clickable.You can check this link
      http://zkfiddle.org/sample/37998l0/4-Frozen-Tabs

      Delete
    15. Yes, I can understand this issue that you just described.

      What I do not know is,

      Assume there are three tabs, the first one is invisible, and frozen="2", how many tabs should be frozen? Only second tab or both second and third tabs?

      Delete
    16. I've apply 'count as a frozen one' rule for invisible tab however, refer to

      http://zkfiddle.org/sample/37998l0/5-Frozen-Tabs

      just added this line below before increase faker size
      if (child.style.display != 'none')

      Delete
    17. thank you.it's working fine as per my requirement.

      Delete
    18. once again i need your help Please look this video you will find my issue http://www.youtube.com/watch?v=l1navmKgz_w

      Delete
    19. frozon tab css style when i change different tab case tab not change color. how to fixed it. it's not happen in demo but issue show in my application.

      Delete
    20. You can try to override _scrollcheck function of tabs and fix frozen in it, please refer to the updated sample

      http://zkfiddle.org/sample/37998l0/6-Frozen-Tabs

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi
    Can you please help me in
    http://forum.zkoss.org/question/88929/please-help-me-in-form-binding/

    ReplyDelete