Skip to main content

Data model manipulation

The data model can be manipulated directly using the JXPathContext interface or indirectly through components, Whenever the user changes the contents of a ZK component, which is bound to a data model object, the change is propagated to the model, which in turn, propagates it to any ZK component that is bound to the modified data model object.

To ease data manipulation, the listbox object, has two new methods: addNew and delete. The first one creates a new object in the data model, and therefore in the listbox, while the second one removes it from the list and the model. Additionally, the autocommit attribute determines whether listbox will try to perform a commit the data model each time the user changes the selected item.

Alternatively, the data model can be directly manipulated through a Apache's commons-JXPath derived package. Every data source component (including datamodel and lisbox) contains a JXPathContext. Through this context JXPath invocations can be made, usign getValue, setValue, removePath or createPath methods. For more information about JXPath use, please review the available docs at: http://jakarta.apache.org/commons/jxpath/

Mind that the components will be notified of any change made through JXPath API, but the won't be noticed of any change made directly to the underlying data model. On the undesirable case underlying data objects are modified directly, you can force the components to be notified by getting a Pointer to the modified object and calling the invalidate method on it. 

As an example, the following example shows how to delete a city or ad a new one to the data model:

<?xml version="1.0" encoding="UTF-8"?>
<?page title="ZKIB Demo" ?>
<zk>
    <xmldatasource id="mydata" src="/my-data.xml" />
        <vbox>
        <form dataPath="/mydata:/title">
            <label bind="@name"/>
            <textbox bind="@name"/>
        </form>
        <listbox id="countries" dataPath="/mydata:/country">
            <listhead>
                <listheader label="Abbr" />
                <listheader label="Name"/>
            </listhead>
            <dataitem bind="@abbreviation">
                <listcell bind="@abbreviation" />
                <listcell bind="@name" />
            </dataitem>
        </listbox>
        <hbox>
            <label value="Active country:"/>
            <textbox bind="/countries:/@name"/>
        </hbox>
        <grid dataPath="/countries:/city">
            <columns>
                <column label="City"/>
                <column/>
            </columns>
            <datarow>
                <label bind="@name" />
                <image src="/img/remove.gif">
                    <attribute name="onClick">
                        row = self.parent;
                        ctx = row.dataSource.jXPathContext;
                        ctx.removePath(row.xPath);
                        ctx.getPointer("/").invalidate();
                    </attribute>
                </image>
            </datarow>
        </grid>                      
        <button label="Add City">
            <attribute name="onClick">
                ctx = countries.jXPathContext;
                pointer = ctx.createPath("/city[count(/city)+1]");
                ctx2 = ctx.getRelativeContext(pointer);
                ctx2.createPath("/@name").setValue("London");
                ctx.getPointer("/").invalidate();
            </attribute>
        </button>
    </vbox>
</zk>