f:param to composite components - jsf-2

In JSF2.1 composite component if we try to pass f:param to a composite component (command button) and recieve in the component as editableValueHolder ,It doesn't seems to be working,
Any ideas?
<mycomp id="button" outcome="newpage" >
<f:param name="foo" outcome="bar" for="button"/>
</mycomp>
compositeComponent....
<cc:interface>
<cc:attribute name="action" targets="commandLink" required="true" />
</cc:interface>
<cc:implementation>
<h:commandLink id="commandLink" action="#{cc.attrs.action}">
</h:commandLink>
</cc:implementation>

Use <cc:insertChildren>.
<h:commandLink ...>
<cc:insertChildren />
</h:commandLink>

Related

Composite method do not resolve parameter if in template

it's a bit similar to this problem https://issues.jboss.org/browse/RF-11469
I have a template containing a composite defined like this:
<h:form id="transfer_list">
<ccs:criteriaPanel header="Critère de recherche"
filterAction="#{controller.filter()}">
<form:criteriaForm bean="#{controller.transferCriteria}"
rendered="#{! empty controller.transferSearchForm}"
mode="UPDATE"
controller="#{controller}" />
</ccs:criteriaPanel>
</h:form>
Controller is defined with a ui:param in the template child.
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/pages/transfer/transferList.xhtml">
<ui:param name="controller" value="#{transferListOpenController}" />
</ui:composition>
Here is the composite impl (criteriaPanel):
<cc:interface>
<cc:attribute name="header" default="#{i18n['HEADER_SEARCH_CRITERIA']}" />
<cc:attribute name="filterAction" method-signature="java.lang.Object filter()" />
<cc:attribute name="update" default="#(.ui-datatable)" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<p:panel header="#{cc.attrs.header}" toggleable="true">
<cc:insertChildren />
<f:facet name="footer">
<p:commandButton id="search_btn"
value="#{i18n['BUTTON_FILTER']}"
action="#{cc.attrs.filterAction}"
icon="ui-icon-search"
update="#{cc.attrs.update}" />
<p:commandButton value="#{i18n['BUTTON_CLEAR_FILTER']}"
action="#{cc.attrs.filterAction}"
process="#this"
immediate="true"
update="#{cc.attrs.update}">
<p:ajax update="#form" resetValues="true" />
</p:commandButton>
</f:facet>
<p:defaultCommand target="search_btn" />
</p:panel>
</div>
</cc:implementation>
Clicking on the button "filterAction" result into this:
javax.faces.FacesException: #{cc.attrs.filterAction}:
javax.el.PropertyNotFoundException: Target Unreachable, identifier
[controller] resolved to null at
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at
org.primefaces.application.DialogActionListener.processAction(DialogActionListener.java:45)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
I use Tomcat 8.5 for this and Mojarra 2.2.13. It works if I don't put the whole thing in a composite component (criteriaPanel)
UPDATE
Sample available here: https://github.com/Rapster/primefaces-test/tree/issue-sof-45834296
Works fine with MyFaces 2.2.11 and Mojarra 2.2.8-23 and 2.3.2 (I don't know how impactful upgrading to 2.3 can be though...) From what I read here https://stackoverflow.com/a/42656386/4605161, Mojarra 2.2.8 is aimed for WebLogic but it seems I will need this one (and i'm running on Tomcat)
WORKAROUND
Writing this make it work (but that's a workaround i'd rather use template):
<ui:composition xmlns="http://www.w3.org/1999/xhtml">
<ui:param name="controller" value="#{testView}" />
<ui:decorate template="/template.xhtml">
</ui:decorate>
</ui:composition>
Funny thing is if I put ui:param inside ui:decorate I'll end up with the same exception
Should be fixed in 2.2.15, see github.com/javaserverfaces/mojarra/issues/4271

f:param works only first time when using the same name in multiple commandButtons

My requierement is to upload some data and generate different reports for download with one click. In the example below I show appropriate button witch has a parameter that is sent to the download bean to select the correct version of the report.
But the f:param is only set the first time a p:commandButton is executed and then stays the same also for other buttons. Why is that and how can I solve this issue?
<h:form id="mainForm" enctype="multipart/form-data">
<p:fileUpload ...../>
....
....
<p:selectBooleanCheckbox id="opt1"
<p:ajax event="change" update="hiddingPanel"/>
</p:selectBooleanCheckbox>
<p:selectBooleanCheckbox id="opt2"
<p:ajax event="change" update="hiddingPanel"/>
</p:selectBooleanCheckbox>
<h:panelGroup id="hiddingPanel">
<p:commandButton id="doOpt1" rendered="#{bean.opt1 and !bean.opt2}"
actionListener="#{bean.readFile}" ajax="false" />
<p:fileDownload value="#{downloadBean.content}" />
<f:param name="reportType" value="REPORT1"/>
</p:commandButton>
<p:commandButton id="doOpt1" rendered="#{!bean.opt1 and bean.opt2}"
actionListener="#{bean.readFile}" ajax="false" />
<p:fileDownload value="#{downloadBean.content}" />
<f:param name="reportType" value="REPORT2"/>
</p:commandButton>
</h:panelGroup>
</h:form>
Thanks for any suggestions!
Regards.

JSF 2.2 custom validator not triggered in ui:repeat

after a desperate period of trials and errors i come to you looking for help, since now i am even unsure if i am doing it all wrong.
My code below displays some fields from a user profile in read only input text boxes. The data comes from a bean as ArrayList of "field" objects, whos properties are described in the ui:param directives.
The user can click an unlock/lock button next to the box to start/finish editing her data.
I want to trigger input validation when the user presses enter after editing or clicks the lock button.
But whatever i tried, after editing and pressing enter or clicking the button, the changed value is not written back and my custom validator is not triggered. Somehow it seems that after clicking the button the then rendered input box is not bound to the field? However, the validator works (and all attributes get passed to it) if used in an input text that is always rendered - and i don't understand it :)
Please have a look at it. If i did not explain my intent well enough or if you need more code, please let me know.
Edit: the annotations of the backing bean:
#ManagedBean( name = "beanProfile" )
#RequestScoped
The jsf code:
<ui:composition>
<ui:param name="i18n" value="#{field.i18n}" />
<ui:param name="val" value="#{field.value}" />
<ui:param name="req" value="#{field.required}" />
<ui:param name="min" value="#{field.min}" />
<ui:param name="max" value="#{field.max}" />
<ui:param name="validationType" value="#{field.validationType}" />
<ui:param name="useHidden" value="#{field.hidden}" />
<ui:param name="locked" value="#{field.locked}" />
<ui:param name="fullName" value="#{beanProfile.name}" />
<h:form id="profileFrm">
<h:outputText value="#{msg.role_profile} " styleClass="headingOutputText" />
<h:outputText value="#{fullName}" styleClass="headerTitle" />
<p />
<h:panelGroup>
<ui:repeat var="field" value="#{beanProfile.userFields}">
<h:panelGrid columns="2">
<h:outputText value="#{msg[i18n]}" styleClass="headerTitle" />
<h:message showDetail="true" for="visInput" styleClass="warn"
rendered="#{!useHidden}" />
<h:message showDetail="true" for="invisInput" styleClass="warn"
rendered="#{useHidden}" />
</h:panelGrid>
<h:panelGrid columns="2" columnClasses="nameColumn">
<h:inputText id="visInput" required="true" value="#{val}"
rendered="#{!useHidden}" readonly="#{locked}" >
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputText>
<h:inputSecret id="invisInput" required="true" value="#{val}"
rendered="#{useHidden}" readonly="#{locked}">
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputSecret>
<h:commandLink id="lock" action="#{beanProfile.lock(field)}"
rendered="#{!locked}" title="#{msg.profile_lock}">
<h:graphicImage height="16" width="16"
name="images/padlock_unlocked.svg" alt="#{msg.profile_lock}" />
</h:commandLink>
<h:commandLink id="unlock" action="#{beanProfile.unlock(field)}"
rendered="#{locked}" title="#{msg.profile_unlock}">
<h:graphicImage height="16" width="16"
name="images/padlock_locked.svg" alt="#{msg.profile_unlock}" />
</h:commandLink>
</h:panelGrid>
</ui:repeat>
</h:panelGroup>
<p />
<h:commandButton id="submitProfileBtn" value="#{msg.cmd_submit}"
styleClass="button" includeViewParams="true"
action="#{beanProfile.submitProfile()}" />
</h:form>
</ui:composition>
The origin of your problem is that you are using the RequestScoped scope for your backing bean containing the Model, so when you want to do a postback request in order to execute the backing bean method the binding just have dissapeared (not in the server memory) and the JSF lifecycle doesn't execute as expected. The solution is to use a longer scope as the ViewScoped scope. Ideally you should use the CDI compatible viewScoped scope, so you have to use JSF 2.2.x version.
Thank you lametaweb, you led me in the right direction.
Being unable to use the #ViewScoped annotation i found the link
how-to-install-cdi-in-tomcat
and followed BalusC's directions for using CDI in Tomcat. Then i had to let all the java classes implement the Serializable interface.
Now i can use the #ViewScoped annotation and the validator gets triggered.

every button click display panelGroup component(it contains 3 components)

every button click display panelGroup component(it contains 3 components).how to do it using jsf or richfaces
<h:form id="autoId">
<h:panelGroup id="pg1" columns="3" >
<rich:autocomplete mode="client" minChars="1" autofill="false"
selectFirst="false"
autocompleteMethod="#{autocompleteBean.autocomplete}"
autocompleteList="#{autocompleteBean.suggestions}"
/>
<h:inputText value=""/>
<h:inputText value=""/>
</h:panelGroup>
<a4j:commandButton value="show pg" />
</h:form>
when clicking on commanButton i like to show panelGroup
how to do it

f:param is not working with h:graphicImage

I'm getting <f:param> i.e., menuItemIndex value as null during my ajax call. Is it because it is with in <h:graphicImage> ??? Can any one suggest please? Note: Parameter is getting passed if I use <h:commandLink> instead of <h:graphicImage>.
<c:forEach items="#{cc.attrs.value}" var="menuItem" varStatus="loopItem">
....
<ui:fragment rendered="#{menuItem.hasChildren}">
<h:graphicImage library="images" name="#{menuItem.symbol}">
<f:ajax render=":fatcaForm:myMenu:menuID" event="click" listener="#{menuBean.refreshMenu}" />
<f:param name="menuItemIndex" value="{loopItem.count}" />
</h:graphicImage>
</ui:fragment>
....
</c:forEach>
The <h:graphicImage> is not a command component and it does therefore not support <f:param> children at all. The <f:param> works only when nested in an UICommand component, such as <h:commandLink> as you found out yourself.
So, this should do:
<h:commandLink action="#{menuBean.refreshMenu}">
<h:graphicImage library="images" name="#{menuItem.symbol}" />
<f:ajax render=":fatcaForm:myMenu:menuID" />
<f:param name="menuItemIndex" value="#{loopItem.count}" />
</h:commandLink>
(note that I fixed the EL syntax error in the <f:param value> as well)
Unrelated to the concrete problem, how you used the <h:graphicImage library> is not entirely right. Please carefully read What is the JSF resource library for and how should it be used?

Resources