Search code examples
jsfjsf-2tomahawk

JSF: Save selected variable value in datatable for next view


I have a data table:

    <h:dataTable binding="#{table}" value="#{chooseKittens.kittenList}">
      <h:column>
        <p:commandLink value="#{chooseKittens.kittenList[table.rowIndex]}" action="#{chooseKittens.petKitten}"/>
      </h:column>
    </h:dataTable>

The dataTable is a of links that will take you to a different page. When I go to a different page, though, I want to save the value of the command link clicked so that I can display it in subsequent views. Is there a way to do this without SessionScope? I looked into t:saveState, but I'm not sure how to save just the variable clicked in a Datatable. If SessionScope is the only thing available, is there a way to make the kittenList in a different scope? (The kitten list should change when a new kitten is added in the database, so it should be in RequestScope or ViewScope).


Solution

  • If you want to share information between views there are two typically used alternatives you could consider.

    1. Pass information to the next view as a GET parameter

      In this case you'll use a JSF component generating a plain navigational link and attach a query parameter to that link, like in:

      <h:link value="Next page" outcome="/view-kitten">
          <f:param name="id" value="#{kitten.id}"/>
      </h:link>
      

      In the receiving page the parameter is available via:

      <f:metadata>
          <f:viewParam name="id" value="#{kittenBean.id}/>
      </f:metadata>
      

      More excellent information can be found in What can <f:metadata> and <f:viewParam> be used for?

    2. Pass information to the redirected view using Flash

      In this case you're performing a redirect in an action method of a command component and will attach necessary data to the target view using Flash object:

      <h:commandButton value="Next page" action="#{bean.next}"/>
      

      with

      public String next() {
          //do business job
          FacesContext.getCurrentInstance().getExternalContext().getFlash().put("kitten", selectedKitten);
          return "/view-kitten?faces-redirect=true";
      }
      

      It will be available in the target view via EL with #{flash.kitten} or programmatically with FacesContext.getCurrentInstance().getExternalContext().getFlash().get("kitten").

      An extended example can be found in JSF2.0 - How to get the values in other jsf page's bean in request scope.

    The last thing to note is: don't abuse HTTP session. You shouldn't pollute the session with information that belongs elsewhere.