how to use rich:effect with a4j:include - jsf

i've got this jsf code
<f:view>
<rich:page pageTitle="My Page" markupType="xhtml">
...
<rich:panel id="content">
<a4j:include viewId="#{MyBacking.viewId}" />
</rich:panel>
and after trying a number of different ways, I've still not managed to place the following correctly in my code:
<rich:effect for="window" event="onload" type="BlindDown" params="targetId:'<different tags depending on where I place this tag>',duration:2.8" />
My aim is to have the changed element in the a4j:included part of the page change but with the effect in use. I've tried putting it in my included page, or just after the f:view and rich:page tags in the calling page but to no avail. The demo doesn't take includes into account so I'm a bit stuck. Thanks

Just target the a panel inside the rich:panel: targetId:'contentPanel'
and then
<rich:panel ..>
<h:panelGroup layout="block" id="contentPanel">
<a4j:include viewId="#{MyBacking.viewId}">
<ui:param name="targetIdParam" value="putYourTargetIdHere" />
</a4j:include>
<h:panelGroup>
</rich:panel>

Related

JSF 2.3 Facet in Composite Component with wrong ID

I have the following simple code in a composite component (using Mojarra 2.3.9 / Primefaces 7):
<composite:implementation>
<h:form id="form">
<composite:insertChildren />
<ui:fragment rendered="#{!empty cc.facets.actions}">
<div class="actions">
<composite:renderFacet name="actions" />
</div>
</ui:fragment>
</div>
</h:form>
</composite:implementation>
And the following part is used in a page, trying to fill the composite form with life:
<cc:compForm id="mySpecialForm">
<f:facet name="actions">
<p:commandButton
id="myBtn"
value="Submit"
process="#form"
update="#form">
</p:commandButton>
</f:facet>
</cc:compForm>
The form and all the children are rendered correctly and working quite well. But the button in the renderFacet block has - in my opinion - a wrong client ID, because instead of:
mySpecialForm:form:myBtn
the button only gets the following clientId:
mySpecialForm:myBtn
This leads to an error rendering the page:
Cannot find component for expression "#form" referenced from
"mySpecialForm:myBtn".:
org.primefaces.expression.ComponentNotFoundException: Cannot find
component for expression "#form" referenced from
"mySpecialForm:myBtn".
Am i doing something wrong or is this a bug in JSF/Primefaces? I also tried to configure the componentType to an #FacesComponent extending from UIForm, but in this case no form will be rendered at all.
Update 1:
I tried to create a "minimal, reproducible example (reprex)" like mentioned by Kukeltje. All what is needed are those 2 Parts in a web application (both files under resources):
cc/compForm.xhtml:
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:composite="http://xmlns.jcp.org/jsf/composite">
<composite:interface name="compForm" displayName="A composite form">
<composite:facet name="actions" />
</composite:interface>
<composite:implementation>
<h:form id="form">
<composite:insertChildren />
<composite:renderFacet name="actions" />
</h:form>
</composite:implementation>
</html>
compFormTest.xhtml:
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:cc="http://xmlns.jcp.org/jsf/composite/cc">
<cc:compForm id="mySpecialForm">
<h:inputText id="inputParam" value="" />
<f:facet name="actions">
<h:commandButton id="myBtn" value="Test" />
</f:facet>
</cc:compForm>
</html>
All todo is call the .xhtml page: http:localhost/YOUR_APP/compFormTest.xhtml.
After using it (at least with Mojarra JSF implementation), the input field has the following correct client ID mySpecialForm:form:inputParam. But the command button retrieves another client ID outside the form: mySpecialForm:myBtn, what is a bug from my point of view, regarding the JSF VDL: " ... will be rendered at this point in the composite component VDL view.".
But as i downstriped the example files, it is clearly not a primefaces problem, because the wrong client ID is also included, if using the standard h:commandButton component.
Perhaps someone can use the mentioned 2 files above in a MyFaces environment to check if the behaviour differs or is the same?
Or has someone a workaround in mind? Using an additional #FacesComponent and moving the button from facet to the right spot under the form leads to the following "funny" duplicate ID error:
"Cannot add the same component twice: mySpecialForm:form:myBtn" (at least the client ID was what i expected in the first place)

Every include should refer to other instance

I include a part of the XHTML page to my Web Application. This part can be included multiple times. And that's the problem! Because every include refers to the same java object. That means that every element has the same value. But I want for each include a new Java object. So whats the best way to solve this problem?
Main page with includes:
<ui:composition template="./templates/template.xhtml">
<ui:define name="mainContent">
<ui:include src="include/includeAbleEditor.xhtml">
<ui:param name="includeParam" value="MyClass" />
</ui:include>
<ui:include src="include/includeAbleEditor.xhtml">
<ui:param name="includeParam" value="YourClass" />
</ui:include>
</ui:define>
includAbleEditor.xhtml
<h:commandButton value="#{editorVisibility.evb.value}"
action="#{editorVisibility.evb.toggle}" />
<h:inputTextarea rendered="#{editorVisibility.evb.enabled}" />
This <h:inputTextarea> is an example for my problem. Every included inputTextarea has a toggle button. By clicking the button the textarea should be shown or hidden. But because of the same reference of the boolean value all <h:inputTextarea> will always have the same rendered value.
Do you have any suggestions?
Thanks a lot!
You'll have to hold as many instances of editorVisibility.evb as you have editors. You could for example create a List<TypeOfEvb> evbList in your EditorVisibility bean, and pass only one element to the <ui:include> as a <ui:param>:
Main page
<ui:include src="include/includeAbleEditor.xhtml">
<ui:param name="includeParam" value="MyClass" />
<ui:param name="evb" value="#{editorVisibility.evbList[0]}" />
</ui:include>
includAbleEditor.xhtml
<h:commandButton value="#{evb.value}"
action="#{evb.toggle}" />
<h:inputTextarea rendered="#{evb.enabled}" />
You could also create a composite component.
See also:
http://www.mkyong.com/jsf2/composite-components-in-jsf-2-0/

JSF page reload without the background

I have to make a webpage with jsf and primafecas, but I don't have to much experience with it. I have to change the content of the page without reloading everything( the background is quite large).
I made a menu(with toolbar) and an iframe to easily change the content (gmap, text, forms, datatable etc). I know it is one of the worst solution, but I couldn't find better.
Now I have to change the menu from the iframe, but it looks impossible, so I'd like to use a nice method instead of the iframe. I tried a few things, but nothing worked well, sometimes i got duplicate id error or nothing worked, but sometimes nothing rendered except the menu.
Now the code looks like this:
<ui:define name="menu">
<h:form id="menuForm">
<p:toolbar activeIndex="#{navigationBean.pageCount}">
<p:toolbarGroup align="right">
<p:commandButton value="menu1" action="#{navigationBean.setUrl(...)}" update=":frmContent,menuForm" />
<p:commandButton value="menu2" action="#{navigationBean.setUrl(...)}" update=":frmContent,menuForm" />
<p:commandButton value="menu3" action="#{navigationBean.setUrl(...)}" update=":frmContent,menuForm" />
<p:commandButton value="menu3" action="#{navigationBean.setUrl(...)}" update=":frmContent,menuForm"/>
</p:toolbar>
</h:form>
</ui:define>
<ui:define name="content">
<h:form id="frmContent" style="height:100%;width:100%" height="100%" width="100%">
<iframe src="#{navigationBean.url}" id="frame" frameborder="0" style="height:100%;width:100%" height="100vh" width="100%"/>
</h:form>
I need a working method to change the content or the whole page without the background.
Try using
<ui:include src="#{navigationBean.url}" />
instead of the iframe.

Jsf 2.0-<ui:include>xhtml included always even if rendered is false

I have a home page xhtml where i am including 3 child xhtml based on conditions.
The issue i am facing is , whatever be the scenario,Book.xhtml always gets invoked.
I changed the rendered condition to false or move out to another condition, but the file always gets invoked Due to which its backing bean also is invoked causing unwanted overhead.
Please provide me a solution
<ui:composition template="/xhtml/baseLayout.xhtml">
<ui:define name="browserTitle">
<h:outputText value="HOME PAGE" />
</ui:define>
<ui:define name="header">
<ui:include src="/xhtml/header.xhtml" />
</ui:define>
<ui:define name="bodyContent">
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.SUPER)}" >
<ui:include src="/xhtml/SuperUser.xhtml" />
</h:panelGrid>
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.MAINTENANCE)}" >
<ui:include src="/xhtml/Maintenance.xhtml" />
</h:panelGrid>
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.PRINT)}">
<ui:include src="/xhtml/Book.xhtml" />
</h:panelGrid>
</ui:define>
</ui:composition>
This is happening due to lifecycle of jsf. JSF UIComponents are evaluated during view render time where as jstl tags are evaluated at build time.
So when you use rendered attribute of h:panelGrid it is too late to not invoke managed beans under the included page. To resolve this try having conditions using jstl tag, the following should work for you.
<c:if test="#{bean.yourCondition}">
<h:panelGrid width="100%">
<h:outputText value="#{bean.yourCondition}"/> <!--if this is not getting printed there is smtg wrong with your condition, ensure the syntax, the method signature is correct-->
<ui:include src="/xhtml/Book.xhtml" />
</h:panelGrid>
</c:if>
<c:if test="#{!bean.yourCondition}">
<h:outputText value="#{bean.yourCondition}"/> <!--This should print false-->
</c:if>
The document below describes the details of jstl and jsf lifecycle.
http://www.znetdevelopment.com/blogs/2008/10/18/jstl-with-jsffacelets/
Check the following document to see another way to solve this without using jstl tags.
http://pilhuhn.blogspot.com/2009/12/facelets-uiinclude-considered-powerful.html
Do this:
Always include the sub pages
Put the panelGrid (with the rendered) inside the page that you always include
Why ? Because the inclusion is performed before the rendered is evaluated.

JSF 2 AJAX - reload whole div (e.g. <ui:include src="toReloadData.xhtml" />)

I'm working with jsf2 and want to use the ajax-functionality of it. Problem: I've already seen some ajax refresh things. But nothing to refresh a whole div...
I have a xhtml page with data from my bean, and i don't really want to refresh all fields of it, it would be easier to refresh the whole ui:include...
does anybody knows a solution? Or do I have to refresh all fields manually?
best regards
Just put them in some container component with an ID and use it in render attribute of f:ajax.
<h:form>
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax render=":foo" />
</h:commandButton>
</h:form>
<h:panelGroup id="foo" layout="block">
<ui:include src="include.xhtml" />
</h:panelGroup>
Note that <h:panelGroup layout="block"> renders a <div>. If you omit the layout attribute, it defaults to <span> (only whenever there are any attributes which needs to be rendered to HTML, like id).
Okay BalusC, but I'm still having a problem with the includes and ajax.
my index.xhtml includes a search.xhtml and a results.xhtml
the ajax-part is in search.xhtml and the toRender-id is in results.xhtml...
so at rendering the jsf-tags there's the problem that there's no toRender-Id at this time...
EDIT:
Okay the problem was not the arrangement of the includes, it was that the ajax-parts must be in the same form tag like this:
<h:form>
<div id="search" class="search">
<ui:insert name="search" >
<ui:include src="search.xhtml" />
</ui:insert>
</div>
<h:panelGroup id="ajaxResult" layout="block">
<ui:insert name="searchResults" >
<ui:include src="searchResults.xhtml" />
</ui:insert>
</h:panelGroup>
</h:form>
search contains f:ajax tag, ajaxResult is toRenderId
best regards, emre

Resources