ZK/How-Tos/Component Development

How do develop an expanding grid with a pop-up window to add new rows to the grid
First setup the page that has the grid that you want to expand:

<?page id="main-page"?>  String[][] values = { {"one", "1"} ,{"two","2"} };      $  <![CDATA[ Window win = (Window) Executions.createComponents( "menu-items-popup.zul", null, null); win.doModal; ]]>

There is quite a lot going on there. First off there is a static array called "values". This is simply there to demonstrate that we can use a forEach="${values}" to output a list of rows. Realistically that data would have been pulled from a database. The next thing to notice is that the tag with the id "rows" has a "use" attribute that specifies that a subclass of org.zkoss.zul.Rows is used to implement that xul element. It is in this custom sub-class that we can add a custom method to insert a new row into the grid:

package org.zkforge.ftg;

import org.zkoss.zul.Hbox; import org.zkoss.zul.Label; import org.zkoss.zul.Row; import org.zkoss.zul.Rows; import org.zkoss.zul.Textbox;

public class ExpandingMenuItemRows extends Rows { /* * This is just an arbitrary custom method that we can call from a zscript. * In it we programmatically create all of the elements that appear in the other * rows. The code below simply creates: *   $     * and sets the two value attributes whatever was passed into the method. */ public void addRow(String name, String price){ Label label = new Label; label.setValue(name); Label dollar = new Label; dollar.setValue("$"); Textbox textbox = new Textbox; textbox.setValue(price); Hbox hbox = new Hbox; hbox.appendChild(dollar); hbox.appendChild(textbox); Row row = new Row; row.appendChild(label); row.appendChild(hbox); this.appendChild(row); } }

So if we can get a zscript function to call that method then a new row will be appended into the grid. This logic is in the pop-up window in the file menu-items-popup.zul:

 doAdd(String name, String price){ rows = Path.getComponent("//main-page/food-to-go-delegate/rows"); rows.addRow(name, price); } Name: Price:  

In that model dialogue window we have two textboxes one for the name and one for the price. If the user clicks 'Add' the button calls a zscript function doAdd passing the two textbox values. doAdd then does an IDSpace lookup for the element in the main page. has an id "rows" within the IDSpace of the window with id "food-to-go-delegate" on the page "main-page" which we write out with the syntax "//page/window/id". Once we have a reference our custom sub-class element we just invoke our custom method 'addRow'.

How to access the preference specific to a component
If you want to develop a component that is configurable by zk.xml, then you have to

1) Define a preference name that a deployer can use to configure in WEB-INF/zk.xml. For example,

org.zkoss.zul.Window.defaultActionOnShow moveDown

2) Access it with the getPreference method of the org.zkoss.zk.ui.util.Configuration class.

However, there is one Configuration instance per Web application, and a component can belong to any Web application if ZK libraries (e.g., zk.jar) are shared by several Web applications. Thus, you can access the preference only if a component is attached to a page. A good moment is when the component is rendered. For example,

//Window.java //getOuterAttrs is called when redraw is called public String getOuterAttrs { StringBuffer sb = new StringBuffer.append(super.getOuterAttrs); HTMLs.appendAttribute(sb, "z.aos",		getDesktop.getWebApp.getConfiguration			.getPreference("org.zkoss.zul.Window.defaultActionOnShow")); return sb.toString; }

If you want to provide a static method to set the default (overrides the preference):

public String getOuterAttrs { StringBuffer sb = new StringBuffer.append(super.getOuterAttrs); String aos = getDefaultActionOnShow; if (aos == null) aos = getDesktop.getWebApp.getConfiguration .getPreference("org.zkoss.zul.Window.defaultActionOnShow"); HTMLs.appendAttribute(sb, "z.aos", aos); return sb.toString; } public static String getDefaultActionOnShow { return _daos; }