0

I have a <h:dataTable> which has a <p:commandLink> within it. I need to fetch some data from the database when <p:commandLink> is clicked and display it within a pop-up for which I am using a <p:dialog>.

<h:form id="form">
<h:dataTable width="80%" value="#{controller.items}" var="a" binding="#{bean.table}"
                rendered="#{not empty controller.items}">
        <h:column>
            <h:outputText value="#{a.date}" />
        </h:column>

        <h:column>
            <h:outputText value="#{a.name}" />
        </h:column>

        <h:column>
            <p:commandLink value="View" action="#{controller.getData()}"
                        update=":form:dialog" oncomplete="w_dialog.show();return false;">

            </p:commandLink>
        </h:column>

        </h:dataTable>

            <p:dialog header="Test" widgetVar="w_dialog" width="600px" height="500px"
                    id="dialog" modal="true" draggable="true" appendToBody="true" rendered="#{sessionScope.sample ne null}">
                    <ui:include src="sample.xhtml"/>
            </p:dialog>

</h:form>   

I need to capture the data of the row which is clicked and get data from the database. My bean and controller classes are as follows:

@Named
@SessionScoped
public class Bean implements Serializable
{       
    private HtmlDataTable table;

    // getters and setters                                      

}


@Named
@SessionScoped
public class Controller implements Serializable
{       

    @Inject
    private Bean bean;

    public void getData(){

    bean.getTable().getRowData();
    SampleClass sample=new SampleClass();


    // fetches data from database and populates it within sample instance

    FacesContext context = FacesContext.getCurrentInstance();
    context.getExternalContext().getSessionMap()
                .put("sample", sample);

    }

}

The <p:dialog> includes a file called sample.xhtml which has references to SampleClass. So I used rendered property in <p:dialog> to avoid NullPointer Exception on loading my xhtml page.Also, sample of type SampleClass is inserted into the sessionMap only after the controller method getData() is executed on clicking the <p:commandLink>.

The problem is that the pop-up never gets displayed even after the method getData() is executed and sample is inserted into the SessionMap.

I have used update=:form:dialog to update the dialog after the <p:commandLink> is clicked. But it seems that the rendered property of the dialog never gets updated. So i cannot see the <p:dialog>.

Am I missing something?

Ardalan Shahgholi
  • 11,967
  • 21
  • 108
  • 144
Jini Samuel
  • 124
  • 1
  • 3
  • 13

1 Answers1

2

You can't update a component that doesn't exist. rendered attribute determines if the component will be shown in the DOM tree or not, not only its visibility. It means, if false, this component will not be available for JSF, for rerendering/updating terms.

The standard solution for that is to wrap the component into a container element and update it instead (by the way, I encourage you not to use getter methods for action purposes):

<h:panelGroup id="parentPanel">
    <p:dialog header="Test" widgetVar="w_dialog" width="600px" height="500px"
        id="dialog" modal="true" draggable="true" 
        appendToBody="true" rendered="#{sessionScope.sample ne null}">
        <ui:include src="sample.xhtml"/>
    </p:dialog>
</h:panelGroup>

<p:commandLink value="View" action="#{controller.showData()}"
                        update=":form:parentPanel" />
Aritz
  • 30,971
  • 16
  • 136
  • 217
  • The pop-up is showing now, but the JSF page does not show the updated values of session cope variable `sample`. Instead, it shows the same values which were populated when the `` was clicked for the first time. Is something wrong in my approach of displaying the values? – Jini Samuel Oct 17 '13 at 07:03
  • Using `ui:include` implies that if the page is `@ViewScoped` it'll be included at build time and you probably cannot update its internal values via ajax (I'm not sure about that). However you have [more ways](http://stackoverflow.com/a/4793959/1199132) to include some content which don't imply to do it at build time. Try to just put your `sample.xhtml`'s content directly in the dialog. If it works, try to go with templating. – Aritz Oct 17 '13 at 07:12
  • It worked, I was using `appendToBody=true` in `` due to which the updated dialog was being displayed under the first dialog(the dialog which opened on clicking the `` for the first time). It was like, if we click the `` 3 times, 3 dialogs were being displayed, one beneath the other. So , the variable `sample` in `sessionScope` was actually being updated everytime in the JSF page. The problem was with the dailog. Thanks for your help...! – Jini Samuel Oct 17 '13 at 11:59