JSF: Dynamic include page into primefaces dialog - jsf

I want to include the content of a primefaces dialog from another page with ui:include. The included page must be set dynamic depending on which button user clicked. I used the very helpful answer from BalusC from JSF dynamic include using Ajax request.
It works very fine as in the example. But problems come if I use a p:dialog instead of h:panelGroup:
<h:form>
<f:ajax render=":dialog">
<p:commandButton value="page1" action="#{productBean.setDialogPage('/page1.xhtml')}" oncomplete="dialogWidget.show()"></p:commandButton>
<p:commandButton value="page2" action="#{productBean.setDialogPage('/page2.xhtml')}" oncomplete="dialogWidget.show()"></p:commandButton>
</f:ajax>
</h:form>
<p:dialog id="dialog" widgetVar="dialogWidget" >
<ui:include src="#{productBean.dialogPage}" />
</p:dialog>
1st problem: Sometimes, I have to click a button several times before dialog appears. It seems not to follow any pattern but is a random effect. Sometimes I need to click twice, sometimes I need to click four times on the button.
2nd problem: Sometimes, the dialog appears not with the selected page but with the old one. When I close dialog and select again, the current page is loaded. It seems to be a random effect, too.
Why do I get this problems with dialog?

hy,
i don't know why you are using this mode to display dynamique dialog,
for me, i like use this mode:
<h:form>
<p:commandButton value="page1"
actionListener="#{productBean.setDialogPage('page1')}" oncomplete="PF('dialogWidget').show()" update="dialog"/>
<p:commandButton value="page2"
actionListener="#{productBean.setDialogPage('page2')}" oncomplete="PF('dialogWidget').show()" update="dialog"/>
</h:form>
<p:dialog id="dialog" widgetVar="dialogWidget">
<ui:include src="/#{productBean.dialogPage}.xhtml" />
</p:dialog>
and:
page1.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:form>
<!-- your code -->
</h:form>
</ui:composition>
it's working fine :)

If you reverse engineer existing tables with Netbeans 8 (generate entities + generate jsf pages), it will do something very similar out of the box; on the list page there is a create-button, which shows a dialog included from another page. You should try it, be sure to select "primefaces" in the last page in the guide for generating jsf pages. They do it like this:
List.xhtml:
<p:commandButton id="createButton" icon="ui-icon-plus" value="#{bundle.Create}" actionListener="#{kornstoranalyseStdController.prepareCreate}" update=":KornstoranalyseStdCreateForm" oncomplete="PF('KornstoranalyseStdCreateDialog').show()" />
Create.xhtml is included with <ui:include src="Create.xhtml"/> below </h:form> in the list-page.
Create.xhtml starts with:
<ui:composition>
<p:dialog id="KornstoranalyseStdCreateDlg" width="500px" widgetVar="KornstoranalyseStdCreateDialog" modal="true" resizable="true" showEffect="clip" appendTo="#(body)" header="#{bundle.CreateKornstoranalyseStdTitle}" hideEffect="clip" position="top">
<h:form id="KornstoranalyseStdCreateForm">
Hopefully you can tweak to suit your needs.

Related

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.

a4j Render not working

I have a modal panel similar to the one below in the xhtml page.
<h:form>
<a4j:commandLink action="" rerender="panel1">
</h:form>
<a4j:outputPanel id="panel1">
<rich:modalpanel>
<a4j:form>
<h:panelgroup binding=#{mybean.panel}/>
<a4j:commandButton id="save">
</a4j:form>
</rich:modalpanel>
</a4j:outputPanel>
When I click on the a4j command link,want to display the modal panel with differrent values. It works correctly if there is no a4j:form inside the modal panel. But I want to validate and save the attributes inside the modal panel on click of save button, and hence couldnt proceed with out the form component. But strangely when I add the a4j:form, panel group stop re rendering values. Please help me to sove this.
I also tried to place both inside same form, but then it worked in a very irregular manner.
Maybe try it this way:
<h:form>
<a4j:commandLink action="" rerender="panel1">
</h:form>
<rich:modalpanel>
<h:form>
<a4j:outputPanel id="panel1">
<h:panelgroup binding=#{mybean.panel}/>
<a4j:commandButton id="save">
</a4j:outputPanel>
</h:form>
</rich:modalpanel>
Works for me with Popuppanel

PrimeFaces dialog lazy loading (dynamic="true") does not work?

I have recently changed all my beans from RequestScoped to ViewScoped. Suddenly, the lazy loading of dialogs does not work. I am using PrimeFaces JSF library.
<html>
<h:body>
<f:view>
<h:form>
<p:commandButton id="addId" value="Add" title="Add" type="button" onclick="dlgMultiFileSelect.show();"/>
...
</h:form>
<p:dialog header="Dialog" widgetVar="dlgMultiFileSelect" modal="true" resizable="true" dynamic="true">
<ui:include src="/dialogs/media_browser.xhtml"/>
</p:dialog>
</f:view>
</h:body>
</html>
Seems like dynamic="true" does not work since the backing bean in media_browser.xhtml gets initialized immediately, and not when button is clicked.
Am I doing something wrong?
Using PrimeFaces 3.5.0.
have found some pretty easy workaround:
Let's quote BalusC's answer on this other question:
Skip executing <ui:include> when parent UI component is not rendered
The <ui:include> runs as being a taghandler during the view build time, while the rendered attribute is evaluated during the view render time.
Regarding his first proposal:
Use a view build time tag like <c:if> around the <ui:include> part.
So first add some new method to your bean. (may even be useful in some application scoped bean for reuse)
public boolean isAjaxRequest() {
boolean val = FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest();
return val;
}
Then enclose your <ui:include> inside following <c:if>:
<p:dialog id="yourDlg" header="Dialog" widgetVar="dlgMultiFileSelect" modal="true" resizable="true" dynamic="true">
<c:if test="#{applicationBean.ajaxRequest}">
<ui:include src="/dialogs/media_browser.xhtml"/>
</c:if>
</p:dialog>
So at page load time, the request isn't ajax... and on other ajax requests on base page, the dialog won't be updated...
But if you trigger your dialog
<p:commandButton id="addId" value="Add" title="Add" type="button"
oncomplete="dlgMultiFileSelect.show();" update=":yourDlg"/>
and update it's content, it will finally be rendered!
Please note following changes: The p:dialog id, p:commandButton update and p:commandButton oncomplete
Facelet tag ui:include will get processed earlier in the cycle and hence it is getting initialized. If you want to update the content of the dialog on button click, you need to do so using the update="id of the dialog" on your commandButton. You can use for your ui:include so that the page is not loaded initially.

p:dialog not showing up

I'm having a issue with JSF / Primefaces to display the popup.
As a background, I'm using JSF templates to generate my pages:
The inline works to show the datatable but when I click the button to show the dialog nothing happens. I don't see any error in the logs.
<h:body>
<p:dataTable id="lstUsers" var="u" value="#{userController.userList}" selectionMode="single"
selection="#{userController.selectedUser}" rowKey="#{u.login}" paginator="true" rows="10">
<p:column headerText="Username">
<h:outputLabel value="#{u.login}"></h:outputLabel>
</p:column>
<p:column headerText="Role" rowspan="2">
<h:outputLabel value="#{u.role}"></h:outputLabel>
</p:column>
<f:facet name="footer">
<p:commandButton id="bttAdd" type="button" value="Add" update=":contentView:idPanelPop" oncomplete="userDialog.show()" ></p:commandButton>
<p:commandButton id="bttEdit" value="Edit"></p:commandButton>
<p:commandButton id="bttRemove" value="Remove"></p:commandButton>
</f:facet>
</p:dataTable>
<p:dialog id='userDialog' header="User Details" widgetVar="userDialog"
resizable="false" width="200px" height="200px" showEffect="clip" hideEffect="fold">
<h:panelGrid id="idPanelPop" columns="2">
<h:outputLabel id='dOutUser' value="Username"></h:outputLabel>
<h:outputLabel id='dOutUserValue' value="#{userController.selectedUser.login}"></h:outputLabel>
<h:outputLabel id='dOutRole' value="Role"></h:outputLabel>
<h:outputLabel id='dOutRoleValue' value="#{userController.selectedUser.role}"></h:outputLabel>
</h:panelGrid>
</p:dialog>
</h:body>
The above code is used as part of
<ui:composition template="./maintemplate.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:define id="contentViewIndex" name="content">
<ui:include src="#{navigationController.currentPage}"></ui:include>
</ui:define>
</ui:composition>
My template page contains the following:
<p:layoutUnit position="center">
<h:form id="contentView">
<ui:insert name="content">
Default Content
</ui:insert>
</h:form>
</p:layoutUnit>
The navigationController.current value changes as per menu click to navigates across the pages.
I'm following the oficial primafaces showcase PrimeFaces datatable
I'm current setup is Netbeans 7.3 RC1 / Apache 7.0.34.0 / Mojarra 2.1.13
I'll appreacite if someone could point me to the right direction to solve this :)
EDIT: After taking account the answer inline nothing works.
Maybe I should had checked first the brower console, and in this case it's weird cause it complains that it does not recognize the widgedVar.
I already tried to put the Dialog outsite the form and the result is the same error. :/
Your bttAdd button is ordinary push button (you set it explicitly with type="button" attribute). This means it just do some JavaScript, without any AJAX requests. To do an AJAX request, and update your panel remove type="button" and try than.
I would change 2 things (first maybe not important):
Add 2 forms: one with data table inside and another inside dialog
change widgetVar="userDialog" to something unique. widgetVar="userDialogWidget"
Found the issue ...
After lots of tests and digging and taking into account the previous answers. The problem was two things:
1st. The diagonal height and width cannot have px in it.
2nd. And as per previous answers, it has to be outside as
here explained.
The p:dialog cannot have px in the sizes.

Dynamic Primefaces:tabView doesn't update

I'm using Primefaces 3.4 (also tried 3.3) and Mojarra 2.1.7. But I have a problem updating my dynamical tabs within a p:tabView.
I have 2 buttons which should add an additional tab. The first button is outside the p:tabView. When clicking this button, the backing bean is called, the p:tabView is updated, and the new tab is shown. But when I click the second button, which is inside a tab of that tabView, the backing bean is called, but the tabView is NOT updated.
This lack of updating occures only in dynamic tabs. When I modify the given example to have only one tab, and displaying a value which changes when clicking the buttons, the tabView is updated by both buttons, and the new Value is shown. So it is an problem only occuring in dynamic tabs.
Here is my code.
<f:view contentType="text/html">
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update=":ApplicationTab"/>
</h:form>
<p:tabView id="ApplicationTab" cache="false" dynamic="false" var="tab" value="#{idTestBean.tabList}">
<p:tab title="tab" closable="false" >
<p:panel>
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update=":ApplicationTab"/>
</h:form>
#{idTestBean.count}
</p:panel>
</p:tab>
</p:tabView>
</f:view>
The different tabs contains separate forms that needed to be submitted separate. therefore I had the approach of more than one form.
Well this must do the trick:
<f:view contentType="text/html">
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update="#form"/>
<p:tabView id="ApplicationTab" cache="false" dynamic="false" var="tab" value="#{idTestBean.tabList}">
<p:tab title="tab" closable="false" >
<p:panel>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update="#form"/>
#{idTestBean.count}
</p:panel>
</p:tab>
</p:tabView>
</h:form>
</f:view>
Today i did the same problem too, I had a dynamic tabview, and inside tabs, there're some panels that needed to be updated when tab changes, so what i did was, i added the p:ajax on event TabChange, and in the update attribute, i added the form id and tabviewId like this:
:formID:tabViewID
and it worked at last.
Just so you know.

Resources