'rich:component' not found: a4j:ajax with a composite component - jsf

I've built a simple composite component - a "richer" commandLink. I want it to support the clientBehavior, but when there is a <a4j:ajax> attached to the component I sometimes get the exception: ELException: Function 'rich:component' not found
It only comes when I use #{rich:component('...')} inside any attribute of <a4j:ajax>. For example oncomplete="#{rich:component('...')}.show()"
Edit: I am getting a Server error, not a JavaScript error.
The composite component (simplified):
<composite:interface>
<composite:attribute name="style" />
<composite:clientBehavior name="click" event="action" targets="commandLink" default="true"/>
</composite:interface>
<composite:implementation>
<h:commandLink id="commandLink" style="#{cc.attrs.style}">
<!-- my custom component content -->
</h:commandLink>
</composite:implementation>
The problematic use of this component looks like this:
<myLib:commandLink value="Custom CmdLink">
<a4j:ajax render="#form" execute="#form"
oncomplete="#{rich:component('myEditPopup')}"/>
</myLib:commandLink>
But the following code works like a charm:
<h:commandLink value="test">
<a4j:ajax render="#form" execute="#form"
oncomplete="#{rich:component('myEditPopup')}.show()"/>
</h:commandLink>
Edit: This one works too:
<a4j:ajax render="#form" execute="#form"
oncomplete="#{rich:component('myEditPopup')}.show()">
<myLib:commandLink value="label"/>
</a4j:ajax>

It seems to be a bug in Mojarra (we have been using the version 2.1.6), that EL lost the namespace "rich".
A working workaround was to declare the namespace in the a4j:ajax tag for each use:
<myLib:commandLink value="Show">
<a4j:ajax render="#form" execute="#form" xmlns:rich="http://richfaces.org/rich"
oncomplete="#{rich:component('myEditPopup')}.show()"/>
</myLib:commandLink>
After updating Mojarra to 2.1.26 the problem is gone and no needs for this workaround.

If you are missing { in your el, you will get the error rich:component not found.
For a4j:commandButton
<a4j:commandButton value="Show" oncomplete="#{rich:component('chargePointDetailPopup')}.show()"/>
For a4j:ajax in commandLink
<h:commandLink value="Show">
<a4j:ajax render="#form" execute="#form" oncomplete="#rich:component('chargePointDetailPopup')}.show()"/>
</h:commandLink>
Make sure to rich:popupPanel
<rich:popupPanel id="chargePointDetailPopup">
......
</rich:popupPanel>
For more Reference

Related

Bootsfaces command button raises "The subexpression 0 doesn't exist, or it can't be resolved" exception

I am using JSF 2.3 and Bootsfaces 3.3 in a small web application. I stumbled upon a scenario where Bootsfaces' <b:commandButton ajax=true ...> raises an exception while <h:commandButton>+<f:ajax> does not. Looking at the exception that gets raised Bootsfaces is not able to find the element with the given ID that should be updated in the render response phase ("ajaxUpdateMe" in the examples below).
I played around the xhtml page to nail down where the actual problem is and to me it looks like <ui:repeat ...> and an ajaxafied <b:commandButton> is not working well together.
This is the (stripped down version of the) xhtml page that I am using (minus <html> and <head> parts):
<h:body>
<b:form id="formTable">
<!-- iterate over list of objects -->
<ui:repeat value="#{testBean.list}" var="element">
<b:row>
<b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column>
</b:row>
<b:row>
<b:column>
<!-- iterate over another list -->
<h:dataTable value="#{element.innerList}" var="inner">
<h:column>
<b:commandButton ajax="true" value="submit"
action="#{testBean.submit(element)}"
update=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
process="#this" />
</h:column>
</h:dataTable>
</b:column>
</b:row>
</ui:repeat>
</b:form>
</h:body>
When I try to access the xhtml page through the browser (GET request) then an exception is immediately raised that looks like this (shortened for sake of brevity):
Caused by: javax.faces.FacesException: Invalid search expression: formTable:j_idt4:0:ajaxUpdateMe The subexpression 0 doesn't exist, or it can't be resolved. net.bootsfaces.component.commandButton.CommandButton formTable:j_idt4:0:j_idt9:0:j_idt13 Additional information: ID not found: 0 search expression: formTable:j_idt4:0:ajaxUpdateMe
at net.bootsfaces.expressions.ExpressionResolver.translateSearchExpressionToId(ExpressionResolver.java:143)
at net.bootsfaces.expressions.ExpressionResolver.getComponentId(ExpressionResolver.java:89)
at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:50)
at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:44)
at net.bootsfaces.component.ajax.AJAXRenderer.generateAJAXCallForClientBehavior(AJAXRenderer.java:582)
at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:233)
at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:177)
at net.bootsfaces.component.commandButton.CommandButtonRenderer.encodeBegin(CommandButtonRenderer.java:120)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:892)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:307)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
at com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:398)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:161)
I replaced the command button from Bootsfaces with this code here:
<h:commandButton value="submit"
action="#{testBean.submit(element)}">
<f:ajax render=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
execute="#this"/>
</h:commandButton>
Now the page loads fine and the command button does what it should do.
Checking the source of the html page in the browser I can see that the element that is mentioned in the exception message formTable:j_idt4:0:ajaxUpdateMe is actually there.
Did I hit a bug in Bootsfaces or am I doing something wrong? Does someone know a workaround where I can still use the command button from Bootsfaces?
It looks like BootsFaces ID resolver strugles with the 0 in formTable:j_idt4:0:ajaxUpdateMe. You can try to add an id="elements to the ui:repeat and then directly reference the target component via :formTable:elements:ajaxUpdateMe.
<h:body>
<b:form id="formTable">
<!-- iterate over list of objects -->
<ui:repeat id="elements" value="#{testBean.list}" var="element">
<b:row>
<b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column>
</b:row>
<b:row>
<b:column>
<!-- iterate over another list -->
<h:dataTable value="#{element.innerList}" var="inner">
<h:column>
<b:commandButton ajax="true" value="submit"
action="#{testBean.submit(element)}"
update=":#formTable:elements:ajaxUpdateMe"
process="#this" />
</h:column>
</h:dataTable>
</b:column>
</b:row>
</ui:repeat>
</b:form>
</h:body>
My IDE does not suggest ui:repeat actually has an id attribute, but it somehow works for me.
Alternatively you can add a standard f:ajax to your button:
<b:commandButton ajax="true" value="submit" process="#this">
<f:ajax render=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe" />
</b:commandButton>
I'm not sure if this is to be considered a bug. You may want to bring this up in their issue tracker

f:ajax render referencing iterated component

I have xhtml with following structure:
<h:form id="frmMain2">
<f:subview id="sub1">
<ui:repeat var="vatId" value="#{someBean.suppliesKeys()}" id="rep1">
<fieldset>
<legend>vatId</legend>
<h:panelGroup id="panel">
<ui:repeat var="item" value="#{someBean.supplies[vatId]}" id="rep2">
<f:subview id="sub2">
<h:commandLink id="command">
${item}
<f:ajax
event="click"
render=":frmMain2:sub1:rep1:0:panel">
</f:ajax>
</h:commandLink>
</f:subview>
</ui:repeat>
</h:panelGroup>
</fieldset>
</ui:repeat>
</f:subview>
</h:form>
This is running in Websphere Portlet via portlet bridge which means I am stuck with Myfaces 2.0.
The problem I am facing is that I am getting following error:
javax.portlet.PortletException: Component with id::frmMain2:sub1:rep1:0:panel not found
Notice that I am trying to reference first iteration of panel inside f:ajax render (:frmMain2:sub1:rep1:0:panel).
If I referenced something else (outside iterated part), e.g. :frmMain2:sub1:rep1, component is found and portlet works.
I am unable to find how do I reference some iterated component in render attribute.
Found following post where this problem is described as resolved in Mojarra newer version, but Myfaces 2.2.7 does not solve the problem: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
So, Is there a way to reference the component I want to render in f:ajax?
Since you only want to render the first iteration, you could create a custom component, tag, or template that encapsulates the components that you are iterating over as a workaround:
<fieldset>
<legend>vatId</legend>
<h:panelGroup id="panel">
<ui:repeat var="item" value="#{someBean.supplies[vatId]}" id="rep2">
<f:subview id="sub2">
<h:commandLink id="command">
${item}
<f:ajax
event="click"
render=":frmMain2:sub1:rep1:0:panel">
</f:ajax>
</h:commandLink>
</f:subview>
</ui:repeat>
</h:panelGroup>
</fieldset>
Then you could hard code the first option. Here's some example code (you'll definitely need to adapt this since I don't have all the info about your model data):
<h:form id="frmMain2">
<f:subview id="sub1">
<custom:component id="first" items="#{someBean.supplies[hardcodedFirstKey]}">
<f:ajax event="click" render="#this" />
</custom:component>
<ui:repeat var="vatId" value="#{someBean.suppliesKeys()}" id="rep1">
<custom:component items="#{someBean.supplies[vatId]}" rendered="#{!key eq hardcodedFirstKey}">
<f:ajax event="click" render=":frmMain:sub1:first" />
</custom:component>
</ui:repeat>
</f:subview>
</h:form>

how to awoid duplication ajax call in composite component

May be I make a fundamental mistake about jsf 2.2 specification, if so I would like to learn the correct solution of my problem. I use mojarra 2.2.9 immplementation, primemafaces 5.0.
I have a composite component with input, which always process on change event:
<cc:interface>
<cc:attribute name="value" type="java.lang.String" required="true"/>
<cc:clientBehavior name="change" event="change" targets="input"/>
</cc:interface>
<cc:implementation>
<span id="#{cc.clientId}">
<p:inputText value="#{cc.attrs.value}">
<p:ajax update="#this"/>
</p:inputText>
/* some ather component */
</span>
</cc:implementation>
And now in some cases I want to use additional listener and update some component outside cc, like clientBehavior solution:
<my:inp value="#{bean.value}">
<p:ajax event="change" listener="#{bean.listener}" update="someComponentOnPage" process="#this">
</my:inp>
Using that solution, I have 2 ajax call on 1 change event: first inside cc, second outside. Is there a solution to call ajax only once (if exist clientBehavior then not use ajax that inside)?
P.S.: sorry for my english...

<h:commandButton> is not refreshing page after actioned

hi we are using along with a4j tag.
here we are retrieving data from database after a click of button. even though the data is available in server, it will not display over view. After manual refresh of web page will lead to data diplay.
here is code snippet
.... some code here
<rich:tab id="menu5" label="Recall">
<ui:include src="/pages/mctrans/reCallMcifTrans.xhtml" />
</rich:tab>
reCallMcifTrans.xhtml contains below code
<h:commandButton type="button" id="reCallbutton1" value=" Search "
styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';"
action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
</h:commandButton>
It looks like you're working with RichFaces 3.3. So, you don't need a <h:commandButton with <a4j:support> because you can use <a4j:commandButton> that already does this. You can refactor your code to this:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" />
Make sure your reCallgrid1 component is available in the same <h:form> of the <a4j:commandButton>.
Since you also want to add a Wait while searching the data behavior when the button is clicked, you can use <a4j:status> along with the <a4j:commandButton> as shown in the <a4j:status> demo. Here's a basic example:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1" />
<!-- Note that there's no oncomplete in this case -->
<a4j:status for="reCallbutton1">
<f:facet name="start">
<h:graphicImage value="/res/images/wait.gif"/>
</f:facet>
</a4j:status>
At last but not least, you should switch your managed bean to request scope and use RichFaces powerful <a4j:keepAlive> in order to simulate JSF 2 #ViewScoped. You can even use it in form of annotation on your managed bean (no additional configuration):
#KeepAlive
public class McifRecallTransBean {
//managed bean code here...
}
When you are using request parameters inside the bean, you need to pass them again with your action :
<h:commandButton type="button" id="reCallbutton1" value="Search" styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12" oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
<f:param name="param1" value="#{param['param1']}" />
<f:param name="param2" value="#{param['param2']}" />
</h:commandButton>

JSF 2.0 - Ajax submit validation on inputs

I have a form that needs to be submitted with ajax. I am trying to get the validation to work but it wont work when I use ajax. When I take the ajax out and submit the form with an empty testinput it properly triggers he validation and does not submit the form. How can I do this with an ajax call. My form is below.
<h:form>
<f:ajax>
<h:panelGrid columns="3">
<h:outputLable for=test" value="testinput:" />
<h:inputText id=test" required="true" label="testinput" />
<h:message for="test" id="testError"/>
</h:panelGrid>
<h:commandButton value="Submit" actionListener="#{testBean.doSomething}" />
</f:ajax>
</h:form>
The <f:ajax> by default doesn't re-render the form, so you won't see anything. Replace <f:ajax> by <f:ajax execute="#form" render="#form" />.
Maybe try something like this:
<h:form id="yourFormId">
<!-- form content -->
<h:commandButton value="Submit">
<f:ajax execute="yourFormId" listener="#{testBean.doSomething}"/>
</h:commandButton>
</h:form>

Resources