Rich DataTable value selection issues - jsf

I am trying to delete data table values. my data tables shows lot of values. when i click to delete particular row in my data table then confirmation dialog box open. if click okay then call to bean and delete that values to database. if click cancel then not to call to bean.. this is my functionality..
ex:
my data table show 10 rows. when i select 1 rows delete button clicked call to bean but its get another rows values pass to bean...
my UI code..
<h:commandButton image="/images/remove.png" onclick="# {rich:component('confirmation')}.show();return false"/>
<a4j:jsFunction name="submit" action="#{bean.delete}">
<f:setPropertyActionListener target="#{bean.name}" value="#{info.name}" />
</a4j:jsFunction>
<rich:popupPanel id="confirmation" width="250" height="150">
<f:facet name="header">confirmation</f:facet>
<h:panelGrid>
<h:panelGrid columns="2">
<h:graphicImage value="/images/remove.png" />
<h:outputText value="Are you sure?" style="FONT-SIZE: large;" />
</h:panelGrid>
<br></br>
<h:panelGroup >
<center><input type="button" value="OK"
onclick="#{rich:component('confirmation')}.hide();submit();return false" />
<input type="button" value="Cancel"
onclick="#{rich:component('confirmation')}.hide();return false" /> </center>
</h:panelGroup>
</h:panelGrid>
</rich:popupPanel>

I guess it has something to do with the 'AJAX calls out of sync'
The posted code lacks the table info so ill assume it has something to do with the AJAX handling.
<rich:extendedDataTable
id="myTable"
value="#{myBean.rows}"
selectionMode="single"
rows="#{crudBean.actionForm.occurrences}"
...
rowKeyVar="idx"
...>
<a4j:ajax event="selectionchange"
listener="#{myBean.selectionListener}"/>
<rich:column width="30px" styleClass="#{rowItem.className}">
<util:myInputText id="status" managedBean="#{myBean}" rowItem="#{rowItem}" rowIndex="#{idx}"/>
</rich:column>
<util:myDeleteRecord id="delete" managedBean="#{myBean}" rowItem="#{rowItem}" rowIndex="#{idx}"/>
</rich:column>
</rich:extendedDataTable>
On my components i use: rowIndex="#{idx}" to make sure i know on which row i'm editing/removing

Related

a4j:commandButton doesn't render the element

I've got a JSF page with <rich:tabPanel> which contains 4 tabs.
On the 4th tab I'm trying to use <a4j:commandButton> to execute the action and render resulTable.
Here is the shorten example
<rich:tab header="Journal">
<h:form id="filterForm">
<a4j:jsFunction name="submitByEnter"
action="#{smsLogList.refresh}" render="smsTable" />
<s:div id="divSearch">
<rich:collapsiblePanel header="#{messages['search']}"
switchType="client">
<h:panelGrid column="1">
<s:decorate template="/layout/edit.xhtml">
<ui:define name="label">Package number</ui:define>
<h:inputText id="packNum" style="width:200px"
value="#{smsLogList.packNum}">
<a4j:ajax event="keyup" listener="#{smsLogList.refresh}"
ignoreDupResponses="true" requestDelay="1500"
render="smsTable" />
</h:inputText>
</s:decorate>
<!---some other search elements-->
<s:div styleClass="actionButtons">
<a4j:commandButton id="search" value="#{messages['search']}"
render="smsTable" action="#{smsLogList.go}" />
<a4j:commandButton id="reset" value="#{messages['clear']}"
onclick="document.getElementById('filterForm').reset();"
action="#{smsLogList.clear}" render="divSearch,smsTable" />
</s:div>
</h:panelGrid>
</rich:collapsiblePanel>
</s:div>
<!--- results table-->
<h:panelGrid id="smsTable">
<s:div>
<rich:dataTable value="#{smsLogList.resultList}" var="sms"
id="table" rendered="#{not empty smsLogList.resultList}">
<rich:column>
<f:facet name="header">Type</f:facet>
<h:outputText value="#{sms.smsType}" />
</rich:column>
<!---- some other columns-->
</rich:dataTable>
<rich:dataScroller for="table" />
</s:div>
</h:panelGrid>
</h:form>
</rich:tab>
So, when I'm clicking on the <a4j:commandButton> - nothing happens, but if I'm switching to the other tab and back - the result is as necessary.
I tried to change a4j to <h:commandButton>, but after it's pressed the page switches to the first tab.
Is any solution how to work this out?
The solution is quite simple.
I used <h:form> inside other <h:form>. It will not work anyway. When I remove internal - the jsf works smooth and as it should.

Display a formatted text / message on p:confirmDialog

When a row in <p:dataTable> is right-clicked, <p:contextMenu> appears with a delete option. When this option is clicked, <p:confirmDialog> appears with two buttons Yes and No - a conformation warning about deleting the current row as follows.
<p:contextMenu for="dataTable">
<p:menuitem oncomplete="confirmDelete.show()"
value="Delete"
update="confirmDialog"
process="#this dataTable"
actionListener="#{testManagedBean.deleteActionListener}"
icon="ui-icon-close" ajax="true"/>
</p:contextMenu>
<p:confirmDialog id="confirmDialog"
widgetVar="confirmDelete"
message="#{testManagedBean.message}"
header="Message"
severity="alert"
closeOnEscape="true"
showEffect="slide"
hideEffect="fold"
appendTo="#(body)"
closable="true">
<p:commandButton id="btnYes"
value="Yes"
process="#this"
oncomplete="confirmDelete.hide()"
actionListener="#{testManagedBean.deleteActionListener}"
update="dataTable"/>
<p:commandButton id="btnNo"
value="No"
onclick="confirmDelete.hide()"
type="button" />
</p:confirmDialog>
Is there a way to set the message attribute with a formatted message on this dialog.
For example, the property testManagedBean.message in its managed bean is set to a string like
You are about to delete <font color='#ff0000'>2</font> rows. <br/>This action will never be undone. <br/>Are you sure?
The confirm dialog displays this string as a whole. HTML in this string should be interpreted as HTML. I don't see any attribute like escape in <p:confirmDialog>.
Is there a way to display this string as a formatted message.
I found an ugly solution nesting of <f:facet name="message"> within <p:confirmDialog>.
<p:confirmDialog id="confirmDialog"
widgetVar="confirmDelete"
header="Message"
severity="alert"
closeOnEscape="true"
showEffect="slide"
hideEffect="fold"
appendTo="#(body)"
closable="true">
<p:commandButton id="btnYes"
value="Yes"
process="#this"
oncomplete="confirmDelete.hide()"
actionListener="#{testManagedBean.deleteActionListener}"
update="dataTable"/>
<p:commandButton id="btnNo"
value="No"
onclick="confirmDelete.hide()"
type="button" />
<f:facet name="message">
<h:outputFormat value="#{testManagedBean.message}" escape="false"/>
</f:facet>
</p:confirmDialog>
Removing the message attribute from <p:comfirmDialog> and nesting <f:facet name="message"> inside it.
Note : <h:outputFormat> is only needed, if one or more parameters need to be passed by means of nested <f:param> to be substituted in respective placeholders ({0}) in the message text. Just keep on using <h:outputText escape="false">, if no such parameters need to be passed.

Unable to get the selected values on Dialog while using ContextMenu with Datatable

I have a requirement where I want the user to move the datatable rows up and down.I thought Context Menu would come handy as there would be a Move up and Move down menu item .For this I tried implementing the context Menu for datatable example from Primefaces Showcase. However I am not getting the selected values from the datatable rows to be displayed on the dialog.
Please find the below code:
<p:contextMenu for="availableCars">
<p:menuitem value="View" update="display" icon="ui-icon-search" oncomplete="carDialog.show()"/>
</p:contextMenu>
<p:dataTable id="availableCars" var="car" value="#{RequestBean.formFields}" rowKey="#{car.car_group}" selectionMode="single" selection="#{RequestBean.selectedField}">
<p:column headerText="Field Label">
<h:outputText value="#{car.car_label}" />
</p:column>
<p:column headerText="Field Group">
<h:outputText value="#{car.car_group}" />
</p:column>
<p:column headerText="Field Name">
<h:outputText value="#{car.car_name}" />
</p:column>
</p:dataTable>
<p:dialog header="Car Detail" widgetVar="carDialog" resizable="false"
width="200" showEffect="clip" hideEffect="fold" id="dialog">
<h:panelGrid id="display" columns="2" cellpadding="4">
<h:outputText value="Car label:" />
<h:outputText value="#{RequestBean.selectedField.car_label}" style="font-weight:bold"/>
<h:outputText value="car Group" />
<h:outputText value="#{RequestBean.selectedField.car_group}" style="font-weight:bold"/>
<h:outputText value="Car Name:" />
<h:outputText value="#{RequestBean.selectedField.car_name}" style="font-weight:bold"/>
</h:panelGrid>
</p:dialog>
Any help would be appreciated.
N.B: I am using PF 2.2.1
It looks like the selection doesn't get sent using ajax - you need to set the onRowSelectUpdate attribute on the data table.
From Primefaces documentation:
In both single and multiple selection options described before, enclosing form needs to be submitted
by user so that the selections would be processed and set to the selection value reference. If you’d
like to execute custom logic whenever the row is selected instantly bind a rowSelectListeneror or define onRowSelectUpdate option.

How to submit values in a pop-up panel?

I have bean struggling to understand how to use the rich:popupPanel component in the right way. There are (at least not that I could find) few post about how to use the rich:popupPanel and how to submit values from it.
To make matter worse the panel seams to add (when checking the html) a hard coded "_content" to its component id name (to the div generated). I have tried to use aj4:region tag to partial render the complete form. But that didn't seamed to work, cause nothing where posted to managed bean. So now I have one option left, where the panel has its own form, outside the main one on the page.
I can see that the evaluation of the form (popup) values is happening, but not the execution of the bean function that persist the values (I see the POST request of the command button). The only reason I can think of at the moment, is that the pop-up panel use another bean to persist the values that the main form on the page (both of them are session scoped).
I am thinking of omit the pop-up panel all together, since it seams so hard to make this work. Maybe its a well know secret, since it so few post about it. It behaves the same if if use componentController or only a a4j:commanLink.
How is it possible to submit values from a rich:popupPanel and invoke a backing bean function to persist the pop-up form values ?
Appreciate if someone can shed some light on this, greetings Chris.
I use Richfaces 4.0-final on Glassfish 3.1
<h:form id="main_form">
<!-- Command for popup -->
<a4j:commandLink actionListener="#{userController.prepareCreateSysRequest}" oncomplete="#{rich:component('popup_sys_user_req_form:popup_sys_user_req')}.show(); return false;"
execute="#this" value="Request New Sector/Category" />
...
<a4j:commandButton action="#{projectController.Create}" ...>
</h:form>
<h:form id="popup_sys_user_req_form">
<rich:popupPanel id="popup_sys_user_req" modal="true" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="New Project Request" />
</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.selectedSysRequestType}" required="true" requiredMessage="Request Type is required" title="Request Type">
<f:selectItems value="#{userController.getSysRequestTypeItems()}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel value="Description:" />
<h:inputTextarea id="user_req_desc" value="#{userController.selectedSysUserRequest.description}" required="true" requiredMessage="Decription is missing" />
</h:panelGrid>
<a4j:commandButton action="#{userController.CreateSysUserRequest}" onclick="#{rich:component('popup_sys_user_req')}.hide(); return false;" execute="#form" render="popup_sys_user_req_form" value="Send Request" />
</rich:popupPanel>
</h:form>
For what I have done I used to have the issue to got to submit twice only the first time.
To fix it the form got to be outside the popupPane. And also that the popupPanel should have the attibute domElementAttachment="form".
Example.
<h:form>
<rich:popupPanel id="shipmentItemUpdateDialog"
autosized="true"
domElementAttachment="form">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{shipmentBundle.shipmentItemDetailsHeader}" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:commandLink>
<h:graphicImage value="/core/images/modal/close.png"/>
<rich:componentControl target="shipmentItemUpdateDialog" operation="hide" />
</h:commandLink>
</f:facet>
<h:outputText for="shipmentItemName"
value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemName}"
/>
<h:inputText id="shipmentItemName"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.name}"
label="#{shipmentBundle.shipmentItemName}"
size="40" >
</h:inputText>
<h:outputText for="shipmentItemCode"
value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemCode}"
/>
<h:inputText id="shipmentItemCode"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.code}"
label="#{shipmentBundle.shipmentItemCode}"
size="40" >
</h:inputText>
<h:outputText value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemAmount}"
/>
<h:inputText id="shipmentItemAmount"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.amount}"
label="#{shipmentBundle.shipmentItemAmount}"
size="4" >
<f:validateLongRange minimum="1"/>
</h:inputText>
<h:outputText value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemNeedsCooling}"
/>
<h:selectBooleanCheckbox id="shipmentItemNeedsCooling"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.needsCooling}"
label="#{shipmentBundle.shipmentItemNeedsCooling}"
/>
<h:outputText for="shipmentItemDetails"
value="#{shipmentBundle.shipmentItemDetails}"
/>
<h:inputTextarea id="shipmentItemDetails"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.details}"
label="#{shipmentBundle.shipmentItemDetails}"
cols="38"
rows="5"
/>
</h:panelGrid>
<h:panelGrid columns="1" dir="LTR">
<h:panelGrid columns="2" dir="LTR">
<a4j:commandButton value="#{coreBundle.acceptButton}"
action="#{shipmentItemController.onUpdate()}"
render="shipmentItemsTable">
</a4j:commandButton>
<h:commandLink value="#{coreBundle.closeLink}"
immediate="true">
<rich:componentControl target="shipmentItemUpdateDialog" operation="hide" />
</h:commandLink>
</h:panelGrid>
<h:outputText value="#{coreBundle.requiredText}"/>
</h:panelGrid>
</rich:popupPanel>
</h:form>
I hope this helps.
I think you got it right.. think of the pop-up as a regular page. To submit and close the pop-up, do something like this:
<a4j:commandButton value="Save" onclick="#{rich:component('panelId}.hide();" render="..."/>
Hope this helps..

JSF 2 + Primefaces - Update Not Working

I'lve already searched, but even implementing the solutions I've found, I was not able to get this working. I select a row in a datatable and click on delete button to delete the selected object, but the object gets deleted but the datatable is not updated. Here's my code:
<h:form id="formPesquisa">
...
<h:panelGroup id="panelToRender" layout="block">
<h:panelGroup id="panelDataTable" rendered="#{not empty bean.dataList}" layout="block">
<div id="dataTableRegion">
<p:panel id="panelBtnsUp" styleClass="cleanPanel">
<ui:include src="/templates/btnDataList.xhtml" />
</p:panel>
<h:panelGroup id="panelTableHolder" layout="block">
<p:dataTable id="dataTableBusca" value="#{bean.dataList}" var="entidade"
rendered="#{not empty bean.dataList}" paginator="true" style="width:100%;"
selection="#{bean.entidadesSelecionadas}" onRowSelectUpdate="panelBtnsUp,panelBtnsDown,dataTableBusca"
onRowUnselectUpdate="panelBtnsUp,panelBtnsDown,dataTableBusca" rowUnselectListener="#{bean.rowUnselectListener}" selectionMode="multiple">
<p:column>
<p:graphicImage url="/icons/checkbox_no.png" rendered="#{!bean.containsSelection(entidade)}" />
<p:graphicImage url="/icons/checkbox_yes.png" rendered="#{bean.containsSelection(entidade)}" />
</p:column>
<ui:insert name="colunasPesquisa" />
</p:dataTable>
</h:panelGroup>
<p:panel id="panelBtnsDown" styleClass="cleanPanel">
<ui:include src="/templates/btnDataList.xhtml" />
</p:panel>
</div>
</h:panelGroup>
</h:panelGroup>
....
</h:form>
And the Delete Button is in the included file:
<div style="margin:5px 0;">
<p:commandButton value="#{msg['commons.excluir']}" image="delete" disabled="#{bean.disableDelete()}" action="#{bean.delete}" update="panelDataTable" />
<p:commandButton value="#{msg['commons.editar']}" image="edit" disabled="#{bean.disableEdit()}" action="#{bean.prepareEdit}" ajax="false" />
</div>
I already tried:
update="dataTableBusca"
update="panelTableHolder"
update="formPesquisa:dataTableBusca"
update="formPesquisa:panelTableHolder"
What am I doing wrong???
Thanks for any help.
The first two approaches will only work if your button and the updated elements are siblings.
For the third and the fourth approach you have to traverse all containing elements in order to get the right id. You panelTableHolder is inside two other h:panelGroup (panelToRender, panelDataTable) and a div (dataTableRegion).
Furthermore to make sure that you start from highest level, prepend a : before the form id.
Try this:
update=":formPesquisa:panelToRender:panelDataTable:dataTableRegion:panelTableHolder"
You could check in the rendered html if this is the correct path for your panelTableHolder.

Resources