p:dialog closes when valueChangeListener is invoked - jsf

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?

Related

How to use f:setPropertyActionListener in h:commandButton in JSF without navigation to other pages? [duplicate]

I have a button to submit a form and invoke a managed bean action.
<h:form>
...
<h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>
But when I press the button it refreshes the whole page and sometimes also changes the URL.
Is there some way to not refresh the page and still invoke the action?
Make use of Ajax. It's a matter of nesting <f:ajax> inside the command button of interest.
<h:form>
...
<h:commandButton ...>
<f:ajax execute="#form" render="#none" />
</h:commandButton>
</h:form>
Particularly the render="#none" (which is the default value anyway, you could just omit the attribute altogether) will instruct JSF to re-render just nothing after the submit. If you intend to re-render only a specific component instead of the whole page, then you could also specify the ID of that specific component in render attribute.
<h:form>
...
<h:commandButton ...>
<f:ajax execute="#form" render="result" />
</h:commandButton>
...
<h:panelGroup id="result">...</h:panelGroup>
</h:form>
If you're already using PrimeFaces, then it's a matter of simply using <p:commandButton> instead of <h:commandButton>. It uses by default ajax already, so you don't need to nest in a <f:ajax>. You only need to remember to use attribute names process and update instead of execute and render.
<h:form>
...
<p:commandButton ... update="result" />
...
<h:panelGroup id="result">...</h:panelGroup>
</h:form>
The execute attribute defaults to #form already, so it could be omitted.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

In JSF 2.2, how to launch a method from a shared menu, wiithout leaving the current page?

The title says almost all. Just an important precision: the menu is in a template and so is shared by several pages and I don't know the page from which the user will choose the menu item.
I tried with a h:commandLink but I have a problem with the redirection to the same page. Perhaps there is a another kind of solution?
Just make it an asynchronous submit instead of a synchronous submit. Nest in a <f:ajax>.
<h:commandLink ...>
<f:ajax />
</h:commandLink>
If you intend to execute or render some specific parts, specify them accordingly in the execute and/or render attribute of <f:ajax>. They both defaults to #this and #none respectively. E.g.
<h:commandLink ...>
<f:ajax execute="#form" render="#form" />
</h:commandLink>

How to execute h:commandButton actionListener before onclick?

I need some help in the below code
<h:commandButton id="WhatifButtonID" value="#{demandBean.dmdReviewScreenLabelVO.whatIf}" style="width:60px; height:22px;" actionListener="#{demandBean.whatif}" onclick="window.open('DemandTargetList.xhtml','whatif','width=460,height=280,top=150,left=350,resizable=no,scrollbars=no')" >
<f:ajax execute="#this" ></f:ajax>
</h:commandButton>
In the above case, the onclick attribute gets executed first followed by the actionlistener attribute. I wanted the actionListener attribute to get executed first followed by the onclick function, since the page that loads onclick needs to get certain values from the actionListener. Please let me know how to acheive the same. Thanks in Advance.
Just let <f:ajax> render a script on complete.
<h:commandButton value="#{demandBean.dmdReviewScreenLabelVO.whatIf}" actionListener="#{demandBean.whatif}">
<f:ajax execute="#this" render="popupScript" />
</h:commandButton>
<h:panelGroup id="popupScript">
<h:outputScript rendered="#{demandBean.whatifPressed}">
window.open('DemandTargetList.xhtml','whatif','width=460,height=280,top=150,left=350,resizable=no,scrollbars=no');
</h:outputScript>
</h:panelGroup>
wherein you set whatifPressed to true in the whatif() method.
PrimeFaces may help with this with the use of the <p:remoteCommand/> tag. You can then just use a plain old button to call the remoteCommand, then simply execute the window.open().
<p:remoteCommand name="viewSomething" actionListener="#{someActionIWantToExecuteBeforeOpeningWindow}" update="#this" process="#this"/>
<button onclick="viewSomething(); window.open('http://somewhere.com', 'windowName', 'height=924,width=723');">Click me!</button>
You can use it over lists of items if you call the javascript function it creates something unique.

How make commandButton not fully refresh page? How to use f:ajax?

I have a button to submit a form and invoke a managed bean action.
<h:form>
...
<h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>
But when I press the button it refreshes the whole page and sometimes also changes the URL.
Is there some way to not refresh the page and still invoke the action?
Make use of Ajax. It's a matter of nesting <f:ajax> inside the command button of interest.
<h:form>
...
<h:commandButton ...>
<f:ajax execute="#form" render="#none" />
</h:commandButton>
</h:form>
Particularly the render="#none" (which is the default value anyway, you could just omit the attribute altogether) will instruct JSF to re-render just nothing after the submit. If you intend to re-render only a specific component instead of the whole page, then you could also specify the ID of that specific component in render attribute.
<h:form>
...
<h:commandButton ...>
<f:ajax execute="#form" render="result" />
</h:commandButton>
...
<h:panelGroup id="result">...</h:panelGroup>
</h:form>
If you're already using PrimeFaces, then it's a matter of simply using <p:commandButton> instead of <h:commandButton>. It uses by default ajax already, so you don't need to nest in a <f:ajax>. You only need to remember to use attribute names process and update instead of execute and render.
<h:form>
...
<p:commandButton ... update="result" />
...
<h:panelGroup id="result">...</h:panelGroup>
</h:form>
The execute attribute defaults to #form already, so it could be omitted.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

JSF - Two Questions about actions on UIComponent

So, let me show us my troubles :)
1 - When i click on a commandbutton
<h:commandButton value="Somethings">
<f:setPropertyActionListener target="#{bean.method}" value="some" />
<f:ajax render="rendering"/>
</h:commandButton>
I dont do any action to the commandButton. Just i fire the ajax call. If i add an action on the button (like action="bean.myAction) it will be executedat the 5° phase of the JSF lifecycle (allright, only if i write event="action" in the f:ajax, but thats as default). Right? But the f:ajax is fired by cliccing on the button as default? Because for a ListBox for example, it's fired only if i write event="change" (the same, i shouldnt write it, because is as default).
2 - When i click on image
<h:graphicImage value="img/img.png" alt="img">
<f:setPropertyActionListener target="#{bean.method}" value="some" />
<f:ajax event="onclick" render="rendering"/>
</h:graphicImage>
This doesnt work. Why?
As usual, thanks for the help!!!!
1 - When i click on a commandbutton
I dont do any action to the commandButton. Just i fire the ajax call. If i add an action on the button (like action="bean.myAction) it will be executedat the 5° phase of the JSF lifecycle
The f:setPropertyActionListener will be executed in the 5th phase as well.
(allright, only if i write event="action" in the f:ajax, but thats as default). Right? But the f:ajax is fired by cliccing on the button as default? Because for a ListBox for example, it's fired only if i write event="change" (the same, i shouldnt write it, because is as default).
The f:ajax just changes the behaviour from a synchronous submit to asynchronous (partial) submit. It does that by generating some additional JavaScript code to the desired event attribute of the parent component (e.g. onclick, onchange, etc, look in generated HTML output in webbrowser). It doesn't change anything in the JSF lifecycle. Only the rendered response will be a partial response which is exactly the part which is to be updated in the component(s) with ID as definied in render attribute.
2 - When i click on image
This doesnt work. Why?
Because the h:graphicImage does not support f:setPropertyActionListener at all. It only works in UICommand components.
You want to wrap it in a h:commandLink instead.
<h:commandLink>
<f:setPropertyActionListener target="#{bean.method}" value="some" />
<f:ajax event="action" render="rendering"/>
<h:graphicImage value="img/img.png" alt="img"/>
</h:commandLink>
(and if necessary style the border/underline caused by generated <a> element away with CSS)

Resources