Master Details Tutorial

compared with
Key
These lines were removed. This word was removed.
These lines were added. This word was added.

View page history


There are 20 changes. View first change.

 h1. {anchor:EasyAjaxPush-EasyAjaxPushTutorial}Master Details Tutorial
  
 Master-Details update forms are commonly used for selecting an item from a list and then updating the details of that item. This example will show how you can easily set up a form to select an employee and update the employee details.
  
  
 This tutorial uses an ICE dataTable with a rowSelector.
 ----
 Here is the entire list of steps worked through during this tutorial:
 # [Make the masterDetails Project|#step1]
 # [Add ICEfaces|#step2]
 # [Create masterDetails.xhtml|#step3]
 # [Create Person.java|#step4]
 # [Create DataTableBean.java|#step5]
 # [Deploy the Application|#step6]
  
 * [Tutorial Source Code Downloads|#code] (coming soon)
  
 ----
 h3. Development Tools Used
  
 The following tools were used to create the project.
 * [Eclipse|http://eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/heliossr1] IDE for Java EE Developers - Version Juno
 * [Tomcat 7.x|http://tomcat.apache.org/download-70.cgi] Web Server
 * [Java 6.x|http://www.oracle.com/technetwork/java/javase/downloads/]
 * ICEfaces 3
  
 h3. {anchor:step1}1. Make the masterDetails Project
  
 * Using Eclipse create a new Dynamic Web Project called masterDetails.
 ** Target runtime: Apache Tomcat v7.0
 ** Dynamic web module version: 3.0
 ** Configuration: JavaServer Faces v2.0 Project (Mojarra)
  
 h3. {anchor:step2}2. Add ICEfaces
  
 Add the icefaces.jar (from the ICEfaces 3 bundle) to your project, either through a custom User Library or by putting them into masterDetails /WEB-INF/lib/. The approach doesn't matter as long as the jars are included in the deployed war file.
  
 h3. {anchor:step3}3. Create masterDetails.xhtml
  
 Create a new page called masterDetails.xhtml and paste the code below:
 {code}
 <?xml version='1.0' encoding='UTF-8' ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:icecore="http://www.icefaces.org/icefaces/core"
  xmlns:ace="http://www.icefaces.org/icefaces/components"
  xmlns:ice="http://www.icesoft.com/icefaces/component">
 <h:head>
  <title>Master/Details demo</title>
  <link rel="stylesheet" type="text/css"
  href="./xmlhttp/css/rime/rime.css" />
 </h:head>
 <h:body>
  <h:form id="master">
  
  <center>
  <ace:panel header="Staff List" toggleable="true" style="width: 50%">
  
  <ice:dataTable id="masterTable" value="#{dataTableBean.personData}"
  var="person">
  <ice:column id="id" headerText="ID">
  <ice:rowSelector value="#{person.selected}"
  selectionListener="#{dataTableBean.selectionListener}" />
  <h:outputText id="idCell" value="#{person.id}" />
  </ice:column>
  
  <ice:column id="name" headerText="Full Name">
  <h:outputText id="nameCell" value="#{person.name}" />
  </ice:column>
  
  <ice:column id="address" headerText="Address">
  <h:outputText id="addressCell" value="#{person.address}" />
  </ice:column>
  </ice:dataTable>
  </ace:panel>
  </center>
  </h:form>
  <p />
  
  <h:form id="details">
  
  <center>
  <ace:panel header="Staff Member Details" toggleable="true"
  style="width: 50%" collapsed="#{dataTableBean.detailsHidden}">
  <ice:panelGrid columns="2">
  <ice:outputLabel for="firstName" value="First Name" />
  <h:inputText id="firstName"
  value="#{dataTableBean.personDetails.firstName}" size="55">
  <f:ajax event="change" listener="#{dataTableBean.changeListener}"/>
  </h:inputText>
  
  <ice:outputLabel for="lastName" value="Last Name" />
  <h:inputText id="lastName"
  value="#{dataTableBean.personDetails.lastName}" size="55">
  <f:ajax event="change" listener="#{dataTableBean.changeListener}"/>
  </h:inputText>
  
  <ice:outputLabel for="address" value="Address" />
  <h:inputText id="address"
  value="#{dataTableBean.personDetails.address}" size="55">
  <f:ajax event="change" listener="#{dataTableBean.changeListener}" />
  </h:inputText>
  <ice:outputText />
  <ice:commandButton value="Update Details"
  action="#{dataTableBean.save}" />
  </ice:panelGrid>
  </ace:panel>
  </center>
  <!-- Confirm Dialog -->
  <ice:panelPopup visible="#{dataTableBean.confirmDialog}" modal="true">
  <f:facet name="header">
  <ice:panelGroup styleClass="headerStyleClass">
  <ice:outputText value="Warning" />
  </ice:panelGroup>
  </f:facet>
  <f:facet name="body">
  <ice:panelGroup styleClass="bodyStyleClass">
  <ice:outputText
  value="You have unsaved data. &lt;br/&gt;
   Are you sure you want to change to a new master record?"
  escape="false" />
  <ice:panelGroup>
  <h:commandButton value="Yes" action="#{dataTableBean.confirmYes}" />
  <h:commandButton value="No" action="#{dataTableBean.confirmNo}" />
  </ice:panelGroup>
  </ice:panelGroup>
  </f:facet>
  </ice:panelPopup>
  </h:form>
 </h:body>
 </html>
 {code}
 In this page we use the ajax change event to set a flag on the backing bean to indicate that the user has changed the text in the details forms. This is so we can warn the user if they try to select a new employee to update when they have unsaved data.
  
In this page we use the ajax change event to set a flag on the backing bean to indicate that the user has change the text in the details forms. This is so we can warn the user if they try to select a new employee to update when they have unsaved data.
  
 h3. {anchor:step4}4. Create Person.java
  
 Create a new Java class file called Person in the package org.icefaces.tutorial.masterdetails.model and paste the code below:
  
 {code}
package org.demo.model;
  package org.icefaces.tutorial.masterdetails.model;
 import java.io.Serializable;
 import javax.faces.bean.ManagedBean;
  
 @ManagedBean
 public class Person implements Serializable, Cloneable{
  private static final long serialVersionUID = -3540661397516075104L;
  public Person(Integer id, String firstName, String lastName, String address) {
  this.setId(id);
  this.firstName = firstName;
  this.lastName = lastName;
  this.address = address;
  }
  private Integer id;
  private String firstName;
  private String lastName;
  private String address;
  private Boolean selected;
  
  public String getFirstName() {
  return firstName;
  }
  public void setFirstName(String firstName) {
  this.firstName = firstName;
  }
  public String getLastName() {
  return lastName;
  }
  public void setLastName(String lastName) {
  this.lastName = lastName;
  }
  public String getAddress() {
  return address;
  }
  public void setAddress(String address) {
  this.address = address;
  }
  public String getName(){
  return firstName + " " + lastName;
  }
  public Integer getId() {
  return id;
  }
  public void setId(Integer id) {
  this.id = id;
  }
  public Boolean getSelected() {
  return selected;
  }
  public void setSelected(Boolean selected) {
  this.selected = selected;
  }
  @Override
  public Object clone() throws CloneNotSupportedException {
  return super.clone();
  }
 }
 {code}
 This class is a model of a Person (in our case, an employee). It contains fields for id, first name, last name, address. In the future it could be extended for different kinds of people (full time, part time, contractor, ect) as required.
  
 h3. {anchor:step5}5. Create DataTableBean.java
  
 Create a new Java class file called ColorBean in the package org.icefaces.tutorial.masterdetails.beans and paste the code below:
  
  
 {code}
package org.icefaces.tutorial.easyajaxpush.beans;
  package org.icefaces.tutorial.masterdetails.beans;
  
 import java.io.Serializable;
import java.util.ArrayList;
 import java.util.List;
  
import javax.annotation.PostConstruct;
 import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
 import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
 import javax.servlet.http.HttpSession;
  import javax.faces.event.AjaxBehaviorEvent;
  
@ManagedBean(name="colorBean")
  import org.demo.model.Person;
  
 import com.icesoft.faces.component.ext.RowSelectorEvent;
  
 @ManagedBean
 @ViewScoped
public class ColorBean implements Serializable {
  private static final String PUSH_GROUP = "colorPage";
  public class DataTableBean implements Serializable {
  
@ManagedProperty(value="#{messageBean}")
  private MessageBean messageBean;
  private String color = "black";
  private String sessionId;
   private static final long serialVersionUID = -2904483316550697214L;
  private List<Person> personData;
  private Person personDetails;
  private Integer index = null;
  private Integer newIndex;
  private boolean confirmDialog = false;
  private boolean detailsHidden = true;
  private boolean change = false;
  
public ColorBean() {
  FacesContext fcontext = FacesContext.getCurrentInstance();
  HttpSession session = (HttpSession)fcontext.getExternalContext().getSession(false);
  sessionId = session.getId();
   @PostConstruct
  public void initData() {
  personData = new ArrayList<Person>();
  // Add some people
  personData.add(new Person(1, "Peter", "Parker",
  "150 Main Street, New York, NY, USA"));
  personData.add(new Person(2, "Ryan", "Penner",
  "528 Newmarket Road, Wilston, QLD, Australia"));
  personData.add(new Person(3, "Paul", "Wilson",
  "50 Big Ben Road, London, UK"));
  }
  
public void setMessageBean(MessageBean messageBean) {
  this.messageBean = messageBean;
   public List<Person> getPersonData() {
  return personData;
  }
  
public String getColor() {
  return color;
   public void setPersonData(List<Person> personData) {
  this.personData = personData;
  }
  
public void setColor(String color) {
  this.color = color;
   public Person getPersonDetails() {
  return personDetails;
  }
  
public String chooseColor() {
  messageBean.addToList(sessionId, color);
   public void setPersonDetails(Person personDetails) {
  this.personDetails = personDetails;
  }
  
return null;
   public void selectionListener(RowSelectorEvent event) {
  // First selection or no changes to the current record
  if (index == null || !change) {
  index = event.getRow();
  try {
  setPersonDetails((Person) personData.get(index).clone());
  } catch (CloneNotSupportedException e) {
  System.out.println(e);
  }
  
  detailsHidden = false;
  }
  // Something else is already selected
  else if (index != event.getRow()) {
  // Throw a warning to the user
  newIndex = event.getRow();
  setConfirmDialog(true);
  }
  }
  
public String getSessionId() {
  return sessionId;
  }
   public void confirmYes() {
  index = newIndex;
  setPersonDetails(personData.get(index));
  confirmDialog = false;
  detailsHidden = false;
  change = false; // We discard the old record
  }
  
public void setSessionId(String id) {
  }
  }
 {code}
   public void confirmNo() {
  newIndex = null;
  confirmDialog = false;
  
  }
  
  public void changeListener(AjaxBehaviorEvent event) {
  change = true;
  }
  
  public void save() {
  // Reset the change flag
  change = false;
  // Save the person
  personData.set(index, personDetails);
  }
  
  public boolean isConfirmDialog() {
  return confirmDialog;
  }
  
  public void setConfirmDialog(boolean confirmDialog) {
  this.confirmDialog = confirmDialog;
  }
  
  public boolean isDetailsHidden() {
  return detailsHidden;
  }
  
  public void setDetailsHidden(boolean detailsHidden) {
  this.detailsHidden = detailsHidden;
  }
 }
  
 {code}
 h3. {anchor:step6}6. Deploy the application
  
 Once the application is built and deployed you will be able to select a employee from the table at the top of the page and edit their details on the table below.

© Copyright 2017 ICEsoft Technologies Canada Corp.