jsf dynamically loaded content is not working - jsf

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?

Related

StreamedContent not getting populated beyond RENDER_RESPONSE [duplicate]

This question already has answers here:
Display dynamic image from database or remote source with p:graphicImage and StreamedContent
(4 answers)
Backing beans (#ManagedBean) or CDI Beans (#Named)?
(5 answers)
Closed 2 years ago.
I'm relatively new to JSF and Primefaces.
I'm trying to build a document viewer that would display tiff, jpeg and pdf.
My UI has a left and a right layout.
Left layout contains a vertical grid of thumbnails of the docs.
User clicks on a thumbnail, and the right layout displays the doc (either via a p:graphicImage or via a p:documentViewer, depending on the thumbnail clicked).
For tiffs, I'm converting the image into PNG and then displaying (both, for the thumbnail and the main display).
For multi-page tiff files, I show only the first page as the left side thumbnail...and for the main display, I give Next and Previous buttons to navigate through the pages. The UI is something like this:
The problem:
When I click on the thumbnails, the backing method gets invoked twice as expected (the second call returning the StreamedContent with the actual data).
However, when I click the Prev and Next buttons, the same backing method is getting called only once -- just for phaseid=RENDER_RESPONSE.
(eventually, this causes the bean method to return only an empty StreamedContent and not one carrying the actual image data...so I don't get to see the other pages of the tiff)
The form:
<h:form id="mainform">
<p:layout fullPage="true" style="width:100%;height:100%">
<p:layoutUnit position="west" style="width:15%;overflow:scroll;" resizable="true">
<p:panelGrid header="Thumbnails" columns="1" class="thumbcell" >
<p:repeat value="#{viewerController.docIds}" var="docId">
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('img')}" >
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('tif')}">
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.tifDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
<f:param name="forThumbnail" value="true" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('pdf')}">
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.pdfFirstPageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
</p:repeat>
</p:panelGrid>
</p:layoutUnit>
<p:layoutUnit position="center" style="width:85%;">
<p:panel id="renderpanel">
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('tif')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<p:panelGrid style="padding:0px !important;" columns="3" id="tifPanelGrid">
<p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('prev', viewerController.currentDocId)}"
id="prevButton" value="Prev" title="Previous page" disabled="#{viewerController.prevButtonDisable}"/>
<p:graphicImage rendered="#{viewerController.render}" id="tifPanel" value="#{viewerController.tifDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
<f:param name="id" value="#{viewerController.currentDocId}" />
<f:param name="forThumbnail" value="false" />
</p:graphicImage>
<p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('next', viewerController.currentDocId)}"
id="nextButton" value="Next" title="Next page" disabled="#{viewerController.nextButtonDisable}"/>
</p:panelGrid>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('img')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
<f:param name="id" value="#{viewerController.currentDocId}" />
</p:graphicImage>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('pdf')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<pe:documentViewer height="600" width="800" value="#{viewerController.pdfDocumentStream}" >
<f:param name="id" value="#{viewerController.currentDocId}" />
</pe:documentViewer>
</p:panelGrid>
</p:panel>
</p:layoutUnit>
</p:layout>
</h:form>
The controller class is annotated with these two:
javax.annotation.ManagedBean
javax.enterprise.context.SessionScoped
The backing method in the controller class, that is not getting invoked twice:
public StreamedContent getTifDocumentStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE ) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
String forThumbnail = context.getExternalContext().getRequestParameterMap().get("forThumbnail");
Doc doc = tifDocMap.get(id);
InputStream is = this.convertTiffToPng(doc, forThumbnail);
return new DefaultStreamedContent(is);
}
}
I'm on this combination: SpringBoot + JoinFaces + PF 6.2
Can any body please advise what I'm doing wrong?
An alternate way I'm considering, to achieve the purpose:
May be, turn the pages of the tiff to individual PNGs beforehand, and then use galleria ...but it would be nice if I could get galleria to work with StreamedContent of each page dynamically.

Extract Tree built-in filter to separate input

I am currently developing an app with Primefaces and recently started using a Tree component. It exactly provide the functionality that I need but I have some problems while using it inside of a dialog. When there are many records I had to surround this tree with <p:outputPanel> in order to have scroll. Everything was fine until I added filtering to that tree component. Because of surrounded panel this filter input text appears right above the tree, inside of this panel and when I scroll this down, this filter input is left above on top.
Is there a possibility that I add manually a filter input above the whole panel and connect it to the tree like it is done for example in DataTable components of PrimeFaces? Tried that way yet it is not working. Below is .xhtml of my dialog. Any help would be appreciated.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" xmlns:f="http://xmlns.jcp.org/jsf/core">
<p:dialog id="manageKnownDeviceDlg" header="#{msg['ip.usb.manageKnownDlg.Title']}" height="700"
showEffect="explode" resizable="true" modal="true" appendTo="#(body)"
width="700" widgetVar="manageKnownDeviceDlg" style="text-align: right;">
<h:form id="manageKnownDialogForm" >
<p:outputPanel style="width: 100%; max-height: 600px; min-height: 600px;height: 88%;overflow: auto;display: block; border: solid 1px;">
<p:tree id="manageKnownDevicesTree" var="knownDevice" value="#{baseModel.usbDeviceDictTreeRoot}"
widgetVar="usbDeviceDictTree"
selectionMode="checkbox" selection="#{baseModel.usbDeviceDictSelected}"
filterBy="#{knownDevice}" filterMatchMode="contains" emptyMessage="#{msg['global.noData']}"
style="text-align: left; width: 98%;">
<p:treeNode>
<h:outputText value="#{knownDevice.toString()}"/>
</p:treeNode>
</p:tree>
</p:outputPanel>
<br/>
<h:panelGrid columns="1" style="position: absolute; right: 5px;">
<h:panelGrid columns="5" style="margin-top: 10px;">
<p:commandButton value="#{msg['ip.usb.manageKnownDlg.Disable']}" update="manageKnownDevicesTree"
actionListener="#{knownDevicesDlgController.unselectKnownDeviceClasses}" styleClass="vs-button"
process="manageKnownDeviceDlg"/>
<p:commandButton value="#{msg['ip.usb.manageKnownDlg.YesToAll']}" update="manageKnownDevicesTree"
actionListener="#{knownDevicesDlgController.selectAllDevices}" styleClass="vs-button"
process="manageKnownDeviceDlg"/>
<p:commandButton value="#{msg['ip.usb.manageKnownDlg.NoToAll']}" update="manageKnownDevicesTree"
actionListener="#{knownDevicesDlgController.unselectAllDevices}" styleClass="vs-button"
process="manageKnownDeviceDlg"/>
<p:commandButton value="#{msg['global.ok']}" update="usbForm:usbDeviceTable,manageKnownDialogForm"
onclick="PF('manageKnownDeviceDlg').hide();" process="manageKnownDeviceDlg" styleClass="vs-button"
actionListener="#{knownDevicesDlgController.addKnownDevice}" style="text-align: right"/>
<p:commandButton value="#{msg['global.cancel']}" update="manageKnownDeviceDlg" styleClass="vs-button"
onclick="PF('manageKnownDeviceDlg').hide();"/>
</h:panelGrid>
</h:panelGrid>
</h:form>
</p:dialog>
</ui:composition>
Setting a max-height on the ui-tree-container solves the problem. Using this in the showcase
.ui-tree-container {
max-height: 70px;
}
Results in
You might want to add an explicit class to the tree and use that in the selector so it does not apply to all trees.

method is not invoked on p:confirmDialog

i am using JSF 2.1 primefaces 3.5
i have p:datatable on every row i have edit - delete commandLink, on delete h:commandLink i have used p:confirmDialog when i click delete h:commandLink confirmDialog popup, if i press yes commandButton action method is not invoking..
but if i put p:confirmDialog code out the form method is invoking can't understand what happening
<h:body>
<p>hello</p>
<ui:composition template="/template/mastertemplate.xhtml">
<ui:define name="content">
<f:view>
<div id="main">
<div class="full_w" style="height: auto; max-width: 1150px; overflow: hidden;">
<!-- <div class="full_w" style="height: auto; max-width: 1045px; overflow: hidden;"> -->
<div class="h_title"><p class="h_titleParagraph" style="margin: 0px;">Head of accounts</p></div>
<h:form styleClass="form" id="headOfAccountsForm">
<!-- <p:panel id="analysisTheBudgetPenel" header="Analysis The Budget"> -->
<div class="divPanel">
<div class="divContent">
<div>
<p:tabView id="headOfAccountsId_tabview">
<p:tab title="Main Head Of Accounts" id="mainHeadOfAccountsId_tab">
<p:dataTable id="allMainHeadOfAccountsId_table" value="#{budgetHeadOfAccountsAction.budgetMainHeadOfAccountsBean.budgetMainHeadOfAccountsListBean}" var="budgetMainHeadOfAccountsList" rowIndexVar="allMainHeadOfAccounts_rowIndex">
//some columns
<p:column headerText="Edit">
<h:commandLink id="deleteId_commandLink" value="delete" onclick="confirmation_widgetVar.show(); return false;" />
</p:column>
</p:dataTable>
<p:confirmDialog header="Confirmation" message="Do you want to delete this row?" widgetVar="confirmation_widgetVar">
<p:commandButton actionListener="#{budgetHeadOfAccountsAction.deleteMainHeadOfAccountsOnAjax}" value="Yes" oncomplete="confirmation_widgetVar.hide();">
<f:setPropertyActionListener target="#{budgetMainHeadOfAccountsBean.budgetMainHeadOfAccountIdBean}" value="#{budgetMainHeadOfAccountsList.budgetMainHeadOfAccountIdBean}" />
</p:commandButton>
<p:commandButton value="No" onclick="confirmation_widgetVar.hide()" type="button" />
</p:confirmDialog>
// all others closing tags..
Just try to use process attribute like
<p:commandButton style="position:absolute;right:-150px;" process="#this"
and let me know

How to right align h:panelGrid?

Im design a navigation bar for a webpage in jsf.
I want some links to be on the right of the bar and some on the left. It doesnt seem to work.
Any ideas?
<h:panelGrid columnus="2">
<h:panelGroup styleClass="alignmentLeft">
<h:panelGrid columns = "2" columnsClasses = "alignmentLeft">
<h:outputLink>... </h:outputLink>
<h:outputText/>
<h:outputLink>... </h:outputLink>
<h:outputText/>
</h:panelGrid>
</h:panelGroup>
<h:panelGroup styleClass="alignmentRight">
<h:panelGrid columns = "2" columnsClasses = "alignmentRight">
<h:outputLink>... </h:outputLink>
<h:outputText/>
<h:outputLink>... </h:outputLink>
<h:outputText/>
</h:panelGrid>
</h:panelGroup>
</h:panelGrid>
.alignmentRight {
text-align : right;
}
Try this out, there was a typing mistake in your coding as well, its the first h:panelGrid 's column you have typed "columnus"
Inside <h:head> the style sheet must be declared.
<h:head>
<h:outputStylesheet name="styles.css"
library="css" />
</h:head>
then in <h:body>
<h:body>
<h:panelGrid columns="2" width="600">
<h:panelGroup>
<h:panelGrid columns="2" columnClasses="alignmentLeft" width="200">
<h:outputLink>...1 </h:outputLink>
<h:outputLink>...2 </h:outputLink>
</h:panelGrid>
</h:panelGroup>
<h:panelGroup>
<h:panelGrid columns="2" columnClasses="alignmentRight" width="200">
<h:outputLink>...3 </h:outputLink>
<h:outputLink>...4 </h:outputLink>
</h:panelGrid>
</h:panelGroup>
</h:panelGrid>
</h:body>
In style sheet (styles.css) the styles are,
.alignmentLeft {
text-align : left;
border: 1px solid black;
background-color: orange;
}
.alignmentRight {
text-align : right;
border: 1px solid black;
background-color: lime;
}

commandLink action in ui:composition is not invoked

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?

Resources