3

How can I use id of DataTable Component (Primefaces 2.2.1) inside Composite Component in Java Server Faces 2.1 ?

Now, I have a view:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:p="http://primefaces.prime.com.tr/ui"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:haiq="http://java.sun.com/jsf/composite/haiqcomponents"
                template="/WEB-INF/templates/login/main.xhtml">

    <ui:define name="content">
        <h:form prependId="false">  <!-- prependId="true" ??? -->
            <p:dataTable id="leakTable" var="leak" value="#{dataExplorer.data}">   

                <p:column filterBy="#{leak.source}" headerText="source" footerText="source" filterMatchMode="contains" >  
                    <f:facet name="header">  
                        <h:outputText value="source" />  
                    </f:facet>  
                    <h:outputText value="#{leak.source}"  />  
                </p:column>  

                <!-- Few more columns here -->
            </p:dataTable> 

            <!-- Add : prefix before ID? -->
            <haiq:exporter target=":leakTable" fileName="#{msgs.fileName}" imageLibrary="images" pageOnly="false" />

        </h:form>   
    </ui:define>
</ui:composition>

My composite component:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:cc="http://java.sun.com/jsf/composite"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.prime.com.tr/ui">

<!-- INTERFACE -->
<cc:interface>
    <cc:attribute name="fileName" default="data" />
    <cc:attribute name="target" required="true" type="java.lang.String" />
    <cc:attribute name="pageOnly" default="true" type="java.lang.Boolean" />
    <cc:attribute name="imageLibrary" default="images" />
</cc:interface>

<!-- IMPLEMENTATION -->
<cc:implementation>
    <h:commandLink>  
        <h:graphicImage library="#{cc.attrs.imageLibrary}" name="excel.png" />  
        <p:dataExporter type="xls"
                        target="#{cc.attrs.target}" 
                        fileName="#{cc.attrs.filename}" 
                        pageOnly="#{cc.attrs.pageOnly}" />  
    </h:commandLink>  
</cc:implementation>
</html>

After view rendering, following error occurred:

javax.faces.FacesException: Cannot find component ":leakTable" in view.
at org.primefaces.component.export.DataExporter.processAction(DataExporter.java:89)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)

Removing : before leakTable (in target attribute) or changing preperndId (in form) to true does not solve the problem.

How can I use datatable inside cc? Similar problem is described here

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
vizzdoom
  • 736
  • 1
  • 9
  • 19

1 Answers1

2

Apparently you've another NamingContainer parent in the view. To be sure, open page in browser, rightclick and View Source and determine the generated ID of <p:dataTable id="leakTable">. Then, you should grab exactly that ID and prefix with :.

Alternatively, you can also bind the table component to the view and use UIComponent#getClientId() instead to dynamically refer the client ID.

<p:dataTable binding="#{leakTable}" ...>

with

<haiq:exporter target=":#{leakTable.clientId}" ...>

Unrelated to the concrete problem, I suggest to replace <!DOCTYPE><html> of your composite by <ui:component>, which is more natural and it also saves JSF from doing it impliticly everytime.

<ui:component
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:p="http://primefaces.prime.com.tr/ui">

See also https://stackoverflow.com/tags/composite-component/info.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for your reply! I don't know how can I bind ID. I tried to declare private UIComponent nameField = new UIInput(); with getter and setter and using it by #{dataExplorer.nameField} but this generates more problems like java.lang.IllegalArgumentException: "". I checked generated HTML of p:dataTable and there are leakTable:... ids inside div and scripts. – vizzdoom Nov 01 '11 at 18:46
  • Uh, I've already demonstrated it with some code in my answer. Just copypaste it. You don't need to bind it to some managed bean property. Just bind it directly to the view. Exactly as shown in my answer. – BalusC Nov 01 '11 at 18:53
  • Ah, I used your solution but... I am using autodeploy for glassfish. This `feature` caused me lots of problems - after clicking on cc page was reloading and nothing happens. I restarted Glassfish and deployed webapp again and then your solution worked! Thanks! – vizzdoom Nov 01 '11 at 21:44