1
votes

I am having a very simple but annoying issue with JSF. I have a datatable (with simple first next etc paging option) , which I want to populate from same page where users do initial selection.

Initial Form

<b><h:selectOneRadio id="radio1" layout="pageDirection" style="font-weight: bold" value="#{displayNOC.slection}">       <f:selectItem itemLabel="Search By NOC" itemValue="N" id="selectItem1" />
 <f:selectItem itemLabel="Search By Title" itemValue="T" id="selectItem2" />
</h:selectOneRadio></td>
<hx:commandExButton type="submit" image="images/btn_search.jpg" action="#{displayNOC.Process_request}" onclick="return validate_ListNoc(this.form)"></hx:commandExButton></b>

Once user select a radio button and click "search", I am populating a datatable (which is hidden in the same page with rendered properties false) and a paging button (at this stage I only have NEXT button which is also hidden at the time of form load using rendered property) without any problem .

<B>Search Results :<BR><BR>
<h:inputHidden id="text1" value="#{displayNOC.firstRow}" ></h:inputHidden>
navigation Next button start
<hx:commandExButton type="submit" value="Next" action="#{displayNOC.goNext}" rendered="#{displayNOC.render_panel_status}" disabled="#{displayNOC.firstRow + displayNOC.rowPerPage >= displayNOC.totalSize}">
</hx:commandExButton>

<h:dataTable border="1" id="table" value="#{displayNOC.WAMNOC}" rendered="#{displayNOC.render_status}" var="SearchResult" headerClass="row2" rowClasses="row-even,row-odd" cellspacing="6">
 <h:column>
 <f:facet name="header">
  <h:commandLink value="NOC_Number" style="text-align: center">
    </h:commandLink>
        </f:facet>
         <h:outputText value="#{SearchResult[0]}" />
         </h:column>
......................
.......................
</h:datatable>

My managed bean SCOPE:REQUEST in face-config.xml is as follows (I have all the getter and setter for all the vars)

@SuppressWarnings("unchecked")
 public void Process_request()
 {
  setRender_status(true);
  setRender_panel_status(true);
  WAMNOCSERVICE WNS=new WAMNOCSERVICE();
  List<WAM_NOC> wnoc= WNS.getNOCandOccupation(0,10);
  //get the total size of the records
  setTotalSize(WNS.totalRecordAvaiable());
  setTotalpage(wnoc.size()/10);
  setRowPerPage(10);
  setFirstRow(1);
  setWAMNOC(wnoc);
 }

 //this action is for next button in the table paging
 @SuppressWarnings("unchecked")
 public void goNext()
 {
  setRender_status(true);
  setRender_panel_status(true);
  setRowPerPage(10);
  System.out.println(firstRow);
  firstRow = getFirstRow() + rowPerPage;
  WAMNOCSERVICE WNS=new WAMNOCSERVICE();
  List<WAM_NOC> wnoc= WNS.getNOCandOccupation(firstRow,rowPerPage);
  setWAMNOC(wnoc);
  }

My problem is when I click GoNext() button render_status never set to true and I never see any datatable or button any more. Admitting I am new to JSF , this was the last thing I thought will give me such trouble. Any help would be highly appreciated.

1

1 Answers

1
votes

The condition for the rendered attribtue is re-evaluated in the subsequent request. But since it's depending on a request scoped bean which get garbaged by end of response and recreated on a next new request, this condition will turn back to default and so the action won't be invoked when you have this in an UICommand component or one of its parents.

In JSF 1.x there are several solutions to go around this:

  • Put bean in session scope. Easiest, but not good for user experience whenever the enduser opens the same page in multiple tabs/browsers on the same session.

  • Use <h:inputHidden> with a binding. Nasty, more detail can be found in this answer.

  • Use Tomahawk's <t:saveState> to retain the bean in the next request. Clean and nice, but requires additional component library.

    <t:saveState value="#{displayNOC}" />
    

The JSF 2.0 solution would be to just put the bean in the view scope.