Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

 1. Lets start off by getting a delegator and using it to list all the Person entities - we will store the result in a variable.  The code should be pretty self evident, it is simply beanshell, using familiar OFBiz API classes.  The interesting bit is in the screen, where we use the special forEach attribute to iterate all the Persons and make a dropdown list from them.  We can access fields on the each iterator variable (in ZK it is always called each) with the Expression Language DOT notation.   And finally, see how we use the value attribute of each listitem, to hold a reference to the Person - not its PK but the GenericValue object itself.  This will come in handy in the next step.

Code Block
 <?page title="Incredible Browser"?>

<window title="Incredible Window">
 <zscript>
  import org.ofbiz.entity.GenericDelegator;

  delegator = GenericDelegator.getGenericDelegator("default");
  persons = delegator.findAll("Person");
 </zscript>
  <listbox mold="select">  <!-- mold: select means a dropdown list -->
   <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>
  </listbox>
</window>

...

3. Finally, lets add a Save button and make it do something.  Note how we dynamically update the person's name on the list, too.  All ZK UI components can be dynamically manipulated via beanshell or Java in this way.

Code Block

 

Part 3: Integration with OFBiz backend - via Spring


 <?page title="Incredible Browser"?>

<window title="Incredible Window" width="500px">
 <zscript>
  import org.ofbiz.entity.GenericDelegator;

  delegator = GenericDelegator.getGenericDelegator("default");
  persons = delegator.findAll("Person");

  selectPerson(person)
  {
	//populate the edit form
	firstName.value = person.getString("firstName");
	lastName.value = person.getString("lastName");

	//and make it visible
	editRow.visible = true;
  }

  savePerson()
  {
	person = personList.selectedItem.value;    //get the person object from the list
	person.set("firstName", firstName.value);  //update its firstName based on the textbox
	person.store();                            //ask the entity engine to store it
	personList.selectedItem.label = person.getString("firstName") + " " + person.getString("lastName");
  }
 </zscript>
 <grid>
  <rows>
   <row spans="1,2"> <!-- spans distributes the colspans of the first grid row, since it only has 2 things -->
	Select the person you wish to edit
    <listbox id="personList" mold="select" onSelect="selectPerson(self.selectedItem.value)">
	 <listitem value="--- SELECT BELOW ---"/>
     <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>
    </listbox>
   </row>
   <row id="editRow" visible="false">
	<textbox id="firstName"/><label id="lastName"/><button label="Save" onClick="savePerson()"/>
   </row>
  </rows>
 </grid>
</window>

4. Imagine you have several pages, and they all use the delegator.  It is very simple to factor out the preparation work into a separate script.  By convention it has the .zs (ZScript) extension, but by default it simply contains plain ol' beanshell.  In our ZUL page we then include it with another zscript tag.  In the example below, my .zs is in the same directory as my ZUL, but you can put it anywhere in the webapp and reference it by a context-relative path starting with /   .

setup.zs

Code Block

 import org.ofbiz.entity.GenericDelegator;

delegator = GenericDelegator.getGenericDelegator("default");

ZUL page

Code Block

<?page title="Incredible Browser"?>

<window title="Incredible Window" width="500px">
 <zscript src="setup.zs"/> <!-- import the script, within the scope of the window -->
 <zscript>
  persons = delegator.findAll("Person");

  selectPerson(person)
  {
	//populate the edit form
	firstName.value = person.getString("firstName");
	lastName.value = person.getString("lastName");

	//and make it visible
	editRow.visible = true;
  }

  savePerson()
  {
	person = personList.selectedItem.value;    //get the person object from the list
	person.set("firstName", firstName.value);  //update its firstName based on the textbox
	person.store();                            //ask the entity engine to store it
	personList.selectedItem.label = person.getString("firstName") + " " + person.getString("lastName");
  }
 </zscript>
 <grid>
  <rows>
   <row spans="1,2"> <!-- spans distributes the colspans of the first grid row, since it only has 2 things -->
	Select the person you wish to edit
    <listbox id="personList" mold="select" onSelect="selectPerson(self.selectedItem.value)">
	 <listitem value="--- SELECT BELOW ---"/>
     <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>
    </listbox>
   </row>
   <row id="editRow" visible="false">
	<textbox id="firstName"/><label id="lastName"/><button label="Save" onClick="savePerson()"/>
   </row>
  </rows>
 </grid>
</window>

Part 3: Integration with OFBiz backend - via Spring

In my firm, we actually use another layer of Spring managed helper objects in between the ZUL pages and the OFBiz entity and service engines.  This makes for easier unit testing, reuse, and less beanshell code in our pages. 

TODO: WRITE UP THIS PART TODO:

Part 4: Considerations when using ZK in production

...