2

I was just implementing a crude functionality using jsf+richfaces and came across this situation, so putting this to the open forum for some answers.

I have a text field and rich:dataTable inside a form. When value changes in textField, table data is populated and table is supposed to be reRendered with latest data.

Now the point in question : What if I have rendered condition on dataTable saying render this table if list of values is not-null/non-empty? So for the 1st time when screen appears, list is null/empty and hence table is not rendered, as and when I modify textField, values are populated and reRender on table is fired but as a whole table does not exist.

Is there a way to solve this behaviour? If I reload the page, yes table definitely appears :)

Here is the sample code for this :

    <h:form id="userSearchForm" prependId="false">
        <h:inputText value="#{ldapSearch.searchString}">
            <a4j:support event="onkeyup" ignoreDupResponses="true" ajaxSingle="true" reRender="usersTable"
            requestDelay="50" actionListener="#{ldapSearch.searchUser}"/>
        </h:inputText>
            <rich:dataTable id="usersTable"
                rendered="#{not empty ldapSearch.users}"
                value="#{ldapSearch.users}" var="user">
                <rich:column sortable="false" label="Name">
                    <f:facet name="header">
                        <h:outputText value="Name"/>
                    </f:facet>
                    <h:outputText title="#{user.displayName}" value="#{user.displayName}"/>
                </rich:column>
            </rich:dataTable>
    </h:form>
Satya
  • 2,094
  • 6
  • 37
  • 60
  • Related: http://stackoverflow.com/questions/9010734/why-do-i-need-to-nest-a-component-with-rendered-some-in-another-component-w – BalusC Mar 01 '12 at 19:25

2 Answers2

4

I solve this issue by surrounding the dataTable with some component that is always rendered, and then reRendering that component instead. For example:

<h:form id="userSearchForm" prependId="false">
    <h:inputText value="#{ldapSearch.searchString}">
        <a4j:support event="onkeyup" ignoreDupResponses="true" ajaxSingle="true" reRender="divUsersTable"
        requestDelay="50" actionListener="#{ldapSearch.searchUser}"/>
    </h:inputText>
    <s:div id="divUsersTable">
        <rich:dataTable id="usersTable"
            rendered="#{not empty ldapSearch.users}"
            value="#{ldapSearch.users}" var="user">
            <rich:column sortable="false" label="Name">
                <f:facet name="header">
                    <h:outputText value="Name"/>
                </f:facet>
                <h:outputText title="#{user.displayName}" value="#{user.displayName}"/>
            </rich:column>
        </rich:dataTable>
    </s:div>
</h:form>
Mike Bockus
  • 2,079
  • 17
  • 23
  • Ya, I could do that or render the whole form. But this kind of situations are tough for me to catch and understand. – Satya Mar 01 '12 at 13:39
  • @Satya But this is the typical solution for this kind of task. What is hard to understand with this approach? – Matt Handy Mar 01 '12 at 13:47
  • 1
    @Satya You just have to remember that the id of the element that you're reRendering has to exist in the page. If the id that you're reRendering is conditionally rendered, then it may or may not exist on the page. If the component hasn't previously been rendered, then it won't be reRendered. – Mike Bockus Mar 01 '12 at 14:14
0

The problem is that you can't rerender something that has not been rendered in the first time. My solution is to play with the display attribute of the component style.

<rich:dataTable id="usersTable"
    style="display:#{not empty ldapSearch.users? 'inline' : 'none'}"    
    value="#{ldapSearch.users}" var="user">
<!-- your columns -->
</rich:dataTable>

In that way, I can rerender the table with no problems :).

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332