p:dataTable not showing updated records from database on Dialog close - ajax

I need your help in refreshing the dataTable component on closing the Dialog. I tried many ways to refresh the dataTable, but it is not retrieving the updated record, unless I have refreshed the full page by clicking on the "Go" button which is next to the URL in the address bar.
The xhtml code:
<h:form id="Requests">
<h:panelGroup id="table">
<p:fieldset id="Pendings" legend="Pending Requests">
<div id="refresh">
<p:dataTable id="PendingRequests" var="hr" value="#{hrd.pendingRequests}" paginator="true" rows="15" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" paginatorPosition="bottom" filteredValue="#{hrd.filteredPendingRequests}">
<p:column headerText="Req. Date" sortBy="#{hr.requestDate}" filterMatchMode="contains" filterBy="#{hr.requestDate}" >
<h:outputText value="#{hr.requestDate}"/>
</p:column>
<p:column>
<f:facet name="header">View</f:facet>
<p:commandButton id="submitbutton" update=":Requests:#{hr.dialogueName} "
oncomplete="PF('#{hr.certificateDialogue}').show()" icon="ui-icon-search" title="View">
<f:setPropertyActionListener value="#{hr}" target="#{hrd.selectedRequest}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</div>
</p:fieldset>
</h:panelGroup>
<p:dialog id="CertificateDialog" header="Cert1" widgetVar="CertificateDialog" >
<p:ajax event="close" update=":Requests" listener="#{hrd.UpdateDatatable}"/>
</p:dialog>
</h:form>
I tried to update the dataTable only, but it is not refreshing. Although, I have tried to update the full form using #form and #all and again the dataTable was not refreshed.
The updateDataTable method:
public void UpdateDatatable(CloseEvent event) {
RequestContext.getCurrentInstance().update(":Requests");
}

When you try to update a component from ManagedBean using RequestContext.update() you should not use the relative component id, because you'd have nothing to relate to.
To fix your problem remove : before Requests in your listener.
RequestContext.getCurrentInstance().update("Requests");
If you feel updating a component from managed bean, increases cohesion. You can use a p:remoteCommand can call if from your javascript any time you want.
<p:remoteCommand name="updateTable" process="#this" partialSubmit="true" update=":Results" />
And you can call the above remoteCommand from javascript or in your case from dialog as below:
<p:dialog onhide="updateTable()">
...
</pdialog>
My suggestion is to move p:dialog out of the h:form in which you placed the dataTable. Because In future if you get into situation where if need to update the h:form from p:dialog while its still open, updating the very own h:form in which the p:dialog is placed, would cause the dialog the p:dialog to close abruptly.
If you your p:dialog out for h:form then you might not need the UpdateDatatable() listener itself. update from your p:ajax would do the job for you.

Related

Getting Primefaces datatable row variable via non-ajax button post request

I have a datatable and polling in my Primefaces page. On Datatable on every row there is a commanButton. Because of polling, f:setPropertyActionListener does not works properly on button click. So I set ajax=false at button and trying to get datatable row "var" via a POST request. Is there a way to do that?
<p:poll interval="15"
listener="#{batchOperation.generateImportFTDBatchFileReport}"
update=":batchOperationsForm:growl :batchOperationsForm:batchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDerrorbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDStatusTxtId"
widgetVar="myPoll" autoStart="true"/>
<p:dataTable id="batchfilestbl" var="batchFile"
value="#{batchOperation.batchFileModel}" paginator="true"
rows="#{batchOperation.batchFileModel.pageSize}"
paginatorPosition="bottom"
sortBy="#{batchOperation.createTime}"
sortOrder="descending"
emptyMessage="#{messages['common.datatable.emptymessage']}"
selectionMode="single"
selection="#{batchOperation.selectedFile}">
<p:column headerText="#{messages['content.batchoperations.datatable.header']}">
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:setPropertyActionListener value="#{batchFile}"
target="#{batchOperation.selectedFile}" />
</p:commandButton>
</p:column>
</p:dataTable>
If you want to send the whole model object as a parameter to a backing bean method, you can send it in using your var for the data table.
<p:dataTable var="myVar">
<p:column>
<p:commandButton actionListener="#{bean.method(myVar)}" />
</p:column>
</p:dataTable>
Alternatively, if you are only interested in the row index, you can send just that using the rowIndexVar value for the data table.
<p:dataTable rowIndexVar="rowIndex">
<p:column>
<p:commandButton actionListener="#{bean.method(rowIndex)}" />
</p:column>
</p:dataTable>
It looks like you are trying to do file download here. You may want to checkout this question.
Instead of using f:setPropertyActionListener, f:attribute solved my problem.
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:attribute name="bf" value="#{batchFile}" />
</p:commandButton>
Method:
public synchronized void createBatchFileForDownloadLatestRevision(ActionEvent event) throws Exception {
selectedFile = (BatchFile) ((CommandButton) event.getSource()).getAttributes().get("bf");
.
.
}

Primefaces two dataTable update and add data from one to another

I have two dataTables in my JSF page they are placed in a dialog that pops up on some action, these dataTables has data from a list in my managed bean, what I am trying to do is when I double click on a row in my first data I want to add it to the second one and I have achieved that but it only occurs when I close the dialog and open it again, I have tried to use ajax update to update my second dataTable on the action but the issue is still occurring and my other issue that I want to HIDE the data from the first dataTable when I move it to the second one without removing it from the list or (at least dont allow the user to move the same item twice) any suggestions please? Here is my dialog and data tables:
<p:dialog modal="true" width="50%" height="50%" widgetVar="test"
id="dialog">
<p:dataTable id="tblAllQuestions" value="#{mbInstructor.fullList}"
var="asEmp" selectionMode="single"
selection="#{mbInstructor.currentExamQuestion}" rowKey="#{asEmp.id}"
rowIndexVar="rowIndex">
<p:ajax event="rowDblselect"
update="#parent:tblAllQuestions2"
process="#this" listener="#{mbInstructor.submitForm()}" />
<p:column headerText="#" width="20">
#{rowIndex+1}
</p:column>
<p:column headerText="#{msg2.get('employee')}" width="200">
#{asEmp.questionTxt}
</p:column>
</p:dataTable>
<p:dataTable id="tblAllQuestions2"
value="#{mbInstructor.formsQuestion}" var="as" selectionMode="single"
selection="#{mbInstructor.currentExamQuestion}" rowKey="#{as.id}"
rowIndexVar="rowIndex">
<p:ajax event="rowDblselect"
update="#parent:pnlfourmData"
process="#this" />
<p:column headerText="#" width="20">
#{rowIndex+1}
</p:column>
<p:column headerText="#{msg2.get('employee')}" width="200">
#{as.question.questionTxt}
</p:column>
</p:dataTable>
<h:outputText value="[no selection made]"
rendered="#{empty mbInstructor.model.target}" />
<p:commandButton id="formSubmit" value="Submit"
actionListener="#{mbInstructor.submitForm()}" style="margin-top:5px" />
</p:dialog>
I have tried to update the whole dialog as well but it disappear when i do the action, so I added the following to my ajax to show it again
oncomplete="PF('test').show()"
but the dialog does not show up when it finish.

displaying the value of the p:dataTable cell on click event of the p:panelGrid using p:ajax

I have p:dataTable, inside column I have a panelGrid where i want the value of the ouputText on the click of the panelGrid without page refresh. The code is something like:
<p:column headerText="5/5" style="width:40px; font-size:9pt;">
<p:panelGrid>
<p:ajax event="click" listener="#{myBean.showSelectedValue(row)}" update=":mainForm"/>
<h:outputText value="#{row.value1}" />
</p:panelGrid>
</p:column>
</p:dataTable>
<h:panelGrid id="ForecastChartTab">
<h:outputText id="value1" value="#{myBean.showValue.value1}" />
</h:panelGrid>
This is working, but the value is seen only on page refresh...! is something wrong here? :(
If you need to update the table, you can use the following
update="#([id$=dtTableId])"
If you need to update the output text you need use the following
update="#([id$= value1])"
With this type of format #([id$= value1]), you can update another component out of the behavior of others.

primefaces checkbox datatable will not check boxes on ajax event

I am trying to get a primefaces checkbox datatable to select multiple rows and pass those values to the bean. I have an ajax event for rowSelect and that works fine, but the ajax for rowSelectCheckbox never fires and it is as if my checkboxes are 'unclickable'. When selecting a row the rowSelect ajax event fires and highlights the entire row and checks the checkbox. However, I am unable to check any other checkboxes off so it is obvious only the rowSelect ajax works and not the rowSelectCheckbox. Here is code:
<p:dataTable id="content-table"
var="obj"
value="#{releaseNotes.contentList}"
rows="5"
paginator="true"
style="width:100%"
selectionMode="multiple"
selection="#{releaseNotes.selectedContent}"
rowKey="#{obj.hashCode()}"
paginatorPosition="bottom"
rendered="#{releaseNotes.showContentTable}">
<p:ajax event="rowSelect" listener="#{releaseNotes.selectListenerCode}" update=":grids :buttons" immediate="true"/>
<p:ajax event="rowSelectCheckbox" listener="#{releaseNotes.checkBoxListener}" update=":grids :buttons" immediate="true" />
<f:facet name="header">Content</f:facet>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<c:forEach items="#{releaseNotes.columnNames}" var="columnName">
<p:column headerText="#{columnName.toLowerCase().replace('_', ' ')}"
filterBy="#{obj.get(columnName)}" filterMatchMode="contains">
<h:outputText value="#{obj.get(columnName)}"/>
</p:column>
</c:forEach>
</p:dataTable>
Thanks in advance, my first post so I apologize if I missed some etiquette for the code formatting or anything like that, just let me know I will not take offense....

Validation errors in dialog not updating after failed submit in JSF

So I click a button which opens a dialog. Inside this dialog I want to fill out information in a form and submit and save it. Some of the inputTexts need to be required in order to submit. So I use the required="true" attribute. It stops the submission, but it does not update the field with a red outline of everything. Now, if I hit cancel and open up the dialog again it will show the fields that failed validation with a red outline!
I thought I could solve this by manually updating the dialog whenever I try to submit the form. This just causes the dialog to close though instead of staying open and refreshing the dialog to show the validation failures.
This is the dialog, when I hit the save button is when I submit the form
<h:form>
<p:dialog header="#{headerValue}" widgetVar="#{uniqueId}_editDialog"
modal="false" showEffect="fade" styleClass="dialogGrid"
dynamic="true" draggable="true" resizable="false">
<p:outputPanel style="text-align:center;" layout="block">
<p:messages autoUpdate="true"/>
<ui:insert name="editContent">
Edit Content Here. Use 'selectedModel.whatever'
</ui:insert>
<p:panelGrid columns="3" styleClass="buttonGrid">
<ui:insert name="saveButton">
<p:commandButton iconPos="left" value="#{msg.save}"
rendered="#{'VIEW' != selectedModel.viewState}"
process="#widgetVar(#{uniqueId}_editDialog)"
action="#{adapterInjector.add(modelList, selectedModel)}"
update="#widgetVar(#{uniqueId}_itemsDataList) #widgetVar(#{uniqueId}_addButton) #widgetVar(#{uniqueId}_editDialog)"
oncomplete="if(!args.validationFailed) PF('#{uniqueId}_editDialog').hide()"
partialSubmit="true" validateClient="true">
</p:commandButton>
</ui:insert>
<p:commandButton iconPos="right" value="#{msg.cancel}"
process="#this" oncomplete="PF('#{uniqueId}_editDialog').hide()"
resetValues="true" partialSubmit="true">
</p:commandButton>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
This is an inserted component which has the required attribute
<p:selectOneMenu id="licenseCert"
value="#{selectedModel.selectedLicenseCert}" filter="true"
required="true">
<f:selectItem itemLabel="#{msg.selectOne}" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{licCert.allLicenseCertMap.entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
</p:column>
Turns out this fixed the problem.
For best practice you should:
move the <h:form> inside the dialog
process the moved <h:form> in the save button.

Resources