Populating two components in PrimeFaces - ajax

I have a page, that, when I select a Folder name, I populate two Components (<p:selectManyMenu> and <p:pickList>). How to I call two actions?
<p:selectOneMenu id="dirObj"
value="#{patchMB.patchBean.directoryObjetos}"
style="width: 350px">
<p:message for="dirObj"/>
<f:selectItem itemLabel="Selecione" itemValue="Select"/>
<f:selectItems value="#{patchMB.dirObjects}"/>
<f:ajax event="change" listener="#{patchMB.loadFiles}" render="pickListArq"/>
</p:selectOneMenu>
Can I use two <f:ajax> event tags? I tried, and seems that it is executing each listener 2 times.
Here's the code for the second action:
<f:ajax event="change"
listener="#{patchMB.carregarSelectMany}"
render="objSelectMany" />

Why do you need two ajax calling? Couldn't popolate two components using just one action?
Where did you put the second ajax event?
If you want execute two different methods on the same action, you can use a single ajax call and put the logic of the method2 in method1.
Otherwise, evaluate also to use valueChangeListener, it has different behaviour compared to ajax change. Read more on this post:
When to use valueChangeListener or f:ajax listener?

Related

p:ajax fires twice

concerning p:ajax of PrimeFaces. I have two p:ajax requests within my <p:commandButton>. I did stdout within the second method so that I can see if its triggered or not. The same (last) method is triggered twice and I don't know why. If I put only one <p:ajax> request into my button he fires once and if I put two <p:ajax> requests he fires twice.
<h:body style="background:#f5f5f5;">
<h:form id="formG">
<p:commandButton styleClass="viewButton" icon="ui-icon-search"
value="#{msg['button.open']}" id="auftragButtonG">
<p:ajax listener="#{auftragBean.saveIdIntoAppScope()}" partialSubmit="true"/>
<p:ajax listener="#{auftragBean.loadXMLData()}" partialSubmit="true"/>
</p:commandButton>
</h:form>
</h:body>
public void loadXMLData(){
setXmlData(entireXmlData(mandantId(), getJobId()));
System.out.println(getXmlData().size());
}
Anybody knows why and how I can ignore the second load?
It's because you're instructing the component to fire two ajax requests on the same (default) event. One <p:ajax> counts as one request. In other words, the code is behaving exactly as you programmed it.
You need to solve your concrete problem differently.
Invoke one method which in turn delegates to the desired methods.
<p:commandButton ... action="#{bean.methodWhichInvokesBothMethods()}" partialSubmit="true" />
Invoke multiple methods in one call. You can use <f:actionListener binding> trick for this.
<p:commandButton ... partialSubmit="true">
<f:actionListener binding="#{bean.method1()}" />
<f:actionListener binding="#{bean.method2()}" />
</p:commandButton>
Either way, the <p:ajax> is totally unnecessary as the <p:commandButton> by itself already has builtin ajax support.
See also:
Differences between action and actionListener

selectOneButton cant submit while inside splitButton

I'm using JSF 2 along with primefaces 5.1, i have a selectOneButton which have 2 values,
EN/FR, i want to be notified each time the language is changed, and then change the locale of the page.
Now the problem is that this selectOneButton is inside a splitButton, and for some reason,
the ajax submit of the "change" event is always returning null for the selectOneButton, and it never passes the values selected.
<h:form prependId="false" id="headerForm">
<p:splitButton>
<p:menuitem>
<p:selectOneButton id="langs" value="#{bean.lang}" >
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Françcais" itemValue="fr"/>
<f:ajax event="change"/>
</p:selectOneButton>
</p:menuitem>
</p:splitButton>
this just for testing:
public void setLang(String lang) {
System.out.println("Changed: " + lang);
this.lang = lang;
}
when i put the selectOneButton inside a p:menu for examples it works just fine.
This problem is two-fold.
First, most PrimeFaces components, particularly the ones which generate hidden HTML input elements and are presented to enduser by a bunch of divs/lists with click listeners instead of as "plain HTML" inputs, require a <p:ajax> instead of <f:ajax> to be properly processed during ajax submits.
<p:selectOneButton id="lang" value="#{bean.lang}" >
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Français" itemValue="fr"/>
<p:ajax />
</p:selectOneButton>
Note that I omitted the event attribute as it has the right default value already, which would be valueChange in case of inputs and action in case of commands. The value of change is not necessarily the right default as some components would require click instead, particularly radiobuttons and checkboxes which have a fixed value.
In any case, the general recommendation is, if you're using PrimeFaces, just stick to <p:ajax> all the time. It'll use PrimeFaces-specific jQuery based Ajax API to process the ajax request instead of JSF native Ajax API and it's capable of dealing with PrimeFaces components.
Second, the JavaScript code associated with <p:splitButton> moves the HTML representation of the menu to end of body (in order to ensure best cross browser compatibility as to z-index). This however causes the menu to not be sitting in a form anymore. You can confirm it by looking at the HTML DOM tree in the webbrowser via rightclick and Inspect Element (not View Source!). You can solve this in basically 2 ways:
Move the form to inside the menu item. It wouldn't make sense anyway to submit all other menu items for this specific requirement.
<p:splitButton>
<p:menuitem>
<h:form id="languageForm">
<p:selectOneButton id="lang" value="#{bean.lang}" >
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Français" itemValue="fr"/>
<p:ajax />
</p:selectOneButton>
</h:form>
</p:menuitem>
</p:splitButton>
Use <p:ajax partialSubmit="true"> to let PrimeFaces Ajax API to collect the invidivual input values instead of searching for a <form> and serializing it (which would fail because there's no form).
<h:form id="headerForm">
<p:splitButton>
<p:menuitem>
<p:selectOneButton id="lang" value="#{bean.lang}" >
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Français" itemValue="fr"/>
<p:ajax partialSubmit="true" />
</p:selectOneButton>
</p:menuitem>
</p:splitButton>
</h:form>

<f:ajax> executing different forms

So I have 2 forms and a command button with f:ajax attached on it. I want to execute the second form on click on button but it seems that it ignores when I'm passing the form's id on execute attribute. But when I replace it with 'execute=":form1"' it runs correctly(the information from the form is sent to server). Can someone tell me why won't work with the id of second form, or how can I achieve this: with one button to execute any form i want from the page.( as it is now no information is sent to server, only the listener is called).
Code bellow:
<h:form id="form1">
<h:panelGrid id="inputSection" >
<h:inputText id="input1" value="#{counterMB.number1}" />
<h:inputText id="input2" value="#{counterMB.number2}" />
</h:panelGrid>
<h:outputLabel id="sumResponse2" value="#{counterMB.sum}" />
</h:form>
<h:form id="form2">
<h:panelGrid id="inputSection" >
<h:inputText id="input1" value="#{counterMB.number1}" />
<h:inputText id="input2" value="#{counterMB.number2}" />
</h:panelGrid>
<h:outputLabel id="sumResponse2" value="#{counterMB.sum}" />
</h:form>
<h:commandButton value="Sum numbers">
<f:ajax event="click" execute=":form2" listener="#{counterMB.sum}" render=":form2 :form1"/>
</h:commandButton>
Update:
so to be more explicit: from what I have read I can use ajax to update/refresh etc some parts of a page instead of refreshing the whole page. What i have tried to do is group some components in different forms and execute a form at a time to see how it behaves. It works perfectly if I use the id of first group(form) but doesn't work at all if I use the id of the second form(it calls the action but doesn't submit any data from any form). I don't understand why. (PS for those who claim i lack some knowledge : this is the reason of asking questions isn't it? I'm trying to learn some new stuff)
It seems that you are lacking basic knowledge of how jsf works. A command button must be inside a form. And it's not possible to submit 2 forms with one single button.
The attribute execute of f:ajax tells which components to process, for example if you have 2 input texts, you can process only one and ignore the other using this attribute. but it's not possible to do what you are trying to do.
It doesn't really make sense to submit 2 forms and execute a single action method once.. there's no point in having 2 forms. why don't you put everything inside a single form?
In your current solution, you use a h:commandButton outside of any h:form - this is a little bit against HTML and JSF, so don't count on it. What I would suggest is
if you use Richfaces, put a a4f:jsFunction in every form and trigger the resulting Javascript from anywhere
if you use Primefaces, put a p:remoteCommand in every form and trigger the resulting javascript from anywhere
if you neither use any of them, put a <h:commandButton /> in every form, set the style hidden and use javascript to submit the form.
Hope it helps...

JSF: Execute values of multiple forms

I want to submit (execute) values from multiple forms, not just the enclosing form. So, I want to be able to do something like this:
<h:form id="form1>
<h:inputText id="testinput1" value="#{testBean.input1}" />
</h:form>
<h:form id="form2>
<h:inputText id="testinput2" value="#{testBean.input2}" />
<h:commandButton value="Submit">
<f:ajax execute=":form1 :form2"/>
</h:commandButton>
</h:form>
How would you solve this?
What is <f:ajax execute="#all"> really supposed to do? It POSTs only the enclosing form
seems to be related, but addresses a slightly different problem and also does not solve it (or this).
Ajax or not, this is not possible with plain JSF/HTML. All input elements which needs to be processed really needs to go inside the same form.

Invoke <h:commandLink> action method using <f:ajax>

I have the following code:
<h:commandLink action="#{testBean.showSomething}">
Do Stuff
</h:commandLink>
which does what I want (change the state of testbean and reload the page which will show a different set of divs. because of their "rendered" properties)
Now I want to use ajax to accomplish this so I did this:
<h:commandLink action="#{testBean.showSomething}">
<f:ajax event="click" render=":content" />
Do Stuff
</h:commandLink>
However this causes the showSomething method to not even be called.
IMHO what I want to do is rather simple but I can't for the life of me figure out how to do it.
You need to use event="action" instead of event="click". You could even omit it altogether. It's namely the default event the <f:ajax> is listening on when nested in an UICommand component.
<h:commandLink action="#{testBean.showSomething}">
<f:ajax render=":content" />
Do Stuff
</h:commandLink>

Resources