CommandButton execution while rendering - jsf

Question: How can I prevent the execution of a while the website is rendering?
Thats where my Button sits:
<p:dialog widgetVar="newComment" height="200" width="500">
<h:form>
<h:panelGrid>
<h:outputText value="#{commentDialog.username}" />
<h:inputTextarea id="in_text" value="#{commentDialog.text}" />
<p:message for="in_text" />
</h:panelGrid>
<p:commandButton validateClient="true" value="Abschicken" ajax="true"
actionListener="#{popupRequestView.update}" action="PF('newComment').hide();update_popup();" />
</h:form>
</p:dialog>

The action attribute is intented to execute a backing bean action method on click, not to print some JavaScript code (which of course get executed immediately
You perhaps meant to use onclick or oncomplete instead. Like as in basic HTML, those on* attributes are intented to execute some JavaScript code during the specified HTML event ("click", "complete", etc).
oncomplete="PF('newComment').hide();update_popup();"
Another cause not visible in the information provided so far is that you forgot to register the p: XML namespace. Any <p:xxx> tags would then be printed as if it's plain text. Verify if a parent element somewhere in the markup has this:
xmlns:p="http://primefaces.org/ui"
Regardless, taking a JSF pause and learning some basic HTML/JavaScript wouldn't be a bad idea. After all, JSF is "just" a HTML/CSS/JS code generator.

you must use primefaces ajaxStatus to prevent click on button while rendering and execute ajax
ajaxStatus in primefaces showcase

Related

commandButton inactive after ajax rendering

I have a problem with these two commandButton : Join and Leave.
I want to hide Join if I click on leave and vice-versa.
When I put ajax on false, there is no problem (but all the page is refresh and I don't find this optimal).
But when ajax attribut is on true with specific updating (cf comment in the code), the rendering is good but the new button whitch appear become inactive. If I click on it, nothing happens (well it's seems the actionListener trigger but the view is not refreshed, I have to manual refresh to see the difference)
Thanks for reading.
<h:form id="formWaitingList" rendered="#{connexion.connected}" >
<p:commandButton id="Join"
actionListener = "#{connexion.joinWaitingList()}"
rendered="#{!connexion.waiting}"
ajax="false"
<!-- ajax="true"
update="Join,Leave"-->
value="Join"/>
<p:commandButton id="Leave"
value="Leave"
ajax="false"
<!-- ajax="true"
udpate="Join,Leave"-->
rendered="#{connexion.waiting}"
actionListener ="#{connexion.leaveWaitingList()}" />
</h:form>
It seems that you're not entirely familiar with HTML/JavaScript. You know, JSF is basically a HTML/JavaScript(/CSS) code generator. Ajax updating works basically like this in JavaScript:
After sending the ajax request to JSF via XMLHttpRequest, retrieve a XML response which contains all elements which needs to be updated along with their client IDs.
For every to-be-updated element, use document.getElementById(clientId) to find it in the current HTML DOM tree.
Replace that element by new element as specified in ajax XML response.
However, if a JSF component has not generated its HTML representation because of rendered="false", then there's nothing in the HTML DOM tree which can be found and replaced. That totally explains the symptoms you're "seeing".
You basically need to wrap conditionally rendered JSF components in a component whose HTML representation is always rendered and then reference it instead in the ajax update.
For example,
<h:form>
...
<h:panelGroup id="buttons">
<p:commandButton ... update="buttons" rendered="#{condition}" />
<p:commandButton ... update="buttons" rendered="#{not condition}" />
</h:panelGroup>
</h:form>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

PrimeFaces dialog lazy loading (dynamic="true") does not work?

I have recently changed all my beans from RequestScoped to ViewScoped. Suddenly, the lazy loading of dialogs does not work. I am using PrimeFaces JSF library.
<html>
<h:body>
<f:view>
<h:form>
<p:commandButton id="addId" value="Add" title="Add" type="button" onclick="dlgMultiFileSelect.show();"/>
...
</h:form>
<p:dialog header="Dialog" widgetVar="dlgMultiFileSelect" modal="true" resizable="true" dynamic="true">
<ui:include src="/dialogs/media_browser.xhtml"/>
</p:dialog>
</f:view>
</h:body>
</html>
Seems like dynamic="true" does not work since the backing bean in media_browser.xhtml gets initialized immediately, and not when button is clicked.
Am I doing something wrong?
Using PrimeFaces 3.5.0.
have found some pretty easy workaround:
Let's quote BalusC's answer on this other question:
Skip executing <ui:include> when parent UI component is not rendered
The <ui:include> runs as being a taghandler during the view build time, while the rendered attribute is evaluated during the view render time.
Regarding his first proposal:
Use a view build time tag like <c:if> around the <ui:include> part.
So first add some new method to your bean. (may even be useful in some application scoped bean for reuse)
public boolean isAjaxRequest() {
boolean val = FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest();
return val;
}
Then enclose your <ui:include> inside following <c:if>:
<p:dialog id="yourDlg" header="Dialog" widgetVar="dlgMultiFileSelect" modal="true" resizable="true" dynamic="true">
<c:if test="#{applicationBean.ajaxRequest}">
<ui:include src="/dialogs/media_browser.xhtml"/>
</c:if>
</p:dialog>
So at page load time, the request isn't ajax... and on other ajax requests on base page, the dialog won't be updated...
But if you trigger your dialog
<p:commandButton id="addId" value="Add" title="Add" type="button"
oncomplete="dlgMultiFileSelect.show();" update=":yourDlg"/>
and update it's content, it will finally be rendered!
Please note following changes: The p:dialog id, p:commandButton update and p:commandButton oncomplete
Facelet tag ui:include will get processed earlier in the cycle and hence it is getting initialized. If you want to update the content of the dialog on button click, you need to do so using the update="id of the dialog" on your commandButton. You can use for your ui:include so that the page is not loaded initially.

primefaces panelgrid update from datatable

I am getting "Cannot find component with identifier "contentForm:tabView:form:addressDialogPanel" referenced from "contentForm:tabView:form:addressBookTable" " error. How can I update my panelGrid inside the widget?
<h:form id="form">
<p:dataTable id="addressBookTable">
<p:ajax event="rowSelect" listener="#{addressBookController.onRowSelect}"
update="contentForm:tabView:form:addressDialogPanel" oncomplete="addressDialog.show()" />
</p:dataTable>
<p:dialog id="addressDialogId" widgetVar="addressDialog">
<h:panelGrid id="addressDialogPanel" columns="2" cellpadding="4">
</h:panelGrid>
</p:dialog>
</h:form>
The main problem is that you are giving the wrong client ID of component's. Also p:tabView is a component it is not a form. When you define a h:form, it generates a standart HTML form element. And when you submit the page JSF uses POST to submit your data into backing bean. So nesting them is going to occur lot's of issues that you don't expect. You should seperate forms into sections like sideForm or searchForm or etc.
You should detect the correct client ID of your component when you try to update it. You can do this with your browser's developer settings(press f12 for chrome). Then select component with the magnifier button and give that ID into update property. Just like here:
You should read to learn basics of JSF for example from here

p:dialog closes when valueChangeListener is invoked

I have a <p:dialog> which contains a <h:selectOneMenu> with a valueChangeListener. Here's the relevant code:
<p:dialog>
<h:form>
<div>
<h:selectOneMenu value="#{itemController.itemId}" valueChangeListener="#{itemController.chkItemType}" onchange="submit()">
<f:selectItems value="#{itemController.itemsList}" />
</h:selectOneMenu>
</div>
</h:form>
</p:dialog>
When it is called, the dialog get closed. I would like to keep it open and only close it on cancel button. How can I achieve this?
That's expected behaviour. The onchange="submit()" which you've there submits the entire form synchronously, causing a complete page reload.
You should be using ajax instead to perform the submit. Replace the onchange attribute by just this tag
<f:ajax />
inside the <h:selectOneMenu>. This way the form will be submitted asynchronously, with by default no page reload at all.
Depending on the concrete functional requirement, which you didn't tell anything about, you do probably also not need a valueChangeListener at all, but rather a <f:ajax listener>.
<f:ajax listener="#{itemController.chkItemType}" />
If you'd like to update some parts of the page on successful execution of the ajax request, use its render attribute.
See also:
When to use valueChangeListener or f:ajax listener?

ReRendering with a4j:commandButton

Does the nesting of elements and multiple forms affect the capabilities of rerendering with a a4j:commandButton?
i have something like:
<ui:panelGrid>
<h:form id="1">
<a4j:commandButton rerender="1,2,3" />
</h:form>
</ui:panelGrid>
<ui:panelGrid>
<h:form id="2">
</h:form>
<h:form id="3">
</h:form>
</ui:panelGrid>
Currently it does not want to reRender anything, only the action on it will get executed.
Also i have in my forms . Would that affect anything ? I use the same bean name in every keepAlive tag
I'm new to all these.
I got it to work by reRendering the form's parent. It's strange. Why wouldn't it rerender only the form or a element in a form?

Resources