commandLink action in ui:composition is not invoked - jsf

i have page with menu in left side and content in the right
every commandLink in left menu change the snippet of the content and activate function that update the current user details (every ):
in profile.xhtml :
in ui:composition tag.
<ui:define name="menuLeft">
<div id="Div2" style="width:172px; padding: 0; font-size: 10px; float:left">
<ui:include src="/users/sections/profile/profileleft.xhtml"/>
</div>
</ui:define>
<ui:define name="content">
<div id="Div3" style="background-color:white; width: 708px; height:1208px; padding: 0; font-size: 12px; float:left">
<ui:include src="/users/sections/profile/content.xhtml"/>
</div>
</ui:define>
<ui:define name="menuRight"/>
in content.xhtml:
in ui:composition tag.
<h:panelGroup id="profileContentSnippet" >
<ui:include src="#{snippetsProfileLinkerBean.snippetFileName}"/>
</h:panelGroup>
in profileleft.xhtml
in ui:composition tag.
<ui:include src="/users/source/profile/leftMenu/menu.xhtml"/>
in menu.xhtml:
in ui:composition tag.
<h:commandLink value="ViewProfilePersonalDetails" action="#{usersController.prepareConnected}">
<f:param name="pageViewId" value="ViewProfilePersonalDetails"/>
<f:ajax render="main:profileContentSnippet" />
</h:commandLink>
in editPersonalDetails-snippet.xhtml:
in ui:composition tag.
<h:outputText value="#{bundle.ViewUsersLabel_userID}"/>
<h:outputText value="#{usersController.selected.userID}" title="# {bundle.ViewUsersTitle_userID}"/>
<h:commandLink action="#{usersController.prepareProfileConnected}" value="view" actionListener="#{snippetsProfileLinkerBean.action}">
<f:attribute name="pageToViewId" value="ViewProfilePersonalDetails" />
<f:ajax render="main:profileContentSnippet" />
in viewPersonalDetails-snippet.xhtml:
in ui:composition tag.
<h:commandLink action="#{usersController.prepareProfileConnected}" value="edit" actionListener="#{snippetsProfileLinkerBean.action}">
<f:attribute name="pageToViewId" value="EditProfilePersonalDetails" />
<f:ajax render="main:profileContentSnippet" />
<h:outputText value="#{bundle.ViewUsersLabel_userID}"/>
<h:outputText value="#{usersController.selected.userID}" title="#{bundle.ViewUsersTitle_userID}"/>
</h:commandLink>
the usersController is request bean that have prepareProfileConnected function that update her selected fild with user details from DB.
the snippetsProfileLinkerBean is request bean that have two options for getting the snippet file name : by f:param or by using action(ActionEvent event) function.
when i click in the left menu everything is working i get the snippet and i see the user ID.
THE BIG PROBLEM IS when i click the edit or the view in the snippet files that also need
to activate function to get user details and change snippet, in some cases the
h:commandLink in the snippets dont work at all.
HOW can I activate h:commandLink in snippet - that will change the snippet file and also
call the function in usersController to update user details?

Related

How to invoke p:dialog with ui:include only after action event of commandLink in JSF?

I have following scenario:
Page1.xhtml
<p:datatable>
<p:column>
<p:commandLink value="#{tableRow.businessObject.xyz"
action="#{view.backingBean.view}"
partialSubmit="true" update="PageId2"
oncomplete="PF('PageVar2').show()">
<f:setPropertyActionListener value="#{tableRow}"
target="#{view.backingBean.selectedTableRow}" />
</p:commandLink>
<p:dialog modal="true" id="PageId2" widgetVar="PageVar2"
closable="true" minimizable="true" style="background-color: white"
header="Page2"
height="600" width="450" appendTo="#(body)">
<h:form>
<ui:include src="/.../Page2.xhtml"/>
<p:commandButton value="close" onclick="PF('PageVar2').hide()" partialSubmit="true"/>
</h:form>
</p:dialog>
</p:colum>
.
.
Page2.xhtml
.
.
<ui:composition>
<ui:param name="backingBean" value="#{sessionBean.currentView['Page2BackingBean']}" />
<p:datatable>
<p:column>
<h:outputLabel for="abc" value="ABC"/>
<h:outputText id="abc" value="#{view.backingBean.businessObject.abc}" />
</p:column>
</p:datatable>
</ui:composition>
.
.
While on action="#{view.backingBean.view}, it shall call generalised class view.java which will get the selected table row and create View page for Page2. But if I click on the command link before loading the Page1.xhtml, I am getting error at browser as:javax.el.PropertyNotFoundException: Could not find property businessObject in Page1.xhtml.
It looks like while loading the full page, it is trying to load the page written inside ui:include tag i.e. Page2.xhtml and it is not able to find current BusinessObject while screen loading.
How to resolve this issue??
I believe you need to pass the bean as a parameter to the Page2.xhtml. As is answered here: Passing the backing bean as a parameter to a Facelet include:
You can use <ui:param> for that. It needs to be nested in the <ui:include>.
<ui:include src="/.../Page2.xhtml"/>
<ui:param name="Bean" value="#{YourBeanName}" />
</ui:include>

Included content is rendered twice even it is excluded with rendered attribute

In a primefaces dialog I show a form with some input fields initially. If the user clicks a button an image or pdf is opened and the dialog is separated with a p:layout. For this I include the rendering of the input fields inside editProperty.xhtml and include it two times in the dialog. Inside a panelGroup to show input fields only and also inside a p:layout. I excluded the panelGroup and the layout with the rendered attribute. So my expectation is that only the dialog is shown with the layout or with the panelgroup.
The initial UI shows it without the p:layout but the fields are rendered twice.
<o:form id="editPropertyFormId">
<p:dialog id="editPropertyDialogId" widgetVar="editPropertyDialogVar" modal="true">
<!-- <c:if test="#{editPropertyContentBL.isContentViewerCollapsed() == false}"> -->
<p:layout id="editPropertiesLayoutId" style="width: 100%; height: 100%;" onResize="adjustContentViewerSize();"
widgetVar="editPropertiesLayoutVar" rendered="#{editPropertyContentBL.contentViewerCollapsed == false}">
<p:layoutUnit id="editPropertiesFieldsLayoutId" position="west" resizable="true" size="400"
style="padding-right: 5px !important;" collapsible="false">
<ui:include src="/sections/edit/editProperty.xhtml">
<ui:param name="idPrefix" value="editPropsInLayout" />
<ui:param name="editPropertyBLInstance" value="#{editPropertyBL}" />
<ui:param name="editPropertyContentBLInstance" value="#{editPropertyContentBL}" />
</ui:include>
</p:layoutUnit>
<p:layoutUnit id="editPropertiesContentViewerLayoutId" position="center" resizable="true"
styleClass="contentViewerLayout">
<ui:include src="/sections/content/contentViewer.xhtml" />
</p:layoutUnit>
</p:layout>
<!-- </c:if> -->
<!-- <c:if test="#{editPropertyContentBL.isContentViewerCollapsed() == true}"> -->
<h:panelGroup rendered="#{editPropertyContentBL.contentViewerCollapsed == true}">
<ui:include src="/sections/edit/editProperty.xhtml">
<ui:param name="idPrefix" value="editProps" />
<ui:param name="editPropertyBLInstance" value="#{editPropertyBL}" />
<ui:param name="editPropertyContentBLInstance" value="#{editPropertyContentBL}" />
</ui:include>
</h:panelGroup>
<!-- </c:if> -->
</p:dialog>
If I use c:if (uncommented in the code), it seems that the ui:parameter does not work because an update inside editProperty.xhtml does not work:
<p:inputText id="#{idPrefix}editPropertyChoiceListValueId"...
<p:commandButton update="#{idPrefix}editPropertyChoiceListValueId"
I get an exception that "editPropseditPropertyChoiceListValueId" cannot be found. Probably there is problem with ui:include/ui:param inside c:if?
Thanks
Oliver
The problem of the twice rendered contents was databinding of a dataTable inside an included xhtml:
<h:dataTable binding="#{editPropertyMainTableBinding}"
I used this to get the current row index:
<ui:param name="curDummyCssClass" value="editPropertyChoiceDummyCssClass#{editPropertyMainTableBinding.rowIndex}" />
After I eliminated this the double rendering was gone. Also the UI rendering seems to be much faster.
Also I removed the "c:if test" and the rendered stuff by putting the contents in separate xhtml files and include it:
<ui:include src="#{editPropertyContentBL.contentViewerCollapsed == true ? '/sections/dialog/editPropertyDialogContent.xhtml' : '/sections/dialog/editPropertyWithContentViewerDialogContent.xhtml'}" />
I don't think this has to do with the double rendering, but removes the unloved c:if tag.

jsf dynamically loaded content is not working

I'm trying to offer some content dynamically, that is without dedicated pages, with the help of buttons. The aforementioned content is correctly loaded, but it's not working.
The layout is like this:
<p:outputPanel style="width: 100%; height: 100%; overflow: auto;" id="contentPanel">
<c:choose>
<c:when test="#{empty requestComposition}">
<ui:insert name="body">Content</ui:insert>
</c:when>
<c:otherwise>
<ui:include src="#{requestComposition}" />
</c:otherwise>
</c:choose>
</p:outputPanel>
The button to load content is like this (inside another outputPanel):
<p:commandButton value="Load Dynamic" update=":contentPanel" actionListener="#{applicationController.processActionButton('/dynamic')}" />
The action listener is like this:
public void processActionButton(String target){
if(target == null || target.isEmpty()){
return;
}
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest req = (HttpServletRequest)context.getExternalContext().getRequest();
req.setAttribute("requestComposition", "/WEB-INF/templates" + target + ".xhtml");
}
The dynamic.xhtml is like this:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions">
<p:outputPanel style="width: 100%; padding-top: 20px;">
<p:outputPanel style="width: 60%; margin: 0 auto;">
<p:outputPanel style="text-align: center; color: gold; font-weight: bold;">Dynamic</p:outputPanel>
<p:messages id="messages" />
<h:form>
<p:panelGrid columns="2" style="width: 100%;">
<p:outputLabel value="Item" for="idItem" />
<p:outputPanel style="display: block; padding-right: 10px;" layout="inline">
<p:inputText value="#{bean.item}" id="idItem" style="width: 100%;" required="true" />
</p:outputPanel>
</p:panelGrid>
<p:outputPanel style="text-align: center;">
<p:commandButton value="Process" style="margin: 5px;" update=":growl" onclick="PrimeFaces.widgets.widget_#{fn:replace(component.clientId, ':', '_')}.disable()" oncomplete="PrimeFaces.widgets.widget_#{fn:replace(component.clientId, ':', '_')}.enable()" actionListener="#{applicationController.dummyAction}" />
<p:commandButton value="Dummy" style="margin: 5px;" update=":growl" actionListener="#{applicationController.dummyAction}" process="#this" />
</p:outputPanel>
</h:form>
</p:outputPanel>
</p:outputPanel>
</ui:composition>
When any of the buttons is clicked the form apparently submits, but the action listener is not executed.
When dynamic.xhtml is loaded as page content the form submits, but the action listener is triggered only for the second button (labelled Dummy), because of process #this, in which case the form is no longer submitted. I can workaround the form not submitting with process#this by adding onchange to input elements, but I failed to understand why is not working when it is loaded dynamically.
Thank you
I have to apologize to BalusC, since the answer he suggested was actually correct. I was tricked by the #PostConstruct which performed an unnecessary initialization for me, but the key is to use a #ViewScoped bean. That however raises another question, since it is stated in the documentation that by default there will be maximum 20 such objects stored in the server, which can be configured to a different value, but if I understood correctly that would mean that the 21st connection to the server will result in reusing the first one, so the new connection will access data not meant for it, or in discarding it and creating a new one, which means the first will lose its data?

p:command to submit a form in overlaypanel

I am trying to put a p:commandButton inside a overlayPanel, to submit the information of a h:form and redirect to another view. So, I use the property action of the button to perform this operation. I have a managed bean associated with this view but the function used for this purpose is never reached. Can u help me?
Here is the code:
advancedSearch-form.xhtml
<h:form>
<h:panelGrid width="100%">
<h:column>
....
</h:column>
....
<p:commandButton value="Submit" action="#{searchForm.save}">
</p:commandButton>
</h:panelGrid>
In another xhtml:
<h:form>
<div>
...
<div class="menu-search">
<p:commandButton id="advancedSearch" icon="ui-icon-carat-1-s" styleClass="ui-search-button" type="button"/>
<p:overlayPanel id="advancedSearchPanel" styleClass="ui-advanced-search-overlay" for="advancedSearch" hideEffect="fade" my="right top" dynamic="true" dismissable="false">
<ui:include src="/search/advancedSearch-form.xhtml"/>
</p:overlayPanel>
</div>
...
</div>
After looking over the properties of overlay, I solved this question by removing the dynamic property of overlaypanel.

jsf 2.0 f:convertDateTime for util.Date with using custom date pattern from .properties

After changing locale in action mathod with return null as I apologize page should be reload but field with date doesn't change after first click on link for changing locale. I use MyFaces
I have a page where user can set locale and after changing locale I can't get desired format of date just after second time push on link for changing locale. I use bean for localization from this post
localiztion article
I cant understand why in
<h:outputText value="#{newsVar.date}">
<f:convertDateTime pattern="#{msg['date.pattern']}" />
</h:outputText>
!!!! Edited!!!
I have some problems with getting id of dataField whem I use facets in mainLayout.xhtml
<f:view locale="#{localeManager.language}">
<div id="wrapper">
<div class="header">
<ui:insert name="header">
<ui:include src="/pages/template/commonHeader.xhtml" />
</ui:insert>
</div>
<div class="content_container">
<ui:insert name="content" />
</div>
</div>
</f:view>
commonHeader is included commandLink
<ui:composition>
<h:form>
<h1>
<h:outputText value="#{msg['header.text']}" />
</h1>
<div class="lang_selector">
<h:commandLink action="#{localeManager.changeLanguage('ru')}"
value="#{msg['header.language.ru']}">
<!-- <f:ajax render=":listGroupId:dateField" />-->
</h:commandLink>
<h:commandLink action="#{localeManager.changeLanguage('en')}"
value="#{msg['header.language.en']}">
<!-- <f:ajax render=":listGroupId:dateField" />-->
</h:commandLink>
</div>
</h:form>
</ui:composition>
And in current page I have next
<ui:composition template="/pages/layouts/mainLayout.xhtml">
<ui:define name="content">
<f:event type="preRenderView" listener="#{news.showNews}" />
<h:form id="listForm" prependId="false">
<h:panelGroup id="listGroupId">
<ui:repeat var="newsVar" value="#{news.newsList}">
<div class="news_item">
<div class="news_title">
<h1>
<h:outputText value="#{newsVar.title}" />
</h1>
<div class="news_date">
<h:outputText id="dateField" value="#{newsVar.date}">
<f:convertDateTime pattern="#{msg['date.pattern']}" />
</h:outputText>
</div>
As you can see a try to get id of "dateField" but that id in different form. I read next article How to JSF 2.0: – render components outside of the form I understand that I should set <h:form id="listForm" prependId="false"> then I can set elementId in <f:ajax/> without name of form but I get error javax.faces.FacesException - Component with id::listGroupId:dateField not found.
And I find that: The element which is specified in render must be already present in the client side HTML DOM tree. May be that's why I have this problem
Please, help me...
Why is pattern for date changed only from 2nd time?
I would recommend the following
1) change setLanguage into changedLanguage (inside that method set the language attribute)
in general , its a bad practive to use setters in action attribute , and in general use get/set prefix in actionmethods
2) add f:ajax
<h:commandLink action="#{localeManager.changedLanguage('en')}" value="#msg['header.language.en']}">
<f:ajax render="dateField"/>
</h:commandLink>
3) change h:outputText into
<h:outputText id="dateField" value="#{newsVar.date}">
<f:convertDateTime pattern="#{msg['date.pattern']}" />
</h:outputText>

Resources