p:messages rendering not working after ajax update - ajax

I have sheet(as datatable) . I am using ajax to update sheet(table) on change . I can update submit button render from backing bean . But i cant update my p:messages rendering like button. At the backing bean i am setting canMessageShow=false to not rendered p:messages but it still shows.
My code :
<form>
<p:commandButton id="submitButton"
disabled="#{facesContext.validationFailed or !anybean.canSubmit}"
actionListener="#{anyBean.dosmethn}" value="Submit"/>
<p:remoteCommand name="onCellEdit" update="someSheet"/>
<pe:sheet id="someSheet"
<p:messages id="createTrashMessages" rendered="#{anyBean.canMessageShow}" autoUpdate="true"
showDetail="true" showIcon="false" style="margin-left: 20px; width: 640px;"/>
<p:ajax event="change" global="false"
update="submitButton someSheet createTrashMessages"
listener="#{anyBean.editActionListener}" oncomplete="onCellEdit()"/>
<pe:sheetcolumn headerText="Item"
readOnly="true"
value="#{entity.item}"/>
<pe:sheet>
</form>
On my ajax update as you can see i am updating sheet and messages it self. Also i tried to remove from
FacesContext.getCurrentInstance().getViewRoot().getAttributes() But p:messages still displays. Also i have checked
FacesContext.getCurrentInstance().getmessages but it says no elements to display i mean its empty. How can i remove p:messages and not rendering upon ajax update. Because right now ajax updating button also setting canMessageShow to false. But p:messages still displaying.
My java version : 8
jsf 2.2.1
primefaces-extensions 6.2.10
primefaces 6.2

Related

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!

Skip validation of a form on re-render with Richfaces

I use Richfaces 3.1.2 and JSF 1.1
I have a textarea with two buttons inside a form : Submit and Update
the button Submit submits the form
One click on the button Update adds some text in the textarea
A validator is used inside the textarea, this validator throws an exception if the textarea only contains the name of the current connected user, for instance if the current connected user is "root" and the textarea contains "root", then an exception should be thrown
The code of the Textarea (by default it contains the name of the current connected user):
<h:panelGroup id="messagePanel">
<h:inputTextarea id="message" label="Update" value="#{beanName.message}">
<f:validator validatorId="messageValidator" />
</h:inputTextarea>
</h:panelGroup>
The submit button :
<h:commandLink id="validerLink" value="Submit" action="accueil"
actionListener="#{beanName.saveInformation}">
<f:param value="#{param.evenementId}" name="evenementId" />
</h:commandLink>
And the update button :
<a4j:commandLink id="inclureRapportLink" value="Update"
actionListener="#{beanName.updateText}" reRender="message">
<f:param name="evenementId" value="#{param.evenementId}" />
</a4j:commandLink>
The problem : If the textarea contains the name of the current connected user, the button Update doesn't update the text because the validator throws an exception.
So what I want to do is to disable the validator, but only if the user clicks on the button Update
I tried to add immediate="true" in the update button, but that didn't worked because apparently immediate="true" and reRender="message" doesn't work together (The bean is updated, but not the front).
I also tried this solution here : Skip validation on re-render and apply only on form submit but that didn't worked either, I got the error Undefined property clientId, and the validator is called even if the required property is set to false.
Can someone help me?

The Rich:commandLink and rich:commandButton on a dynamically rendered popup panel do not work in IE 8

I have created a JSF application using Myfaces 2.1.12 and Richfaces 4.3.3. On normal browsers the application works fine, but the client insists that he also needs to use a "browser" - IE8, version 8.0.7601. I am having a bunch of problems.
I have a rich:extendedDataTable on the main form. Clicking a row is to open a popup with the details (that is rendered and filled with the data from the selected row). The popup can also be called from a toolbar, this way it displays the details of the row that was selected when the page was first loaded.
The table is defined as follows (column definition removed for clarity)
<h:form>
<rich:extendedDataTable id="table" rowClass="row" rows="15"
value="#{scheduleController.allSchedules}" var="schedule" selectionMode="single"
selection="#{scheduleListBean.selectedSchedule.selection}" clientRows="15">
<a4j:ajax render="scheduleDetails, toolbar, transferListPopup" event="selectionchange"
listener="#{scheduleController.scheduleSelectionChanged}"
oncomplete="#{rich:component('scheduleDetailsPopup')}.show()"/>
...
</rich:extendedDataTable>
</h:form>
The popup contains a couple of panel grids, one of wich contains some buttons.
<h:panelGrid columns="2" styleClass="alignTop" id="scheduleDetails">
...
<rich:panel header="#{generalProperties.controls}">
<h:panelGrid columns="4">
<a4j:commandLink styleClass="btn" type="button"
render="table#body, transferDetailsPanel, destinationPanel, datesPanel"
oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('scheduleDetailsPopup')}.hide()"
status="pleaseWait" action="#{scheduleController.saveSchedule}"
value="#{generalProperties.save}" />
<h:commandButton class="btn" action="#{scheduleController.changeScheduleStatus}"
value="#{applicationProperties.changeStatus}" status="pleaseWait" type="button"
disabled="#{scheduleController.currentSchedule.id == null}">
<rich:componentControl target="changeScheduleStatusPopup" operation="show" />
</h:commandButton>
<h:commandButton class="btn" value="#{generalProperties.delete}" status="pleaseWait" type="button"
disabled="#{scheduleController.currentSchedule.id == null}">
<rich:componentControl target="removeSchedulePopup" operation="show" />
</h:commandButton>
<a4j:commandButton styleClass="btn" type="button"
render="fileTable, transferDetailsPanel, destinationPanel, datesPanel"
disabled="#{scheduleController.currentSchedule.id == null}"
oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('transferListPopup')}.show()"
status="pleaseWait" value="#{applicationProperties.transferHistory}" />
</h:panelGrid>
</rich:panel>
</h:panelGrid>
The disabled="#{scheduleController.currentSchedule.id == null}" part checks the bean if anything is selected as the popup is also used to add new rows.
Everything works fine on firefox. On IE8:
clicking the commandLink does not work(nothing happens, besides a "#"
that is appended to the url in the browser) when the popup is called from the
extended data table (rendered), but works when it is called from the
toolbar.
clicking the commandButton does not work(page is reloaded instead of an ajax request beeing executed) when the popup is called from the extended data table (rendered), but works when it is called from the
toolbar.
if I remove the type="button" from command buttons, then clicking them causes the entire page to be reloaded
What am I missing?
The answer was in the question itself. I rebuilt the UI so that no buttons are rendered in ajax requests. This way it works both on IE 8 and IE 9.
Ie.: Instead of setting the disabled attribute based on a bean and rendering the buttons I had to use two instances of each of those buttons. I did that by extracting a form into a composite component using composite:insertChildren just to inject buttons in the proper state and having two instances of the form on the page, showing the right one when the user clicked new schedule / edit schedule.
The drawback of this method is that I had to set the render attribute of the components that show the popup to something different then forms (in this case - panels), which would be an issue if I used Mojarra (see this question: javax.faces.ViewState is missing after ajax render)

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?

Primefaces blockUI stops working after ajax update

I am trying to create a datatable that displays a blockUI whenever it is busy, and I have been mostly successful. It now grays out and shows "Loading..." whenever I click either of two commandButtons, sort the datatable by clicking on a header, or page through the datatable. You can see the code for it below.
The problem is that after I have used one of the commandButtons (which runs an ajax update on the blocked element), subsequent actions do not trigger the blockUI (until I refresh the page). For example:
Load page
Click a datatable header - blockUI appears until table is finished sorting
Click one of the datatable page navigation buttons - blockUI appears until the page is loaded
Click one of the commandButtons - blockUI appears until the button's actionListener has finished
Click a datatable header - table sorts, but blockUI does not appear.
Click one of the datatable page navigation buttons - page loads, but blockUI does not appear
Click one of the commandButtons - actionListener runs and table updates, but blockUI does not appear
Reload the page - everything works properly again
Changing the commandButtons' update="" attribute to ajax="false" causes the sorting/paging to always display the blockUI, but the commandButtons to never display the blockUI.
Any ideas?
<div class="buttonDiv">
<p:commandButton ... update="resultsPanel" id="submitButton" ... />
...
<p:commandButton ... update="resultsPanel" id="resetScenarioButton" ... />
</div>
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
</p:panel>
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
The trigger attribute binds jQuery listeners on the specified elements. However if you update an element the binding gets lost. I don't know if it works, but you could try moving the <p:blockUI inside the resultsPanel. I suspect that when you update the panel the blockUI gets updated too and thus re-binding the listener to the data table.
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
</p:panel>
I've had the same problem and kind of simillar scenario:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons">
<!-- content to be blocked -->
</p:outputPanel>
<p:blockUI block="buttons" widgetVar="blockMessageButtons"/>
The problem was that panel buttons was both updated by ajax, and blocked by blockUI. I had to divide it in two:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons-content" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons-container">
<p:outputPanel layout="block" id="buttons-content">
<!-- content to be blocked -->
</p:outputPanel>
</p:outputPanel>
<p:blockUI block="buttons-container" widgetVar="blockMessageButtons"/>
#siebz0r already provided the explanation why blockUI stops working when a component is updated.
I am using a one blockUI element in the template for all other pages and thus don't want to include more blockUI elements.
If the blockUI element is updated as well one does not need to move the blockUI inside the component that will be updated.
Here is an example:
<p:panel id="surroundingPanel">
...
<p:commandButton value="ButtonName" styleClass="blockUi"
action="actionToBeExecuted" update=":surroundingPanel :blockUiBinding" />
</p:panel>
<p:outputPanel id="blockUiBinding">
<p:blockUI block=":elementToBeBlocked" trigger="#(.blockUi)">
Loading ...
</p:blockUI>
</p:outputPanel>
The element blockUiBinding can be located anywhere, as long as it can be updated. It is wrapping the blockUI element, because blockUI generates at least two different divs. So when the wrapping element is updated also the blockUI will be updated.

Resources