title: JSF (Primefaces) Button in datatable to new page with data
body: <p>and primefaces. </p>
  
  <p>I have a simple datatable with users. I want a button in each row "Add Item" that navigates to a new page where the user can input item details. Off the id of the customer must be used when creating a new item. </p>
  
  <pre><code>&lt;p:dataTable id="dataTable" var="customer"
                  value="#{customerController.lazyCustomerModel}"
                  rowKey="#{customer.id}" styleClass="userDataTableStyle"
                  paginator="true" rows="10"
                  selection="#{customerController.selectedCustomers}"
                  paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                  lazy="true" rowsPerPageTemplate="10,15,50"&gt;
  
                  &lt;p:column selectionMode="multiple" style="width:18px" /&gt;
                  &lt;p:column&gt;
                      &lt;f:facet name="header"&gt;
                          &lt;h:outputText value="Id" /&gt;
                      &lt;/f:facet&gt;
                      &lt;h:outputText value="#{customer.id}" /&gt;
                  &lt;/p:column&gt;
  
                  &lt;p:column&gt;
                      &lt;f:facet name="header"&gt;
                          &lt;h:outputText value="Phone" /&gt;
                      &lt;/f:facet&gt;
                      &lt;h:outputText value="#{customer.phone}" /&gt;
                  &lt;/p:column&gt;
  
                  &lt;p:column&gt;
                      &lt;f:facet name="header"&gt;
                          &lt;h:outputText value="Name" /&gt;
                      &lt;/f:facet&gt;
                      &lt;h:outputText value="#{customer.name}" /&gt;
                  &lt;/p:column&gt;
  
                  &lt;p:column&gt;
                       &lt;!-- Here a button to new page for adding item --&gt;
                  &lt;/p:column&gt;
  
  
                  &lt;f:facet name="footer"&gt;
                                              &lt;p:commandButton value="Delete Users"
                          actionListener="#{customerController.deleteUsers}"
                          update="dataTable" icon="ui-icon-trash" /&gt;
                  &lt;/f:facet&gt;
  
              &lt;/p:dataTable&gt;
  </code></pre>
  
  <p>What is the nest way to do this... Can I navigate directly to the new page with the customer id in the url ? or should I submit to the controller with the id and then redirect ? </p>
  
  <p>Update : </p>
  
  <p>So I try to use viewParam : 
  When I click the New Item button no parameters are passed in the URL. </p>
  
  <p>If I type in the URL manually : like 
  /newItem.jsf?customerId=2</p>
  
  <p>The method </p>
  
  <pre><code>public void setCustomerId(String customerId) {
      this.customerId = customerId;
  }
  </code></pre>
  
  <p>in NewItemController is called with the id 2
  I then type in data in the new item form an press Save button, but now the customerId is null</p>
  
  <p>customers.xhtml</p>
  
  <pre><code>&lt;ui:define name="content"&gt;
          &lt;f:metadata&gt;
              &lt;f:viewParam name="customerId" value="#{customerController.customerEnt.id}" /&gt;
          &lt;/f:metadata&gt;
          &lt;h:form id="customers" prependId="false" includeViewParams="true"&gt;
  
              &lt;p:panelGrid styleClass="panelGridCenter"&gt;
                  &lt;f:facet name="header"&gt;
                      &lt;p:row&gt;
                          &lt;p:column style="text-align: center;" colspan="2"&gt;Search Customer&lt;/p:column&gt;
                      &lt;/p:row&gt;
                  &lt;/f:facet&gt;
  
                  // Rows with search fields
  
                  &lt;f:facet name="footer"&gt;
                      &lt;p:row&gt;
                          &lt;p:column style="text-align: center;" colspan="2"&gt;
                              &lt;p:commandButton value="Search"
                                  action="#{customerController.search}"
                                  update=":customers:dataTable" /&gt;
                          &lt;/p:column&gt;
                      &lt;/p:row&gt;
                  &lt;/f:facet&gt;
              &lt;/p:panelGrid&gt;
              &lt;br /&gt;
  
              &lt;h:outputText
                  value="Result is more than 100, only the first 100 results are displayed!"
                  rendered="#{customerController.searchResultSize &gt; 100}" /&gt;
              &lt;h:outputText value="#{customerController.searchResultSize}" /&gt;
              &lt;br /&gt;
              &lt;p:dataTable id="dataTable" var="customer"
                  value="#{customerController.customers}" rowKey="#{customer.id}"
                  styleClass="userDataTableStyle" paginator="true" rows="10"
                  selection="#{customerController.selectedCustomers}"
                  paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                  lazy="true" rowsPerPageTemplate="10,15,50"&gt;
  
                  // Columns
  
                  &lt;p:column&gt;
                      &lt;p:commandButton value="New Item" action="#{customerController.newItem()}"/&gt;
                  &lt;/p:column&gt;
  
              &lt;/p:dataTable&gt;
  
          &lt;/h:form&gt;
  
      &lt;/ui:define&gt;
  </code></pre>
  
  <p>CustomerController
  Only showing the important part here... </p>
  
  <pre><code>@SuppressWarnings("serial")
  @SessionScoped
  @Named
  public class CustomerController implements Serializable {
  
      private Long customerId;
  
      public String newItem() {
          return "newItem?faces-redirect=true&amp;includeViewParams=true";
      }
  
      public Long getCustomerId() {
          return customerId;
      }
  
      public void setCustomerId(Long customerId) {
          this.customerId = customerId;
      }
  }
  </code></pre>
  
  <p>newItem.xhtml</p>
  
  <pre><code>    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ui:composition 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:p="http://primefaces.org/ui"
      template="/WEB-INF/templates/default.xhtml"&gt;
  
      &lt;div class="center"&gt;
          &lt;ui:define name="content"&gt;
              &lt;f:metadata&gt;
                  &lt;f:viewParam name="customerId" value="#{newItemController.customerId}" /&gt;
              &lt;/f:metadata&gt;
  
              &lt;h:form id="item"&gt;
                  &lt;p:messages id="messages" /&gt;
                  &lt;p:panelGrid styleClass="panelGridCenter"&gt;
                          ...
                  &lt;/p:panelGrid&gt;
              &lt;/h:form&gt;
          &lt;/ui:define&gt;
      &lt;/div&gt;
  &lt;/ui:composition&gt;
  </code></pre>
  
  <p>NewItemController</p>
  
  <pre><code>    @SuppressWarnings("serial")
  @ViewScoped
  @Named
  public class NewItemController implements Serializable {
  
      private String customerId;
  
  public void save() throws Exception {
          try {
              CustomerEnt customerEnt = null;
              if (StringUtils.isNotBlank(customerId)) {
                  customerEnt = customerDas.find(Long.parseLong(customerId));
              } else {
                  throw new Exception("Customer id not set when creating a new item");
              }
              itemEnt.setCustomerEnt(customerEnt);
              serviceSLSB.save(itemEnt);
          } catch (Exception e) {
              String errorMessage = getRootErrorMessage(e);
              FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Saving unsuccessful");
              facesContext.addMessage(null, m);
          }
      }
  
      public String getCustomerId() {
          return customerId;
      }
  
      public void setCustomerId(String customerId) {
          this.customerId = customerId;
      }
  }
  </code></pre>