I use a Primefaces carousel component to display a list of items. What i would like to do is show a commandButton on every carousel item which triggers a method on the bean to confirm or decline the entry.
Now it works only for the first entry of the carousel. Clicking on another entry does not invoke the action confirmResource. I guess it has something to do with the IDs but i can't figure it out.
Here's the form:
<h:form id="form" prependId="false">
<p:carousel id="resourceCarousel" value="#{resourceRatingBean.resourceProposalList}" var="var" rows="1" itemStyle="width:500px; height: 400px; text-align:center;" circular="true">
<p:column>
<h:panelGrid columns="1" cellpadding="3">
<p:graphicImage value="/cache/images/#{var.imagePath}" width="100"/>
<h:outputText value="#{var.imagePath}" />
<h:outputText value="#{var.name}" />
<h:outputText value="#{var.description}" />
</h:panelGrid>
<p:commandButton value="confirm" action="#{resourceRatingBean.confirmResource}" process="#this">
<f:setPropertyActionListener value="#{var}" target="#{resourceRatingBean.ratedResource}" />
</p:commandButton>
</p:column>
</p:carousel>
</h:form>
I see two likely problems here:
The process="#this" is likely an issue as this will only invoke the process of the invoke the action of the commandButton and not the changes in the carousel component. Try setting this attribute to resourceCarousel or #form instead.
If you are still having issues and using JSF 2 + EL 2.2, then instead of depending on setPropertyActionListener to set the value of a managed property, then instead you can pass the argument var to an actionListener method through an EL expression.
Here is an example:
<p:commandButton value="confirm" actionListener="${resourceRatingBean.confirmResourceListener(var)}"
this="resourceCarousel" />
Related
Hello I am trying to implement some primefaces commandbuttons in a p:datatable. My need is almost identical to this post:
f:setPropertyActionListener not invoked
Basically I need to have a column of buttons in a , click on one button will pass the object of the current row to the bean, and a dialog will pop out, showing some information of the chosen object.
The following is the relevant code:
<f:view>
<body>
<h:form id="theForm">
<p:dataTable id="testFailures" value="#{testDetails.report.failures}" var="failure"
styleClass="baseTable">
<p:column id="requestColumn">
<f:facet name="header">
<h:outputText value="Request" id="requestHeaderText" />
</f:facet>
<p:commandButton value="Detail" update="requestDialog"
oncomplete="PF('dlg1').show();" type="button">
<f:setPropertyActionListener
target="#{testDetails.selectedFailure}" value="#{failure}" />
</p:commandButton>
<h:message for="requestDialog" />
<p:dialog id="requestDialog" header="Request Dialog"
widgetVar="dlg1" dynamic="true">
<h:outputText value="#{selectedFailure.request}" />
</p:dialog>
</p:column>
</p:dataTable>
</h:form>
<h:message for="theForm" />
<h:message for="responseDialog" />
<p:dialog id="responseDialog" header="Request Dialog"
widgetVar="dlg2" dynamic="true">
<h:form>
<h:outputText value="#{selectedFailure.request}" />
</h:form>
</p:dialog>
</body>
</f:view>
I tried to put the dialog in different positions (see my "dlg1" and "dlg2"). But neither works. No dialog showing. does not show anything either. And I don't see any error message in the browser's console window. (I think there is a exclamation warning).
I have tried debug mode, and set method for the property "selectedFailure" is not called.
Try to remove type="button" from your commandButton and it should work. Also dialogs should not be placed inside dataTables so the position of "dlg2" is more correct.
I am using a primefaces dialog box. I have a list of items, and whenever I choose an item, I want the dialog box to display that item name. However, this is not happening. Rather than displaying the item name, the dialog is not displaying any name at all. I've posted my code below.
<h:form>
<h:dataTable binding="#{table}" value="#{item.itemList}" >
<h:column>
<h:link value="#{item.itemList[table.rowIndex]}" outcome="item">
<f:param name="itemName" value="#{item.itemList[table.rowIndex]}" />
</h:link>
</h:column>
<h:column>
<p:commandButton action="#{item.setItem(item.itemList[table.rowIndex])}" id="showDialogButton"
type="link" value="Delete" onclick="dlg.show()" />
</h:column>
</h:dataTable>
<br />
<p:dialog header="Item" widgetVar="dlg" resizable="false">
<!-- I've also tried Item: #{item.item} -->
<p>Item: <f:attribute name="contentId" value="#{item.item}"/> </p>
<p:commandButton id="submitButton" value="Yes" action=
"#{item.deleteItem}" oncomplete="dlg.hide();">
</p:commandButton>
<p:commandButton id="cancelButton" value="Cancel" oncomplete="dlg.hide();" />
</p:dialog>
</h:form>
My getters and setters are just generic getters and setters.
You forgot to update the dialog before opening.
<p:commandButton ... update="dialogId" />
I also suggest to use oncomplete instead of onclick to open the dialog.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to show details of current row from p:dataTable in a p:dialog and update after save
Primefaces p:dialog doesn't always show up if update="dlg" in commandButton
I have a table in a form. One of the columns in the table displays a row of buttons to edit and delete the table entries. When I delete an entry callign the controller from a button's action attribute, it works as expected.
But once I have added a dialog to let the user confirm the deletion, a wrong entry is deleted. It is always the last entry in the current table. I have no idea what the reason could be - I am using the same DataTable var for the button and for the dialog.
I am working with JSF 2 (Mojarra 2.1.6) and Primefaces 3.5 deploying on JBoss 7.1.1 on a Suse 12.2 machine.
The form:
<h:form id="downloads">
<ui:include src="components/table.xhtml"/>
</h:form>
The table:
<ui:composition>
<p:dataTable value="#{controller.currentLevelResources}"
var="download" id="downloadTable" scrollHeight="120" rows="10">
<p:column sortBy="#{download.name}">
<f:facet name="header">Name</f:facet>
<h:outputText id="downloadName" value="#{download.name}" title="#{download.description}" />
</p:column>
...
<p:column>
<ui:include src="menuBar.xhtml"></ui:include>
</p:column>
The menu bar:
<ui:composition>
<p:commandButton id="edit"
action="#{downloadEditController.editResource(download)}"
icon="ui-icon-gear" title="Edit" oncomplete="updateStyles()"
update=":downloads" />
<p:commandButton id="delete" onclick="deletedDlg.show();"
icon="ui-icon-trash" title="Delete" oncomplete="updateStyles()" />
<p:dialog header="Delete confirmation" widgetVar="deletedDlg"
resizable="false">
<h:panelGroup layout="block" style="padding:5px;">
<h:outputText
value="The Resource #{download} will be deleted. Proceed?" />
</h:panelGroup>
<p:commandButton id="deleteBtn" value="Delete"
oncomplete="deletedDlg.hide(); updateStyles(); "
action="#{downloadEditController.deleteResource(download)}"
process="#this" update=":downloads">
</p:commandButton>
<p:commandButton value="Cancel" type="button"
onclick="deletedDlg.hide();" />
</p:dialog>
If I replace the dialog with this, everything works:
<p:commandButton id="delete" icon="ui-icon-trash" title="Delete"
action="#{downloadEditController.deleteResource(download)}"
oncomplete="updateStyles()" update=":downloads" />
Creating a <p:dialog> for every row is not a good idea.
For starters you had better create a single <p:dialog> outside your <p:dataTable>.
Next thing that I would do is to set the id or the row var in your bean upon delete button click and in case of confirmation in dialog use that id or the row var from bean to delete.
This is how your delete button could look like, set the download var in prepareDataForDeletion action and show the dialog...
<p:commandButton id="deleteConfirmation" icon="ui-icon-trash" title="Delete"
action="#{downloadEditController.prepareDataForDeletion(download)}"
onsucess="deletedDlg.show();"/>
Regarding your current anomaly: it's because all your dialogs have the same widgetVar and each next one is overriding the previously declared one all the way until the last one. You could dynamically give them a different widget names like so widgetVar="deleteDlg_#{someIndex}", but this makes no sense if you can have just only one reusable dialog whose content is updated before opening.
I am trying to submit values in a pop-up panel inside another panel that has a submit/action event. But before opening pop-up panel I need to invoke a function on my managed bean that create a new entity object. The outer panel has the only h:form, since you can't nest them. I have wrapped the pop-up panel in a a4j:region to submit only this part when the use submits the values inside the pop-up panel. This works, but not the execution of the preparing function that need to be invoked when the pop-up panel executes. I have tried a4j:commandLink but that component don't work together with the rich:popupPanel (strange since both of them are Richfaces components?!). So I have to relay on the h:commandLink and use ajax.
How can I invoke a function on my managed bean when the link to open/render the pop-up panel fires?
(What is the correct pattern for this?)
PS. The initial question has changed, but not the problem concerning submitting values in a pop-up panel.
Part of the xhtml file:
<h.form>
...
<a4j:region>
<rich:popupPanel id="popup_sys_user_req" modal="false" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="Request New Sector/Category" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('popup_sys_user_req')}.hide(); return false;">
X
</h:outputLink>
</f:facet>
<h:panelGrid columns="2">
<h:outputLabel value="Request New:" />
<h:selectOneMenu id="sys_req_type" value="#{userController.selectedSysUserRequest.sysrequesttype}" required="true" >
<f:selectItems value="#{userController.getSysRequestTypeItems('SECTOR_CATEGORY')}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel value="Description:" />
<h:inputTextarea id="user_req_desc" value="#{userController.selectedSysUserRequest.description(desc)}" required="true" requiredMessage="Decription is missing" />
</h:panelGrid>
<a4j:commandButton action="#{userController.CreateSysUserRequest()}" value="Send Request" execute="sys_user_req_form" oncomplete="#{rich:component('popup_sys_user_req')}.hide(); return false;"/>
</rich:popupPanel>
</a4j:region>
</h:form>
The commandLink (re-edit)
<h:commandLink actionListener="#{userController.prepareCreateSysRequest}" value="Request New Sector/Category">
<f:ajax execute="popup_sys_user_req #this" render="popup_sys_user_req">
<rich:componentControl id="popup_ctr" event="click" target="popup_sys_user_req" operation="show"/>
</f:ajax>
</h:commandLink>
----------------------------
//Managed Bean:
public void prepareCreateSysRequest(ActionEvent event ) {
selectedSysUserRequest = new Sysuserrequest();
JsfUtil.log("Prepare Create System User Request");
}
This post continues the dicussion about the pop-up panel.
Greetings Chris.
If I understand correctly you want to submit all form elements inside popupPanel but not outside the panel when you invoke someAction1? I can think of two ways to do this:
1. a4jcommandButton has a limitToList attribute, you can list which components you want to be updated on the server
2. create your popupPanel outside of the first form and then use its own form:
<h:form>
...
<a4j:commandButton action="someAction2"...
</h:form>
<rich:popupPanel>
<h:form>
...
<a4j:commandButton action="someAction1"...
</h:form>
</rich:popupPanel>
Update
If you are using RichFaces 4 you can replace the limitToList attribute with limitRender
The problem is that the popup isn't a child of the form in jsf, you only need to use the domElementAttachment attribute to change that. So your code would look like this:
<h.form>
...
<a4j:region>
<rich:popupPanel id="popup_sys_user_req" modal="false" autosized="true" resizeable="false" domElementAttachment="form">
<f:facet name="header">
...
I have a composite displayed inside a dialog. I have an edit button that get the current bean #SessionScoped (item in a data table) and then update the UI. My app is very similar to a simple CRUD app like http://balusc.blogspot.com/2010/06/benefits-and-pitfalls-of-viewscoped.html.
The problem is that the UI is updated correctly when using <h:outputText/> but not when using a form element.
<h:inputTextarea value="#{cc.attrs.managedBean.assertionStatement}" />
<h:inputText value="#{cc.attrs.managedBean.assertionStatement}" />
<h:outputText value="#{cc.attrs.managedBean.assertionStatement}"/>
The UI shows an empty textarea and input but the outputText renders the correct value. The getAssertionStatement() is called 3 times which seems to be the correct behavior.
When I close the dialog and reopen it, everything (form element) is populated.
The dialog call (ag namespace is for composite component):
<p:dialog widgetVar="DataValueRuleDialog" modal="true" height="600" width="800">
<p:outputPanel id="DataValueRulePanel">
<ag:DataValueAssertion managedBean="#{dataValueAssertionController}" id="DataValueComposite" />
</p:outputPanel>
</p:dialog>
The composite that calls another composite:
<h:form id="DataValueForm">
<ag:assertionMetadataComponent
managedBean="#{cc.attrs.managedBean.dataValueAssertionBean.assertionMetadataBean}"
assertionStatementRows="5" />
<p:dataTable value="#{cc.attrs.managedBean.model}" var="item">
<p:column>
<f:facet name="header">Assertion Statement</f:facet>
<h:outputText rendered="#{item.profileBean.profileLocation == cc.attrs.managedBean.selectedComformanceProfile.name}" value="#{item.assertionMetadataBean.assertionStatement}" />
</p:column>
<p:column>
<p:commandButton rendered="#{item.profileBean.profileLocation == cc.attrs.managedBean.selectedComformanceProfile.name}" value="edit" immediate="true"
actionListener="#{cc.attrs.managedBean.editDataValueAssertion}" update=":DataValueComposite:DataValueForm">
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
When I remove the immediate=true the form is validated and since one of the required field (supposed to be populated) is missing, I got a validation error. This is why I have immediate=true but it should be necessary since all the items in the data table should be valid.