Primefaces: Update (refresh) p:panel inside p:rowExpansion - ajax

I have the following configuration:
JSF: Apache MyFaces JSF-2.1 Core API (Version: 2.1.10)
PrimeFaces 3.4.2
Tomcat 7.0.35
I have a DataTable with rowExpansion and a panel with button in the rowExpansion. I would like to refresh only the panel inside the rowExpansion when the user clicks on the button.
<p:dataTable id="vmt" var="vmtemplate" value="#{myViewBean.myList}" rowKey="#{vmtemplate.id}">
<p:ajax event="rowToggle" listener="#{myViewBean.onRowToggle}" update=":growl" />
<p:column style="width:2%"><p:rowToggler /></p:column>
<p:column>...</p:column>
<p:rowExpansion>
<p:panel id="exp_panel" header="#{vmtemplate.name} Instances">
<h:form id="instancesForm">
<p:commandButton id="refreshRowExpPanel" title="Refresh" update=":growl" action="#{myViewBean.reloadData}"/>
</h:form>
</p:panel>
</p:rowExpansion>
</p:dataTable>
I think I have to set the update property of the refreshRowExpPanel button in order to refresh the exp_panel, but when I set it to update=":growl :expanel" I get an error:
Cannot find component with identifier ":expanel" referenced from
"mainForm:vmt:0:refreshRowExpPanel".
so the generated ID of the panel is "mainForm:vmt:0:refreshRowExpPanel", but when I specify this to the update (update=":mainForm:vmt:0:refreshRowExpPanel") I got the same error:
Cannot find component with identifier
":mainForm:vmt:0:refreshRowExpPanel" referenced from
"mainForm:vmt:0:refreshRowExpPanel".
with update=":mainForm" it works, but it refreshes the whole dataTable and my expanded row will be closed, so it's not fine.
Could you please suggest a solution how to refresh only my panel inside the rowExp, maybe from JS, or any other idea?
thx!

I recommend you to try using ID of the panel without colon on the beginning, so:
update="mainForm:vmt:0:refreshRowExpPanel"
Also you may like to read this post about making references.

I've just realized, that I had a form outside my dataTable:
<h:form id="outerForm">
<p:dataTable id="vmt" var="vmtemplate" value="#{myViewBean.myList}" rowKey="#{vmtemplate.id}">
pansion>
...
</p:dataTable>
</form>
by removing the outer form, and changing the update value to "#form" solved the problem

Related

JSF and primefaces p:booleancheckbox not rendering correctly

I have a strange behaviour in my code that for some reason I'm unable to solve.
I'm using PF4 and mojarra 2.1.28 running on jboss eap 6.4.
Here's the code
<p:column>
<f:facet name="header">
<p:selectBooleanCheckbox id="checkAll" value="#{backingBean.allowAll}">
<p:ajax listener="#{backingBean.confirmAllowAlla}" process="tablaDoc" update="tablaDoc :form1:facesMessages" onstart="mask();" oncomplete="unmask();" />
</p:selectBooleanCheckbox>
<p:outputLabel for="checkAll" value="Allow all" />
</f:facet>
<p:selectBooleanCheckbox id="checkTipo" value="#{tipoDocumento.allowed}" >
<f:param name="idTipoDocumento" value="#{tipoDocumento.idTipoDocumento}"/>
<f:param name="secuencia" value="#{tipoDocumento.secuencia}"/>
<p:ajax listener="#{backingBean.confirmChange(tipoDocumento)}" process="#this" update="tablaDoc :form1:facesMessages" onstart="mask();" oncomplete="unmask();" />
</p:selectBooleanCheckbox>
</p:column>
Getters and setters exist, backing bean is invoked as it should... apparently everything works but...
when I click in the booleanCheckbox placed in the header all the other checkboxes should be checked.
First time I click internally everything seems to go ok. Model is updated correctly and my datatable is updated accordingly but for the checks. Visually they are not checked (checked="checked" is missing in the output html) but all the expected behaviour is just fine. A button for each row is enabled/disabled and even if I add a column to display the internal value used for the check it renders the expected value.
If I uncheck the main checkbox and check it again, normal behaviour is restored and the checks for each row start rendering ok (checked="checked is in the output html).
I cannot modify my DTOs so I cannot implement SelectableDataModel from PrimeFaces.
Any ideas?

malformedXML: During update: outerTab:j_idt185 not found; iframe id="JSFFrameId"

I have a form with a PrimeFaces selectOneMenu which, when the user selects an option, I want to refresh a DataTable in the same form with different data. When I select an option I get a Javascript popup that says "malformedXML: During update: outerTab:j_idt185 not found" with no DataTable refresh and on inspecting the source I see an invisible iframe at the bottom of the page with id="JSFFrameId" that contains an element <partial-response> that in turn contains an element <update id="outerTab:j_idt185" ...> and this contains an element <![CDATA[<div id="outerTab:j_idt185" class="ui-messages ui-widget" aria-live="polite"></div>]]>. I think this references my <messages> tag, but nothing in the backing bean creates a message, and I do see an element in the page source <div id="outerTab:facilitatorTestsForm:j_idt113" class="ui-messages ui-widget" aria-live="polite"></div> where the messages should be, so the messages tag is indeed rendered. I can find no element with an ID containing "j_idt185" and apparently neither can some Javascript.
The "outerTab" in the IDs is a PrimeFaces TabView that contains all this stuff.
A page refresh causes the update to happen and the DataTable shows the correct data for the selected SelectOneMenu option.
I have found several posts by balusC where some element that is updated by an ajax call has a rendered value that makes it not render and therefore unable to be found when the update is called for. The target of my update (the DataTable) has no rendered attribute and is visible all the time, so this is a different problem. Other posts speak to a bug in earlier versions of PrimeFaces (I am using 6.1). I cannot figure out why this error occurs.
#Kukeltje kindly pointed me to several posts showing that using an encoding type of multipart/form-data in a file-upload component or a form submit can cause this problem but my page has neither of these.
Here is an excerpt of my page:
<div align="center">
<h:form id="facilitatorTestsForm">
<p:messages for="testBeanMessages" showSummary="true" showDetail="true" globalOnly="true" escape="false" autoUpdate="true" />
Tests for which event?
<p:selectOneMenu value="#{testBean.selectedEventId}" style="top: 7px; ">
<f:selectItem itemLabel="All Tests" itemValue="" />
<f:selectItems value="#{testBean.facilitatorEvents}" var="event" itemValue="#{event.id}" itemLabel="#{event.name}" />
<f:ajax update="facilitatorTests" />
</p:selectOneMenu>
<p:commandButton value="Add a New Test" style="margin: 20px;" oncomplete="PF('newTestDialog').show();" actionListener="#{testBean.createEmptyNewTest}" immediate="true" />
<p:dataTable var="test" value="#{testBean.testsForFacilitator}" rowIndexVar="index" id="facilitatorTests" widgetVar="facilitatorTests" selectionMode="single" selection="#{testBean.selectedTest}" rowKey="#{test.id}">
<p:ajax event="rowSelect" oncomplete="PF('facilitatorEditTestDialog').show(); " update="#form:facilitatorEditTestDialog" />
<p:column>#{index + 1}</p:column>
<p:column headerText="Test" sortBy="#{test.name}" width="40%"><h:outputText value="#{test.name}" /></p:column>
<p:column headerText="Tester" sortBy="#{test.tester.fullname}"><h:outputText value="#{test.tester.fullname}" /></p:column>
<p:column headerText="Manager" sortBy="#{test.manager.fullname}"><h:outputText value="#{test.manager.fullname}" /></p:column>
<p:column headerText="Event" sortBy="#{test.event.name}"><h:outputText value="#{test.event.name}" /></p:column>
<p:column headerText="Functional Area" sortBy="#{test.functionalArea.name}"><h:outputText value="#{test.functionalArea.name}" /></p:column>
<p:column headerText="Complete" width="150" sortBy="#{test.completionDate}"><h:outputText value="#{test.completionDate == null ? 'Not Completed' : test.completionDate}"><f:convertDateTime pattern="M/d/yyyy hh:mm a" /></h:outputText></p:column>
<p:column id="delete" style="text-align: center; vertical-align: middle; min-width: 54px; ">
<p:commandButton update="facilitatorTests" process="facilitatorTests" icon="ui-icon-close" actionListener="#{testBean.deleteTest(test.id)}"
title="If the test has not been completed, it will be deleted permanently. Otherwise it will be archived."/>
</p:column>
</p:dataTable>
<... a few dialogs with conditional rendering ...>
</h:form>
</div>
I have tried different targets for the selectOneMenu update attribute and it does not change the behavior so I believe it is correct.
Primefaces 6.1
Mojarra JSF API & IMPL 2.2.4
EL 3.0.0
Tomcat 7
Is this a JSF bug? Thanks for any help you can offer.
Found the solution. Thanks to #Kukeltje for staying with me through this even if he did downvote my question for not having enough info :)
It comes back to #BalusC's posts about not rendering the target of an ajax update. In this case I had several PrimeFaces TabView tabs containing <p:messages> tags with autoUpdate="true", and the tabs are shown/hidden depending on the role of the user. When I removed autoUpdate="true" from these messages tags the problem went away. Apparently every time I did an ajax post, even if I had partial submit limited to rendered subelements of the current visible tab, autoUpdate causes JSF to try to update the messages tags in the unrendered tabs and of course they cannot be found.
The way I found this was to put id attributes EVERYWHERE, on every element in my forms. Then the Javascript error pointed me to a named (id'd) element, rather than one with an automatically assigned ID that I could not trace, and when I saw "autoUpdate" the light bulb came on. Moral: put ids on EVERYTHING.
I hope this helps someone with the same symptom to look for autoUpdate everywhere.
And #Kukeltje you were right that my post had inadequate information - without the enclosing tab tags with their rendered attributes you could not have seen the problem. Since they were in another template that ui:includes the forms I did not think they were relevant. Wrongo!

How to submit JSF PrimeFaces form with selectBooleanCheckbox without refreshing the page?

I'm using JSF with PrimeFaces to make an application as an assignment for college. I'm struggling to get something working. I'm using PrimeFaces and I have a tabview which contains 5 tabs. In one of those tabs I have a dataTable which has several rows and columns. This all works fine, but the problem is that I want to submit the form without rerendering the (entire page). The thing is, every column in the dataTable has a selectBooleanCheckbox, and when that checkbox is selected, a button should disappear. If it's unselected the button should appear. This works fine with onchange="this.form.submit()" or onclick="this.form.submit()" but it refreshes the entire application, and it causes the first tab to be selected, rather than the one I was at. So I'm looking for a solution to be able to submit and re-render some stuff without refreshing the entire program. This is my code:
<body>
<h:form id="customerForm">
<p:dataTable id="customerlist" var="c" value="#{customerBean.customerList}">
<p:column>
<f:facet name="header">Select</f:facet>
<center>
<p:selectBooleanCheckbox value="#{c.selected}" onchange="this.form.submit()"/>
</center>
</p:column>
</p:dataTable>
<h:commandButton id="testtest" value="test" rendered="#{customerBean.numberSelected() == 0}"/>
</h:form>
</body>
I removed most of the columns for the sake of simplicity. What is the solution to this? I've tried using ajax, but that didn't work
<p:selectBooleanCheckbox value="#{c.selected}">
<f:ajax event="click" execute="#form" render="#none"/>
</p:selectBooleanCheckbox>
Do you really need to submit the whole form? If it's enough that the view is being rerenderd try just to update the form. For that you can use the primefaces ajax event.
<p:selectBooleanCheckbox value="#{c.selected}">
<p:ajax update="#form"/>
</p:selectBooleanCheckbox>
If this does not work, please tell us what "..ajax, didn't work" exactly mean. Is there any POST Request submitted? Is any Action/Setter called?

Listener not called by p:ajax on p:inputText

I want to implement custom filtering on a p:dataTable. In the header of the dataTable, I have a p:inputText that I want to filter the table via ajax. The problem I am having is that the bean method is not being called by the p:ajax tag. Here is the offending code snippet:
<h:form id="form1">
<p:dataTable id="selectTable" var="select"
selectionMode="multiple" rowKey="#{select.id}"
value="#{pc_Selectcourses.allCourses}">
<f:facet name="header">
<p:outputPanel>
Search For Courses Completed:
<p:inputText id="filterEntry" value="#{pc_Selectcourses.query}">
<p:ajax event="keyup" update=":form1:selectTable"
listener="#{pc_Selectcourses.filterListener}" />
</p:inputText>
</p:outputPanel>
</f:facet>
<!-- table columns here, etc. -->
</p:dataTable>
</h:form>
And the backing bean:
public void filterListener() {
System.out.println("Hello world, hope you're listening...");
}
When I type in the inputText, the Sysout is never printed. I also notice that my ajax notifier/status icon doesn't show any activity, so I doubt anything is happening.
Edit
I just tried dragging and dropping p:ajax from Eclipse's Palette into my xhtml code and it said to use this I needed to import libraries into my workspace. I let it go ahead and it added primefaces v3.2 jar file into Web_INF/lib. The p:ajax still doesn't work.
I am confused as to why it asked for this as all the Primefaces components have been working great all along. Is there possibly something wrong with the project setup?
I saw this same problem today. It turns out that in your backing bean, if you have a getter function for query but NOT a setter function, p:ajax won't call its listener. Since you didn't post that section of your Java code, I assume there's a good chance this is your problem.

Primefaces Inline DataTable Delete functionality

I'm using primefaces inline editing datatable.which consists of primefaces RowEditor and a CommandButton to delete the record.My Problem is when i deleted any record from the the database,the row is successfully deleted and the deleted record is showing when i click on the edit button for editing the next record.This edit problem continues with all the records .It is showing the present value in h:outputText and the old value in h:inputText which comes when we click on edit button.
Could anyone help me on this ?
Thankyou all.
There are a lot of Primefaces bugs logged on the <p:dataTable> component, so I am not going to search through all of them.
I do know however that there is an open bug as of Primefaces 2.2.1 stating that components within a row of a <p:dataTable> will not correctly update (refresh) the appropriate values within the dataTable. This problem MAY be fixed in Primefaces 3.0. If you are interested you can search the known bugs here.
Fortunately I have figured out a workaround for this. You need to perform an asynchronous operation from a component OUTSIDE of the <p:dataTable> and make sure that component sets the id of the dataTable in its update attribute.
<h:form id="form1">
<p:commandButton widgetVar="updateButton" update="form1:table1" ... />
<p:dataTable id="table1" ...>
<p:column ...>
<p:commandButton id="deleteButton" action="#{managedBean.doDelete}" oncomplete="javascriptFunction();" ... />
</p:column>
</p:dataTable>
</h:form>
And in a javascript:
function javascriptFunction() {
updateButton.jq.click();
}

Resources