Processing...
Description & Source Code

In this demo we'll cover some common uses of input components that accepts text, numbers, and date. We'll see how they can be initialised with their controller's variables, and how to utilise their default formatting and constraint checking features.


Access Controller's Variables in View

We may access variables in the controller from view by the use of an EL Expression: ${expression} . The implicit variable win$composer is a reference to the controller which was assigned to the Window component with the ID: win. For instance, to assign the component attribute value with the property title of an inventoryItem instance in the controller, we write value="${win$composer.inventoryItem.title}".


Textbox

The content of a Textbox is accessible through its value attribute. Developers may impose constraints on the data it accepts by specifying its constraint attribute. For instance,constraint="no empty" indicates that user must not leave the Textbox blank.

<textbox id="titleTextbox" value="${win$composer.inventoryItem.title}" constraint="no empty" />

An onChange event is fired when content of theTextbox's modified. Every input component's getValue() method returns its corresponding type. For example, Textbox returns String , and Intbox returns Integer .

public class EditController ...{
	@Wire
	private Textbox titleTextbox;
	
	@Listen("onChange = #titleTextbox")
	public void changeTitle() {
		String title = titleTextbox.getValue();
		...
	}
}

Datebox

Datebox allows users to input date and time in a specific format. User input can then be retrieved as a Date object. Date format and constraint can be configured through their respective component attributes. The Timebox component can serve as an alternative to Datebox whenever only hour and minute parameters are relevant. Like other input components, an onChange event is triggered when the value is changed in Datebox and Timebox. Similarly, the updated value can be obtained using the getValue() method.

<datebox id="createdDatebox" value="${win$composer.inventoryItem.createdDate}"
		format="yyyy/MM/dd" constraint="no empty" />

Intbox and Doublebox

As their names suggest, Intbox accepts integer values while Doublebox accepts decimal numbers; both support the format and constraint attributes. As with other input components, the method getValue() is called to retrieve the component's current value and an onChange event is fired whenever the value's modified.

<intbox id="barcodeIntbox" value="${win$composer.inventoryItem.barcode}"
	format="000000" constraint="no empty,no negative" />
<doublebox id="unitPriceDoublebox" value="${win$composer.inventoryItem.unitPrice}"
	format=",###.#" constraint="no empty,no negative" />

Spinner

Spinner is similar to Intbox but allows users to choose from a range of values. It provides two buttons to increase or decrease the current value. It also supports the onChange event and the getValue() method.

<spinner id="quantitySpinner" value="${win$composer.inventoryItem.quantity}"
	format=",###" constraint="no empty,min 0" />

In Place Editing

Almost every input component supports in place editing . This feature renders input components like ordinary labels until the input component's selected, which the components would then morph back into the appearance of usual input component with boxed borders. To enable in place editing, we assign inplace="true" to an input component.

<textbox id="locationTextbox" value="${win$composer.inventoryItem.location}" inplace="true" />

Please follow this link to view the complete list of input components available in ZK.

demo.zul
<window id="win" title="Car Inventory Editor" width="400px" border="normal"
	apply="demo.getting_started.input.EditController">
	<grid>
		<rows>
			<row>
				Title:
				<textbox id="titleTextbox" value="${win$composer.inventoryItem.title}"
					constraint="no empty" />
			</row>
			<row>
				Created Date (yyyy/MM/dd):
				<datebox id="createdDatebox" value="${win$composer.inventoryItem.createdDate}"
					format="yyyy/MM/dd" constraint="no empty" />
			</row>
			<row>
				Bar Code:
				<intbox id="barcodeIntbox" value="${win$composer.inventoryItem.barcode}"
					format="000000" constraint="no empty,no negative" />
			</row>
			<row>
				Unit Price:
				<doublebox id="unitPriceDoublebox" value="${win$composer.inventoryItem.unitPrice}"
					format=",###.#" constraint="no empty,no negative" />
			</row>
			<row>
				Quantity:
				<spinner id="quantitySpinner" value="${win$composer.inventoryItem.quantity}"
					format=",###" constraint="no empty,min 0" />
			</row>
			<row>
				Location (click location to edit):
				<textbox id="locationTextbox" value="${win$composer.inventoryItem.location}"
					inplace="true" />
			</row>
		</rows>
	</grid>
	<button id="submitButton" label="Submit" />
</window>
EditController.java
package demo.getting_started.input;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Doublebox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Spinner;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;
import demo.getting_started.CarService;
import demo.getting_started.CarServiceImpl;
import demo.getting_started.InventoryItem;

public class EditController extends SelectorComposer<Component> {
	private static final long serialVersionUID = 1L;

	private CarService carService = new CarServiceImpl();
	private InventoryItem inventoryItem = new InventoryItem("1", "The Tumbler", new Date(), 654321, 29999.9,
			30, "Southern Depository");
	@Wire
	private Window win;
	@Wire
	private Textbox titleTextbox;
	@Wire
	private Datebox createdDatebox;
	@Wire
	private Intbox barcodeIntbox;
	@Wire
	private Doublebox unitPriceDoublebox;
	@Wire
	private Spinner quantitySpinner;
	@Wire
	private Textbox locationTextbox;

	public InventoryItem getInventoryItem() {
		return inventoryItem;
	}

	@Listen("onChange = #titleTextbox")
	public void changeTitle() {
		String title = titleTextbox.getValue();
		inventoryItem.setTitle(title);

		showNotify("Changed to: " + title, titleTextbox);
	}

	@Listen("onChange = #createdDatebox")
	public void changeCreatedDate() {
		Date createdDate = createdDatebox.getValue();
		inventoryItem.setCreatedDate(createdDate);
		DateFormat formatter = new SimpleDateFormat(createdDatebox.getFormat());

		showNotify("Changed to: " + formatter.format(createdDate), createdDatebox);
	}

	@Listen("onChange = #barcodeIntbox")
	public void changeBarcode() {
		Integer barcode = barcodeIntbox.getValue();
		inventoryItem.setBarcode(barcode);
		NumberFormat formatter = new DecimalFormat(barcodeIntbox.getFormat());

		showNotify("Changed to: " + formatter.format(barcode), barcodeIntbox);
	}

	@Listen("onChange = #unitPriceDoublebox")
	public void changeUnitPrice() {
		Double unitPrice = unitPriceDoublebox.getValue();
		inventoryItem.setUnitPrice(unitPrice);
		NumberFormat formatter = new DecimalFormat(unitPriceDoublebox.getFormat());

		showNotify("Changed to: " + formatter.format(unitPrice), unitPriceDoublebox);
	}

	@Listen("onChange = #quantitySpinner")
	public void changeQuantity() {
		Integer quantity = quantitySpinner.getValue();
		inventoryItem.setQuantity(quantity);
		NumberFormat formatter = new DecimalFormat(quantitySpinner.getFormat());

		showNotify("Changed to: " + formatter.format(quantity), quantitySpinner);
	}

	@Listen("onChange = #locationTextbox")
	public void changeLocation() {
		String location = locationTextbox.getValue();
		inventoryItem.setLocation(location);

		showNotify("Changed to:" + location, locationTextbox);
	}

	@Listen("onClick = #submitButton")
	public void submit() {
		carService.store(inventoryItem);

		showNotify("Saved", win);
	}

	private void showNotify(String msg, Component ref) {
		Clients.showNotification(msg, "info", ref, "end_center", 2000);
	}
}
CarService.java
package demo.getting_started;

import java.util.List;

public interface CarService {

	/**
	 * Retrieve all cars in the car store.
	 * @return all cars.
	 */
	public List<Car> findAll();

	/**
	 * Store or modify a car in car store.
	 */
	void store(Car car);

	/**
	 * Store or modify a inventory item in car store.
	 */
	void store(InventoryItem inventoryItem);

	/**
	 * Order cars.
	 */
	void order(List<OrderItem> orderItems);

	/**
	 * Retrieve the root of car categories.
	 */
	Category getCarCategoriesRoot();

	/**
	 * Count cars by filter.
	 */
	int countByFilter(String filter);

	/**
	 * Query cars by filter.
	 */
	List<Car> queryByFilter(String filter);
}
InventoryItem.java
package demo.getting_started;

import java.util.Date;

public class InventoryItem {

	private String inventoryId;
	private String title;
	private Date createdDate;
	private int barcode;
	private double unitPrice;
	private int quantity;
	private String location;

	public InventoryItem(String inventoryId, String title, Date createdDate, int barcode, double unitPrice, int quantity, String location) {
		this.inventoryId = inventoryId;
		this.title = title;
		this.createdDate = createdDate;
		this.barcode = barcode;
		this.unitPrice = unitPrice;
		this.quantity = quantity;
		this.location = location;
	}

	public String getInventoryId() {
		return inventoryId;
	}

	public void setInventoryId(String inventoryId) {
		this.inventoryId = inventoryId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

	public int getBarcode() {
		return barcode;
	}

	public void setBarcode(int barcode) {
		this.barcode = barcode;
	}

	public double getUnitPrice() {
		return unitPrice;
	}

	public void setUnitPrice(double unitPrice) {
		this.unitPrice = unitPrice;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

}