I created a sample project with Netbeans 8 using Glassfish 4.
I created entity classes from database, then created JSF pages from those entity classes (from templates in Netbeans).
However, when I click on view button it shows regarding database entry in dialog box in the same window.
This is the command button which shows the dialog box:
<p:commandButton id="viewButton" icon="ui-icon-search" value="#{bundle.View}" update=":CustomerViewForm" oncomplete="PF('CustomerViewDialog').show()" disabled="#{empty customerController.selected}"/>
This is the dialog box I want to open in seperate window
This is the View.xhtml file viewButton refers:
<ui:composition>
<p:dialog id="CustomerViewDlg" widgetVar="CustomerViewDialog" modal="true" resizable="false" appendTo="#(body)" header="#{bundle.ViewCustomerTitle}">
<h:form id="CustomerViewForm">
<h:panelGroup id="display">
<p:panelGrid columns="2" rendered="#{customerController.selected != null}">
<h:outputText value="#{bundle.ViewCustomerLabel_customerId}"/>
<h:outputText value="#{customerController.selected.customerId}" title="#{bundle.ViewCustomerTitle_customerId}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_name}"/>
<h:outputText value="#{customerController.selected.name}" title="#{bundle.ViewCustomerTitle_name}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_addressline1}"/>
<h:outputText value="#{customerController.selected.addressline1}" title="#{bundle.ViewCustomerTitle_addressline1}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_addressline2}"/>
<h:outputText value="#{customerController.selected.addressline2}" title="#{bundle.ViewCustomerTitle_addressline2}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_city}"/>
<h:outputText value="#{customerController.selected.city}" title="#{bundle.ViewCustomerTitle_city}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_state}"/>
<h:outputText value="#{customerController.selected.state}" title="#{bundle.ViewCustomerTitle_state}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_phone}"/>
<h:outputText value="#{customerController.selected.phone}" title="#{bundle.ViewCustomerTitle_phone}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_fax}"/>
<h:outputText value="#{customerController.selected.fax}" title="#{bundle.ViewCustomerTitle_fax}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_email}"/>
<h:outputText value="#{customerController.selected.email}" title="#{bundle.ViewCustomerTitle_email}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_creditLimit}"/>
<h:outputText value="#{customerController.selected.creditLimit}" title="#{bundle.ViewCustomerTitle_creditLimit}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_discountCode}"/>
<h:outputText value="#{customerController.selected.discountCode}" title="#{bundle.ViewCustomerTitle_discountCode}"/>
<h:outputText value="#{bundle.ViewCustomerLabel_zip}"/>
<h:outputText value="#{customerController.selected.zip}" title="#{bundle.ViewCustomerTitle_zip}"/>
</p:panelGrid>
<p:commandButton value="#{bundle.Close}" onclick="CustomerViewDialog.hide()"/>
</h:panelGroup>
</h:form>
</p:dialog>
</ui:composition>
I want to see the dialog box in separate window.
How should I change the project to see this dialog box in new window?
I tried changing button to a commandLink, adding action attribute to redirect to View.xhtml, adding target="_blank", etc. but couldn't find proper solution.
Related
I have a app created by JSF using Primefaces templates in Netbeans.
One of the pages is a Create.xhtml to insert new record in a mysql database. This page is called by a button in a footer of a List od records.
The problem that when I select this page, the form is empty, only have title and buttons. The outputLabel and inputText are "hidden" (inspecting the page in browser). But if I select first a record in the List and next the Create page the outputLabel and inputText already are visible, but with values.
I want that when I select the Create page this came in an empty form and when I want insert the values I wanted in database.
The code of List.xhtml:
<h:form id="DistritoCreateForm">
<p:panel header="#{bundle.CreateDistritoTitle}">
<h:panelGroup id="display">
<p:panelGrid columns="2" rendered="#{distritoController.selected != null}">
<p:outputLabel value="#{bundle.CreateDistritoLabel_nomeDistrito}" for="nomeDistrito" />
<p:inputText id="nomeDistrito" value="#{distritoController.selected.nomeDistrito}" title="#{bundle.CreateDistritoTitle_nomeDistrito}" required = "true" />
</p:panelGrid>
<p:commandButton actionListener="#{distritoController.create}" value="#{bundle.Save}" update="display,:growl" oncomplete="handleSubmit(args,'DistritoCreateForm');" action="List.xhtml"/>
<p:commandButton value="#{bundle.Cancel}" action="List.xhtml"/>
</h:panelGroup>
</p:panel>
</h:form>
The code of Create.xhtml:
<h:form id="DistritoListForm">
<p:panel header="#{bundle.ListDistritoTitle}">
<p:dataTable id="datalist" value="#{distritoController.items}" var="item" style="width:50%;"
selectionMode="single" selection="#{distritoController.selected}"
paginator="true"
paginatorPosition="bottom"
rowKey="#{item.id}"
rows="10">
<p:ajax event="rowSelect" update="createButton viewButton editButton deleteButton"/>
<p:column filterBy="#{item.nomeDistrito}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="#{bundle.ListDistritoTitle_nomeDistrito}"/>
</f:facet>
<h:outputText value="#{item.nomeDistrito}"/>
</p:column>
<f:facet name="footer">
<p:commandButton id="createButton" icon="ui-icon-plus" actionListener="#{distritoController.prepareCreate}" action="Create.xhtml"/>
<p:commandButton id="viewButton" icon="ui-icon-search" action="View.xhtml"/>
<p:commandButton id="editButton" icon="ui-icon-pencil" action="Edit.xhtml"/>
<p:commandButton id="deleteButton" icon="ui-icon-trash" actionListener="#{distritoController.destroy}" update=":growl,datalist" disabled="#{empty distritoController.selected}"/>
</f:facet>
</p:dataTable>
</p:panel>
</h:form>
So effectively (it cannot be seen in your code since it is not an mcve)
You select something
As a consequence a certain variable is set to be used in the shared 'show'/'edit'/'create' page/dialog
Next you press the create button and the same page/dialog is shown with the content from the selection before.
A simple deduction then is that the 'selected' variable is not cleared in the method that is called when the create button is pressed (#{distritoController.prepareCreate})
Solution:
Clear the variable (e.g. by creating a new empty instance of the object...
Effectively this is not a PrimeFaces problem (same would happen with plain jsf too) and it sort of is not a 'java' problem either but a plain coding issue.
I have a problem with primefaces datatables. I have one datatable with some entries and a column with a button inside. If the button is pressed a popup is opened with another datatable. The entries in the second datatable are depending on the row in which the button is pressed.
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Entries" widgetVar="edit_entries" modal="true"
resizable="false">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</p:dialog>
</form>
Bean2
public void updateEntries(Item selectedItem) {
this.entriesList = this.entriesQuery.getAllEntriesByItemID(selectedItem.getId());//db query could take some time
System.out.println("entrieslist size: " + this.entriesList.size()); //prints the correct size
}
The problem is that there are no entries listed in the popup datatable although there are some in the list after the db query.
Any ideas how to fix this bug?
Thanks in advance!
UPDATE 1:
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries" update=":dialogUpdateEntries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
</h:form>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Enries" id="dialogUpdateEntries" widgetVar="edit_entries" modal="true"
resizable="false">
<h:form id="formEntriesList">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</form>
</p:dialog>
You're indeed not updating the data table in the dialog. JSF doesn't automatically update the view on change of the model, you have to explicitly tell the view to do so. You can use the ajax action component's update attribute for this. This takes a JSF client ID which can be found by rules as outlined in this related answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".
Given the markup as shown in the question, that'll be
<p:commandButton ... update=":list:list2" />
However, there's another potential problem. You're using <p:dialog modal="true"> inside a form instead of giving the dialog its own form. This way the dialog may not be available in the HTML DOM tree as JavaScript (the one responsible for dealing with ajax stuff) would expect to find it. Giving the dialog its own form should fix this matter. It'll also fix the potential future problems with invoking actions from inside the dialog as handled in this related question: <p:commandbutton> action doesn't work inside <p:dialog>.
<h:form id="viewForm">
...
<p:commandButton ... update=":editDialog" />
...
</h:form>
<p:dialog id="editDialog" modal="true">
<h:form id="editForm">
...
</h:form>
</p:dialog>
Try adding update="list2" to Edit Entries command button (even update="#widgetVar(edit_entries)" should work).
If, because of page layout and structure, you can't target the second datatable using above suggestions, then add styleClass="tList2" to second table, and update it with update="#(.tList2)" on edit button.
I am trying to update a primefaces form (wizard-first step) after an ajax command button request with no success. The command button that makes the actual ajax call is on a dialog. I would like after submitting the request to force my view to refresh.
The command button deletes a record from a datatable. It works fine, record is deleted but when dialog is hidden the datatable keeps displaying the deleted record. I would like to force it somehow to refresh. Any ideas? Could I do it from my backing bean reviewManagerBean.deleteProtocol() method?
Here is the code (my BackBean is viewScoped):
<h:form id="reviewManagerForm">
...
<pe:masterDetail id="masterDetail" level="#{reviewManagerBean.currentLevel}" showBreadcrumb="false" selectLevelListener="#{reviewManagerBean.levelListener}" >
<f:facet name="header" >
<h:panelGroup layout="block" style="margin-top: 10px;" >
<h:panelGroup styleClass="levelTitle ui-state-default ui-corner-all wizard-breadcrumbs#{reviewManagerBean.currentLevel eq 1 ? 'ui-state-hover' : ''}">
<h:outputText value="1: Protocol picker"/>
</h:panelGroup>
...
<p:messages id="mainMessagesPanel" showDetail="true" closable="true" />
</h:panelGroup>
</f:facet>
<pe:masterDetailLevel level="1">
<p:panel id="panel1" header="List of available protocols">
<p:dataTable id="protocolsDataTable" var="cRProtocol" rowKey="#{cRProtocol.revProtId}" value="#{reviewManagerBean.cRReviewProtocolList}"
widgetVar="protocolsTable"
...
selection="#{reviewManagerBean.selectedReviewProtocol}"
selectionMode="single" >
...
<p:ajax event="rowSelect" listener="#{reviewManagerBean.setSelectedRow}" />
<p:ajax event="rowUnselect" listener="#{reviewManagerBean.unsetSelectedRow}"/>
...
<p:column sortBy="#{cRProtocol.revProtTitle}" headerText="Title" style="width:200px;text-align:center;">
<h:outputText value="#{cRProtocol.revProtTitle}" />
</p:column>
...
<p:column>
<p:commandButton value="Delete" onclick="dlg5.show()"
update=":reviewManagerForm:deleteSingleProtocol"
disabled="#{reviewManagerBean.checkifProtocolIsOpen(cRProtocol)}"
ajax="true" process=":reviewManagerForm:deleteSingleProtocol" />
</p:column>
</p:dataTable>
</p:panel>
...
<p:dialog id="dialog-deleteprotocol" header="Delete Image Type" widgetVar="dlg5" dynamic="true" modal="true" resizable="false">
<p:panelGrid id="deleteSingleProtocol">
<p:row>
<p:column>
<h:outputText value="Id:" style="font-weight:bold; padding-right:10px" />
</p:column>
<p:column>
<h:outputText value="#{reviewManagerBean.selectedReviewProtocol.revProtId}" />
</p:column>
</p:row>
...
<p:column>
<p:commandButton id='protocolDelete'
value='Delete'
action='#{reviewManagerBean.deleteProtocol()}'
ajax="true"
onclick="dlg5.hide()" icon="ui-icon-disk"
update=":reviewManagerForm:protocolsDataTable"
process=":reviewManagerForm:deleteSingleProtocol" />
</p:column>
</p:row>
</p:panelGrid>
</p:dialog>
Your datatable should be re-rendered properly, you would have gotten an exception otherwise (something like component with id :reviewManagerForm:protocolsDataTable could not be found).
This means that #{reviewManagerBean.cRReviewProtocolList} will get called again. You need to remove the item from that list. This is appropriately done from #{reviewManagerBean.deleteProtocol}.
When #{reviewManagerBean.cRReviewProtocolList} is called after the removal, your datatable will get updated.
I would like to submit value form jsf page to bean from overlayPanel with checkbox like this:
To show overlay panel and ajax submission I use this code, and see it's OK in debugger:
<p:commandButton id="joinBtn" value="Basic" type="button" disabled="#{dataPropertyCurrent.notJoinable}"/>
<p:overlayPanel id="joinPanel" for="joinBtn" appendToBody="true" dynamic="false">
<f:facet name="header">Details</f:facet>
<p:dataList value="#{treeBean.getDataPropsCouldBeJoinedWith(dataPropertyCurrent)}" type="definition" var="dataJoinVal">
<h:panelGrid columns="2" cellpadding="10">
<h:column>
<p:selectBooleanCheckbox value="#{dataJoinVal.checked}" id="cbID">
<p:ajax event="change" update="cbID" partialSubmit="true"/>
</p:selectBooleanCheckbox>
</h:column>
<h:column>
<h:outputText value="#{dataJoinVal.caption}" />
</h:column>
</h:panelGrid>
</p:dataList>
<!--<p:commandButton value="Apply" id="btnApplyJoin" type="button" process="#parent" />-->
<h:outputLabel value="ID: #{dataPropertyCurrent.joinDataPropertyId}" />
</p:overlayPanel>
But after it when the overlayPanel is hidden and form submit button being pressed with this code:
<p:commandButton value="Apply join" update="joinAccordionPanel,dsAccordionPanelMain" actionListener="#{treeBean.applyJoinOptions}" />
it sets "false" to bean boolean value again.
So how to submit overlayPanel value to bean properly?
PrimeFaces version: 3.5
I've found explanation here: http://forum.primefaces.org/viewtopic.php?f=3&t=30550#p97737:
"If you are using appendToBody, it's strongly recommended to have a form inside the overlayPanel component that wraps all of the input fields and buttons. This is what you have done in your last solution. However, this means that you cannot place the overlayPanel inside another form in the xhtml page because of the limitation on nesting forms. The best solution is typically to avoid appendToBody wherever it's not absolutely necessary."
Edit
I've added <h:form> inside overlayPanel, and now it works fine:
<p:overlayPanel id="joinPanel" for="joinBtn" appendToBody="true" dynamic="true" >
<h:form id="formTmp">
<f:facet name="header">Details</f:facet>
<p:dataList value="#{treeBean.getDataPropsCouldBeJoinedWith(dataPropertyCurrent)}" type="definition" var="dataJoinVal">
<h:panelGrid columns="2" cellpadding="10">
<h:column>
<p:selectBooleanCheckbox value="#{dataJoinVal.checked}" id="cbID">
<p:ajax event="change" update="cbID" partialSubmit="true"/>
</p:selectBooleanCheckbox>
</h:column>
<h:column>
<h:outputText value="#{dataJoinVal.caption}" />
</h:column>
</h:panelGrid>
</p:dataList>
</h:form>
</p:overlayPanel>
I am trying to use Ajax with a command link to update a dialog. Te form doesn't have any id, I am not able to run this page also, it says component with "dialog" not found/doesn't exist
<h:form>
<p:tabView id="tabView">
<p:tab id="tab1" title="Tab 1">
<h:panelGrid columns="1" cellpadding="10">
<h:dataTable value="#{testBean.dataList}" var="data">
<h:column>
<h:outputText value="#{data}" />
</h:column>
<h:column>
<p:commandLink action="#{testBean.loadCommentHistory(data)}"
update="dialog" oncomplete="dlg.show()">
<h:graphicImage url="resources/theme1/images/comments.gif"
styleClass="basicImageStyle" />
</p:commandLink>
</h:column>
</h:dataTable>
<p:dialog id="dialog" header="Dynamic Dialog" widgetVar="dlg">
<h:outputText value="#{testBean.commentHistory}" />
</p:dialog>
</h:panelGrid>
</p:tab>
</p:tabView>
</h:form>
The p:dataTable itself is a container. The p:commandLink is searching within the p:dataTable for an element with an id "dialog".
Solution: add an id to the form and refer to the dialog as ":formid:dialog".
Edit:
The p:tabView or the p:tab is also a container so check the id of the dialog in your browser and use that one. ;-) It should be noted to avoid id's as jdt_id4.