2

I have a piece of code similar to "Data Table - Instant Row Selection". However, when I break it down into composite components the selection values are not displayed. I have a suspicion it's caused by PrimeFaces code.

Below is the code that doesn't work:
viewApplicationConfig.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.prime.com.tr/ui"
                xmlns:dti="http://java.sun.com/jsf/composite/dti"
                template="../../templates/baseTemplate.xhtml">
    <f:metadata>
        <f:viewParam name="contextApplicationId" value="#{viewApplicationConfig.contextApplicationId}"/>
    </f:metadata>
    <ui:define name="title">#{viewApplicationConfig.pageTitle}</ui:define>
    <ui:define name="content">

        <p:panel id="panel" header="#{viewApplicationConfig.pageTitle}" style="width: 1280px">
            <ui:remove>
                ------ ApplicationFilterCriteriaPanel ----------
            </ui:remove>
            <dti:dtiPanel value="#{viewApplicationConfig.getPanelBean('ApplicationFilterCriteriaPanel')}"
                          toggleable="true" toggleSpeed="500">
                <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationFilterCriteriaLayer').getLayerId()}">
                    <div style="width: 600px;">
                        <div style="float: left">
                            <h:dataTable
                                    value="#{viewApplicationConfig.getLayerFields('ApplicationFilterCriteriaLayer')}"
                                    var="field">
                                <h:column>
                                    <dti:dtiField field="#{field}" record="#{record}"/>
                                </h:column>
                            </h:dataTable>
                        </div>
                    </div>                
                </dti:dtiLayer>
            </dti:dtiPanel>
            <ui:remove>
                ------ End ApplicationFilterCriteriaPanel ----------
            </ui:remove>
            <ui:remove>
                ------ ApplicationGridPanel ----------
            </ui:remove>
            <dti:dtiPanel value="#{viewApplicationConfig.getPanelBean('ApplicationGridPanel')}"
                          toggleable="true" toggleSpeed="500">
                <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationGridLayer_GH').getLayerId()}">
                    <div style="width: 600px;">
                        <div style="float: left">
                            <h:dataTable value="#{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"
                                         var="field">
                                <h:column>
                                    <dti:dtiField field="#{field}" record="#{record}"/>
                                </h:column>
                            </h:dataTable>
                        </div>
                    </div>
                </dti:dtiLayer>
                <ui:remove>
                    ------ DTI GRID ----------
                </ui:remove>
                <dti:dtiGrid columns="#{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"
                             dataBean="#{viewApplicationConfig}"/>
                <ui:remove>
                    ------ END DTI GRID ----------
                </ui:remove>
            <ui:remove>
                ------ END ApplicationGridPanel ----------
            </ui:remove>
            </dti:dtiPanel>

            <ui:remove>
                ------ Debugging Code --------------
                <h1 class="title ui-widget-header ui-corner-all"
                    style="width: 1200px; margin-left: 20px;"><h:outputLabel
                        value="Welcome #{loginBean.name}"></h:outputLabel></h1>

                <h:outputText value="Theme: #{guestPreferences.theme}"/><br/>
                <h:outputText
                        value="Selected contextApplicationId -- getContextApplicationId(): #{viewApplicationConfig.contextApplicationId}"/>
                <br/>
                <h:outputText value="Grid Header -- getXmlHeader(): #{viewApplicationConfig.xmlHeader}"/> <br/>

                <h:outputText
                        value="Grid Header Fields -- getXmlHeaderFields(): #{viewApplicationConfig.xmlHeaderFields}"/>
                <br/>
                <h:outputText
                        value="Grid Header Layer Fields -- getXmlHeaderLayerFields(): #{viewApplicationConfig.xmlHeaderLayerFields}"/>
                <br/>
                <h:outputText value="Page Fields -- getPageFields(): #{viewApplicationConfig.pageFields}"/> <br/>
                <h:outputText value="Layers  getLayers(): #{viewApplicationConfig.layers}"/> <br/>
                <h:outputText
                        value="Layers  getLayer(ApplicationGridLayer_GH): #{viewApplicationConfig.getLayer('ApplicationGridLayer_GH')}"/>
                <br/>
                <h:outputText
                        value="Layers  getLayerFields(ApplicationGridLayer_GH): #{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"/>
                <br/>

                <div class="entry">
                    <h:form>
                        <h:commandLink actionListener="#{viewApplicationConfig.navigateToPageConfig}"
                                       value="Click on contextApplicationId"/>

                        <p:dataTable var="record" value="#{viewApplicationConfig.applications}"
                                     paginator="true" rows="5" id="entityTable"
                                     style="width:1220px">

                            <f:facet name="header">
                                Applications -- Size: #{viewApplicationConfig.applications.size()}
                            </f:facet>

                            <p:column headerText="ClientId" style="width:100px">
                                <h:outputText value="#{record.fieldNameList}"/>
                            </p:column>
                        </p:dataTable>
                    </h:form>
                </div>
                ------ End Debugging Code ----------
            </ui:remove>
        </p:panel>
    </ui:define>
</ui:composition>

dtiPanel.xhtml

<!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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
      <composite:attribute name="value" required="true"/>
      <composite:attribute name="toggleable" required="true"/>
      <composite:attribute name="closable"/>
      <composite:attribute name="toggleSpeed"/>
      <composite:attribute name="collapsed"/>
    </composite:interface>

    <composite:implementation>
        <p:panel id="#{cc.attrs.value.id}" header="#{cc.attrs.value.title}"
                toggleable="#{cc.attrs.toggleable}" closable="#{cc.attrs.closable}"
                toggleSpeed="#{cc.attrs.toggleSpeed}"
                collapsed="#{cc.attrs.collapsed}">
            <composite:insertChildren/>
        </p:panel>                              
    </composite:implementation>    
</html>

dtiLayer.xhtml

<!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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
      <composite:attribute name="id" required="true"/>
      <composite:attribute name="hidden"/>
    </composite:interface>

    <composite:implementation>
        <p:outputPanel id="#{cc.attrs.id}" rendered="#{!cc.attrs.hidden}">    
            <composite:insertChildren/>
        </p:outputPanel>
    </composite:implementation>        
</html>

dtiGrid.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:dti="http://java.sun.com/jsf/composite/dti">

<composite:interface>
    <composite:attribute name="columns" required="true"/>
    <composite:attribute name="dataBean" required="true"/>
</composite:interface>

<composite:implementation>
    <div class="entry">
        <h:form id="gridForm">
            <p:ajaxStatus style="width:32px;height:32px;">
                <f:facet name="start">
                    <h:graphicImage value="/core/images/design/ajaxloading.gif"/>
                </f:facet>

                <f:facet name="complete">
                    <h:outputText value=""/>
                </f:facet>
            </p:ajaxStatus>
            <f:facet name="header">
                <p:messages/>
            </f:facet>
            <p:growl id="growl" showDetail="true"/>
            <h:panelGrid columns="2">
                <p:panel header="Export All Data">
                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/excel.png"/>
                        <p:dataExporter type="xls" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/pdf.png"/>
                        <p:dataExporter type="pdf" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/csv.png"/>
                        <p:dataExporter type="csv" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/xml.png"/>
                        <p:dataExporter type="xml" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>
                </p:panel>

                <p:panel header="Export Page Data">
                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/excel.png"/>
                        <p:dataExporter type="xls" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/pdf.png"/>
                        <p:dataExporter type="pdf" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/csv.png"/>
                        <p:dataExporter type="csv" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/xml.png"/>
                        <p:dataExporter type="xml" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>
                </p:panel>
            </h:panelGrid>
            <p:dataTable var="record" value="#{cc.attrs.dataBean.applications}"
                         paginator="true" rows="5" id="entityTable"

                         selection="#{cc.attrs.dataBean.selectedRecord}" selectionMode="single"
                         rowSelectListener="#{cc.attrs.dataBean.onRowSelect}"
                         onRowSelectUpdate="rowForm:display growl"
                         rowUnselectListener="#{cc.attrs.dataBean.onRowUnselect}"
                         onRowUnselectUpdate="growl"
                         onRowSelectComplete="rowDialog.show()" update="rowForm:display"
                         dblClickSelect="true"

                         style="width:1220px">

                <f:facet name="header">
                    Applications -- Size: #{cc.attrs.dataBean.applications.size()}
                </f:facet>
                <c:forEach var="column" items="#{cc.attrs.columns}">
                    <c:choose>
                        <c:when test="#{fn:toUpperCase(column.fieldId)=='SELECT_IND_GH'}">
                            <p:column selectionMode="multiple" style="width:20px"/>
                        </c:when>
                        <c:otherwise>
                            <p:column headerText="#{column.label}" filterBy="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"
                              sortBy="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"  style="width:100px">
                                <c:choose>
                                    <c:when test="#{not empty column.href}">
                                        <h:link outcome="viewApplicationConfig"
                                                value="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}">
                                            <f:param name="pageUrl" value="#{column.href}"/>
                                        </h:link>
                                    </c:when>
                                    <c:otherwise>
                                        <h:outputText
                                                value="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"/>
                                                <ui:remove>
                                        <br/>Field Id:  #{column.fieldId}
                                        <br/>Data Type: #{column.datatype}
                                        <br/>Display Type: #{column.displayType}
                                        <br/>Read Only:  #{column.isReadOnly}
                                        <br/>Visible:  #{column.isVisible}
                                        <br/>HREF: #{column.href}
                                        </ui:remove>
                                    </c:otherwise>
                                </c:choose>
                            </p:column>
                        </c:otherwise>
                    </c:choose>
                </c:forEach>
            </p:dataTable>
        </h:form>
        <p:dialog header="Edit Row" widgetVar="rowDialog"
                  resizable="false" width="700">
            <h:form id="rowForm">
                <dti:dtiPanel id="display" value="#{viewApplicationConfig.getPanelBean('ApplicationGridDetailPanel')}"
                              toggleable="true" toggleSpeed="500" collapsed="false">
                    <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationGridDetailLayer').getLayerId()}">
                        <div style="width: 600px;">
                            <div style="float: left">
                                <h:dataTable
                                        value="#{viewApplicationConfig.getLayerFields('ApplicationGridDetailLayer')}"
                                        var="field">
                                    <h:column>
                                        <ui:remove>
                                            <h:outputText
                                                    value="testX: #{cc.attrs.dataBean.selectedRecord.getFieldValue('baseShortDescription')}"/> /
                                            <h:outputText value="testX 1: #{cc.attrs.dataBean.selectedRecord.size}"/>
                                        </ui:remove>
                                        <dti:dtiField field="#{field}" record="#{cc.attrs.dataBean.selectedRecord}"/>
                                    </h:column>
                                </h:dataTable>
                            </div>
                        </div>
                    </dti:dtiLayer>
                </dti:dtiPanel>
            </h:form>
        </p:dialog>
    </div>            
</composite:implementation>
</html>

dtiField.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="field" required="true"/>
    <composite:attribute name="record" type="dti.oasis.recordset.Record" required="true"/>
</composite:interface>

<composite:implementation>      
    <ui:remove>
        <h:outputText value="FieldName 0: #{cc.attrs.record.getFieldNameList().get(0)}"/> / <h:outputText
            value="test 1: #{cc.attrs.record.size()}"/>
    </ui:remove>
    <p:outputPanel rendered="#{cc.attrs.field.isVisible and !fn:endsWith(cc.attrs.field.fieldId, '_GH')}">
        <div id="#{cc.clientId}">
            <h:panelGrid columns="2">
                <div style="width: 100%">
                    <div style="float: left; #{cc.attrs.field.style}">
                        #{cc.attrs.field.label}
                    </div>
                    <div style="float: right">

                        <h:outputText value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}" rendered="#{cc.attrs.field.isReadOnly}"/>

                        <h:inputText rendered="#{cc.attrs.field.displayType == 'TEXT' and !cc.attrs.field.isReadOnly}"
                                     value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}"/>
                        <h:selectOneMenu rendered="#{cc.attrs.field.displayType == 'SELECT' and !cc.attrs.field.isReadOnly}">
                            <f:selectItems/>
                        </h:selectOneMenu>
                        <h:selectBooleanCheckbox rendered="#{cc.attrs.field.displayType == 'CHECKBOX' and !cc.attrs.field.isReadOnly}"
                                                 value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}"/>                        
                           <ui:remove>               
                        <br/>Display Type: #{cc.attrs.field.displayType}
                        <br/>Visible: #{cc.attrs.field.isVisible}
                        <br/>Read Only: #{cc.attrs.field.isReadOnly}
                        <br/>Field Id: #{cc.attrs.field.fieldId}
                        <br/>Rows: #{cc.attrs.field.rowNum}
                        <br/>Columns: #{cc.attrs.field.colNum}
                        <br/>Field Value: #{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}
                        </ui:remove> 
                    </div>
                </div>
            </h:panelGrid>
        </div>
    </p:outputPanel>
</composite:implementation>
</html>

The bean class looks like the following:

package com.dti.admin.cwb.appconfigmgr.view;

import com.dti.admin.view.BaseAdminManagedBean;
import com.dti.view.ManagedBeanUtils;
import dti.admin.cwb.appconfigmgr.AppConfigManager;
import dti.oasis.recordset.Record;
import dti.oasis.recordset.RecordSet;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;

import java.io.Serializable;
import java.util.List;

@Component("viewApplicationConfig")
@Scope("request")
public class ViewApplicationConfig extends BaseAdminManagedBean implements Serializable {
    private AppConfigManager appConfigManager;
    private String contextApplicationId;
    private List<Record> applications;
    private RecordSet applicationRecordSet;

    //////
    private Record selectedRecord;

    public Record getSelectedRecord() {
System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- getSelectedRecord --");
        if(selectedRecord!=null){

System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- getSelectedRecord -- getRecordNumber: "+
            selectedRecord.getRecordNumber());
        }
        return selectedRecord;
    }

    public void setSelectedRecord(Record selectedRecord) {
        this.selectedRecord = selectedRecord;
    }
  //////

    public void onRowSelect(SelectEvent event) {
        System.out.println("onRowSelect");
        FacesMessage msg = new FacesMessage("Entity Selected",
           (String)((Record) event.getObject()).getFieldValue("baseShortDescription"));

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onRowUnselect(UnselectEvent event) {
        System.out.println("onRowUnselect");        
        FacesMessage msg = new FacesMessage("Entity Unselected",
            (String)((Record) event.getObject()).getFieldValue("baseShortDescription"));

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }    
    ///////////////////
    public ViewApplicationConfig() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "ViewApplicationConfig()");
    }


    @Autowired()
    public ViewApplicationConfig(AppConfigManager appConfigManager) {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- "
                + "ViewApplicationConfig(AppConfigManager appConfigManager)");

        this.appConfigManager = appConfigManager;

        this.setPageId("MaintainApplicationConfig");
        this.setAnchorColumnName("applicationId");
    }


    @PostConstruct
    public void onLoad() throws Exception {

        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "onLoad()");

        HttpServletRequest request = ManagedBeanUtils.getHttpServletRequest();

        init(request);


        //Grid Header
        setXmlHeader(getGridHeader(request));

        //From Action Class
        Record inputRecord = getInputRecord(request);

        //From prime-movicollector -- sort of
        if(applicationRecordSet == null) {
            applicationRecordSet = appConfigManager.loadAllWebApplications(inputRecord);
            applications = ManagedBeanUtils.convertRecordSetToList(applicationRecordSet);
        }
        //

        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " + applications.size());
    }

    @PreDestroy
    public void onUnload() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "onUnload()");
        terminate();
    }


    public void navigateToPageConfig(ActionEvent actionEvent) {
        System.out.println("navigateToPageConfig("+contextApplicationId+")");
        String pageUrl = "/pageconfigmgr/maintainPageConfig.do?contextApplicationId=" + contextApplicationId;
        navigateToPage(pageUrl);
    }

    public AppConfigManager getAppConfigManager() {
        return appConfigManager;
    }

    public void setAppConfigManager(AppConfigManager appConfigManager) {
        this.appConfigManager = appConfigManager;
    }

    public List<Record> getApplications() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "getApplications()");
        return applications;
    }

    public void setApplications(List <Record> applications) {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "setApplications(RecordSet applications)");
        this.applications = applications;
    }

    public RecordSet getApplicationRecordSet() {
        return applicationRecordSet;
    }

    public void setApplicationRecordSet(RecordSet applicationRecordSet) {
        this.applicationRecordSet = applicationRecordSet;
    }

    public String getContextApplicationId() {
        return contextApplicationId;
    }

    public void setContextApplicationId(String contextApplicationId) {
        this.contextApplicationId = contextApplicationId;
    }

}

Did anyone have a similar issue using composite components, p:dataTable and p:dialog?

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Michael
  • 21
  • 1
  • 2
  • we are using Primefaces 3.0M2 with Mojarra 2.0.6. What versions are you using? We have a similar problem according to your description (I did not run your code to compare). We have several composites on a page and with F5 or an ajax update (from commandButton or else) the composites forget all their information. The Tags declared in the composite implementation are rendered, but they are empty. All data passed through attributes is gone. Does this correspond with your problem? – user342495 Aug 04 '11 at 15:14

1 Answers1

0

I didn't read through the whole code as you didn't point me to a specific piece of code like "when I click the <p:commandButton id="someButton" ..." so I'm just 'taking a guess'.

I see the backing bean is request scoped using Spring's container. I think the problem you're experiencing is that the bean has the lifespan of one request. If you're doing AJAX things like selecting rows in a data table you need a view scoped bean. Have a look at this question for an explanation of different scopes.

I'm also guessing that you now want to use a view scoped bean, and I know Spring doesn't have a @Scope("view") you can use. Luckily Cagatay Civici came to the rescue and has posted a solution on his blog.

Community
  • 1
  • 1
siebz0r
  • 18,867
  • 14
  • 64
  • 107