2

I'm using primefaces 3.5 with JSF mojarra 2.2.
I've a page with two ui:include which are wrapped in a p:dialog and ui:param is being used to pass values in/out of the includes.

<p:dialog header="Customer Selection Criteria" widgetVar="customerSelectionDialog" width="1200" position="center" appendToBody="true">
    <h:form id="customerForm">
        <p:outputPanel id="customerSelection">
            <ui:include src="../INTERNAL/8500.xhtml">
                <ui:param name="showCidSelect" value="1" /> 
                <ui:param name="targetObject" value="#{customerDetailsInquiry.cf8444.cg1014.cg1014cidnumb}" />
            </ui:include>
            <p:commandButton rendered="false" value="#{COMMON.COMMON_SELECTBUTTON}" action="#{customerDetailsInquiry.tchelp.handleReturnFromCustomerSelectionCriteria}" oncomplete="customerSelectionDialog.hide();" update=":mainForm:cf8444icg1014c1002" >
                <f:setPropertyActionListener value="#{customerSearchEngine}" target="#{flash.customerSearchEngine}"/>
            </p:commandButton>
        </p:outputPanel>
    </h:form>
</p:dialog>
<p:dialog closeOnEscape="true" modal="true" appendToBody="false" header="Entity Stack" widgetVar="entityStackDialog" width="400" >
    <h:form id="entityForm">
        <ui:include src="../INTERNAL/StackedEntity.xhtml">
            <ui:param name="displayCaption" value="CID Numbers" />
            <ui:param name="department" value="8" /> 
            <ui:param name="stackedObject" value="#{customerDetailsInquiry.cf8444.cg1014.cg1014cidnumb}" />
        </ui:include>
    </h:form>
</p:dialog>

Backing Bean:

FaceletContext faceletContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
String paramValue = (String) faceletContext.getAttribute("showCidSelect");

now the problem is with "showCidSelect" parameter.

showCidSelect determines whether to show "select" button in 8500.xhtml or not.

Since "showCidSelect" in this above example is set to "1", select button should be rendered.

Without the second dialog for "StackedEntity.xhtml" this works perfectly fine.

But when i put second dialog and its ui:param's this stops working and FaceletContext getAttribute call returns null.

As of now i'm forced to include "showCidSelect" in both dialogs, then everything works fine. But i somehow feel there is some other better possible solution for this problem.

Request expert help

Joffrey Hernandez
  • 1,809
  • 3
  • 21
  • 39
satya
  • 164
  • 1
  • 8

1 Answers1

0

It actually solved the same problem here by rewriting ui:include and ui:param to a custom JSF tag in a taglib.

Then you have a nice and easy to reuse tag, like:

<widgets:showCustomerSelector targetObject="#{customerDetailsInquiry.cf8444.cg1014.cg1014cidnumb}" />

And:

<widgets:stackedEntity displayCaption="CID Numbers" department="8" stackedObject="#{customerDetailsInquiry.cf8444.cg1014.cg1014cidnumb}" />

And then add new namespace to each JSF page/template where you use it (of, course):

xmlns:widgets="http://your-company/jsf/widgets/customer"

And write a taglib:

WEB-INF/widgets.jsf.taglib.xml:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib version="2.2"
                xmlns="http://xmlns.jcp.org/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">
    <namespace>http://your-company/jsf/widgets/customer</namespace>
    <tag>
        <tag-name>showCustomerSelector</tag-name>
        <description>@TODO Document this. Here goes your 8500.xhtml You had it in INTERNAL, better put templates in e.g. WEB-INF/templates/group/sub-group/ to have it out of document-root.</description>
        <source>resources/tags/show_customer_selector.xhtml</source>
        <attribute>
            <name>targetObject</name>
            <description>@TODO Document this.</description>
            <required>true</required>
            <!-- @TODO Find a **WAY** better type-hint, like an interface? -->
            <type>java.lang.Object</type>
        </attribute>
        <attribute>
            <name>rendered</name>
            <description>Whether this tag is being rendered by JSF engine.    </description>
            <required>false</required>
            <type>java.lang.Boolean</type>
        </attribute>
    </tag>
    <tag>
        <tag-name>stackedEntity</tag-name>
        <description>@TODO Document this. Here goes your StackedEntity.xhtml - keep file names lower_under_scored to avoid case-sensitive problems!</description>
        <source>resources/tags/stacked_entity.xhtml</source>
        <attribute>
            <name>displayCaption</name>
            <description>@TODO Document this.</description>
            <required>true</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>department</name>
            <description>@TODO Document this.</description>
            <required>true</required>
            <type>java.lang.Number</type>
        </attribute>
        <attribute>
            <name>rendered</name>
            <description>Whether this tag is being rendered by JSF engine.    </description>
            <required>false</required>
            <type>java.lang.Boolean</type>
        </attribute>
        <attribute>
            <name>stackedObject</name>
            <description>@TODO Document this.</description>
            <required>true</required>
            <!-- @TODO Find a **WAY** better type-hint, like an interface? -->
            <type>java.lang.Object</type>
        </attribute>
    </tag>
</facelet-taglib>

And finally, register it in web.xml:

<context-param>
    <description>JSF widget tags library</description>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/widgets.jsf.taglib.xml</param-value>
</context-param>
Roland
  • 184
  • 1
  • 14
  • **Important**: You have to include even common attributes (if you wish to use them) like `id`, `rendered`. Omitting the last one and then using it when you use your tag results your tag being **shown** as **any** not registered attribute will be ignored by JSF engine! Source/credits: https://stackoverflow.com/questions/17473377/can-i-make-jsf2-skip-rendering-my-custom-tag-without-modifying-the-tag-itself?answertab=active#tab-top @BalusC – Roland Aug 20 '17 at 22:23
  • So your `resources/tags/stacked_entity.xhtml` (and all opthers) **must** do something like: `` and closing `` at the end. – Roland Aug 20 '17 at 22:37