Ajax without JavaScript

Tutorial - Introducing ZK - Part 2

      

Controller & databinding

This section provides a step by step guide of the Controller and its functions. The controller handles all the business logic of the application and responds to events fired from the user interface. Currently our sample application includes add, update and delete events for both the employees and the departments.

Defining a Controller

To create a controller the class org.zkoss.zk.ui.util.GenericForwardComposer should be extended. An example controller is shown in Figure 3. The composer then needs to be associated with a relevant view. Previously, the usage of apply was touched upon in Nesting ZK Components. In the following section the relationship is outlined in more detail.

Figure 3: Example Controller

 

public class EmployeeController extends GenericForwardComposer {

  /**
   * 
   */
  private static final long serialVersionUID = -9089818718875587898L;

}

 

Associating the Controller with the view

To implement the interaction between the View and Controller, data binding is used in this example. To implement data binding, the apply attribute of a component has to be set. Most components support the apply attribute. Figure 4 demonstrates the usage of the apply attribute. The EmployeeController is responsible for handling the user flow. The code of the EmployeeController is demonstrated in Figure 5. Figure 5 introduces two concepts firstly the ability to capture an event and secondly invalidating a component. These are outlined next.

Figure 4: A part of index.zul

 

<div id="employeediv"
  apply="org.zkoss.jtjexample.controller.EmployeeController"
  hflex="true">
Figure 5: EmployeeController.java

 

public class EmployeeController extends GenericForwardComposer {

  /**
   * 
   */
  private static final long serialVersionUID = -9089818718875587898L;

  private static final Log log = Log.lookup(EmployeeController.class);

  private Employee _currentEmployee;
  private ListModelList _model = EmployeeService.INSTANCE.getModel();

  Listbox lstEmployee;
  Textbox txtFirstName, txtLastName;
  Intbox intAge;

  public Employee getCurrentEmployee() {
    return _currentEmployee;
  }

  public void setCurrentEmployee(Employee currentEmployee) {    
    this._currentEmployee = currentEmployee;
  }

  public ListModel getEmployeeModel() {
    return _model;
  }

  // click events
  public void onClick$btnAddEmployee() {

    String firstName = txtFirstName.getText();
    String lastName = txtLastName.getText();
    int iAge = Integer.parseInt(intAge.getText());

    Employee employee = new Employee(firstName, lastName, iAge);

    if (!_model.add(employee)) {
      reportError(Messages.getString("EmployeeController.0"), employee);
    }

  }

  public void onClick$btnUpdateEmployee() {
    if (lstEmployee.getSelectedItem() != null) {

      Employee employee = (Employee) (lstEmployee.getSelectedItem()
          .getValue());
      
      employee.setFirstName(txtFirstName.getText());
      employee.setLastName(txtLastName.getText());
      employee.setAge(Integer.parseInt(intAge.getText()));
    } else {
      UiUtils.showMessage(Messages.getString("EmployeeController.2"));
    }
  }

  public void onClick$btnDeleteEmployee() {

    if (lstEmployee.getSelectedItem() != null) {
      Employee employee = (Employee) (lstEmployee.getSelectedItem()
          .getValue());

      if (!_model.remove(employee)) {
        reportError(Messages.getString("EmployeeController.3"), employee);
      }

    } else {
      UiUtils.showMessage(Messages.getString("EmployeeController.4"));
    }

  }

  private void reportError(String message, Employee employee) {
    StringBuilder sb = new StringBuilder(message).append(Messages.getString("EmployeeController.5")).append(employee);
    final String error = sb.toString();

    UiUtils.showMessage(error);
    log.error(error);
  }
} 

Capturing events

Event capturing in ZK is easy to implement, providing developers with enormous power. Figure 6 is a function signature to capture the onClick event from the button named btnAddEmployee. The onClick event is fired when a user clicks a button. The method signature in Figure 6 can be broken down into 3 parts. Firstly, the return type is void and method is public. The method name consists of the event name, followed by a dollar sign ($) and the name of the component whose event you want to trap. Then lastly, in this case the event type is a ForwardEvent. Using this technique it is possible to trap any event from any ZK component in a composer which is properly wired to the view.

Figure 6: Function signature for event capturing

 

public void onClick$btnAddEmployee(ForwardEvent fe)

 

Using databinding to load data from our service

The view is tied to the controller using the apply attribute as discussed in Associating the Controller with the view. Now ZK's data binding mechanism needs to be activated for this page. Remember, due to the include mode being deferred each zul is considered a separate entity, thus, they can each have their own data binding instance. To initialize the Annotated data binder, use the line shown in Figure 7.

Figure 7:Initalise the databinder

 

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>

 

        

Timothy Clare
Timothy Clare

What do you think?

JAX Magazine - 2014 - 06 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions