JSF 2.0 - Ajax and Rendered Components - ajax

I'm experiencing some problems when using the "rendered" attribute with ajax behavior. I'll paste the code so I think it will be a lot more clear:
<h:selectOneMenu value="#{registrarVentaController.esCobroChequeString}">
<f:selectItem itemLabel="Efectivo" itemValue="false"/>
<f:selectItem itemLabel="Cheque" itemValue="true"/>
<f:ajax execute="#this" render="#form"/>
</h:selectOneMenu>
<h:panelGroup id="panelMonto">
<span>Monto:</span>
<h:inputText value="#{registrarVentaController.monto}" rendered="#{registrarVentaController.banCobroCheque}"/>
<h:inputText value="#{registrarVentaController.monto}" rendered="#{not registrarVentaController.banCobroCheque}"/>
</h:panelGroup>
My "#{registrarVentaController}" is just a View Scoped JSF Managed Bean with appropiate setters/getters.
This way it works, I mean, when user selects option "Efectivo", panelGroup "panelMonto" will get updated and we'll see the first inputText, and conversely when user selects option "Cheque" user will see the second inputText.
For this approach I used "f:ajax" component where I updated the whole #form to get this behavior work and I just want to update panelGroup "panelMonto" (using render="panelMonto" It doesn't work at all (I even try with full scope resolution :formName:panelMonto with no result).
I just want to have rendered work with ajax="idComponent" or similar behavior to show certain parts according what user have selected.
Best Regards!
Note (One solution)
I managed to get a solution (taking as an input
JSF rendered is not working
and a bit of myself). I've just moved to a new form the part that I'm
interested in filtering according what user selected. This way I still
use #form ajax's render and it will just render this new form (not the
whole form as I was using!) Neverthless I'm still wondering if there
is a solution to not used #form and just the component/s ID.

what if you check with
render=":panelMonto"
not
render=":formName:panelMonto"
still not working?
this should work only with
render="panelMonto" //because is in the same form
Can you add more code?
Also can you check with your browser (in chrome: right click, inspect element, network) to see if there is any activity?? perhaps is rendering the same thing because of you...

Related

JSF Submit Form to CommandButton using Ajax

https://www.primefaces.org/showcase/ui/ajax/event.xhtml
I want do that same what in showcase but without refreshing page. Like: setting value in inputtext and click on button to view result, but if i have <p:ajax event="blur" />or <p:ajax/> then i must click two times on the button
<p:inputText id="data" value="#{buttonView.data}">
<p:ajax/>
</p:inputText>
<p:commandButton value="Ajax Submit" id="ajax" actionListener="#{buttonView.buttonAction}" />
Maybe something like use outpupanel and update that panel in commandbutton?
If you are to use the <p:commandButton /> then the form will be submitted. In this case use update attribute of <p:commandButton /> to update the target component.
If you want to update another component as soon as you type then use <p:ajax event="keyup" update="your_target_component_id" /> to update your target component. (YOur event can be keyup, keypress, change, blur, etc.)
I don't understand why are you mixing the concept of using p:ajax with the functionality of the p:commandButton.
Basically, usage of p:ajax is intended to partially process the
field(s) value and update the component(s) of the form even without
submitting it.
Example:
You have Countries and States drop-downs (pre-populated) on a screen (let's say registration) with some other fields, but if user changes the country, you need to refill the States drop-down and update on the screen asynchronously. There you need to use the p:ajax.
On the other hand, p:commandButton is intended to submit the form
(not to update the components initially). However, it also supports
the updating of the components using update attribute.
Example:
Now, reconsider the above example with similar drop-downs (but disabled with fixed values). Now you know that your screen has nothing to be updated and you just have to tackle with validation (if any) and submit the form (update if required).
As far as you are concerned with using the p:ajax on the p:inputText for some asynchronously updates on the screen and p:commandButton to finally submit the form, that totally depends on your requriement.
Instead p:ajax try f:ajax. You can use < f:ajax event="change" render="#this"/>
once the value gets change, same will reflect in backing bean.

Disable validation for immediate actions

I have a complex page with a p:commanButton with actionListener and immediate="true"
Upon clicking this commandButton, I need to process a single inputField(thus skipping rest of the form). The problem is, that the inputField has a validator which I'd like to use only in full page submit.
<p:inputText id="#{cc.attr.id2}_input" value="#{myBB.value}"
immediate="true">
<f:validateLength minimum="4"/>
</p:inputText>
<p:commandButton id="#{cc.attr.id2}_search" immediate="true"
process="#{cc.attr.id2}_input #this"
actionListener="#{myBB.listener}">
</p:commandButton>
When I do this with i.e. 3 letters in the inputText, the myBB.value is not updated because of the failed validation. So I'd like to disable the validator for the inputField for the immediate processing by the commandButton. But I don't know how.
I know I can get the value from the ExternalContext, but this seems like a very hacky solution to me(and in my case is not even applicable, because it's inside composite component and I have no way of knowing the clientId of the textField.)
I also know about disabled attribute of the validator tag, but I have no idea how could I put that to use in this situation.
EDIT: I've changed a code a bit, because the IDs I'm using are actually not as simple as I first stated and don't allow me to use simple proposed solution.
I use Mojarra 2.2.4 and Primefaces 4.0
So, first of all, you haven't got the problem with immediate, but rather with <f:validateLength> validator.
That is, to rephrase your question, you'd like to skip validation of a given component in case the particular button is clicked.
Depending on whether you are on Mojarra 2.1.18+ or not there are two solutions. The first one is quite straightforward: use the disabled attribute of <f:validateLength>, while the other one takes into account issue 1492. As we've nowadays have advanced past the aforementioned version of Mojarra, I'll post the first and easier solution, otherwise, scroll through the excellent answers to Why does f:validateDoubleRange only work for #SessionScoped? and Disabled attribute of <f:validateLength> does not evaluate request parameters by BalusC.
So, the solution is the following:
<h:form id="formId">
<p:inputText id="inputId" value="#{myBB.value}">
<f:validateLength minimum="4" disabled=#{not empty param['formId:buttonId']}" />
</p:inputText>
<p:commandButton id="button" process="#this inputId" actionListener="#{myBB.listener}" />
</h:form>
As a side note, you can see that I didn't use immediate attribute at all because I supposed that you abused it to perform a given task. With the rise of AJAX in particular within JSF-based applications you can now easily group a subset of input elements validation by specifying the process attribute of <p:commandButton> or <p:ajax> instead of the previously used prioritized validation especially in synchronous requests. Only those components whose ids are supplied will be processed on the server and all other components will be omitted prom processing lifecycle. Also note that process="#this ..." is also mandatory to execute actions associated with the button itseld.
Regarding the appropriate usage of immediate I'd strongly suggest to refer to the classics: Debug JSF lifecycle blog post by BalusC to check whether you've used it correctly.

How to execute another <h:form> using <f:ajax>?

I've noticed that this doesn't work for me and I'm wondering if it's just not possible:
<h:form id="one" prependid="false" >
<h:commandButton>
<f:ajax execute=":two">
</h:commandButton>
</h:form>
<h:form id="two" prependid="false">
... content ...
</h:form>
Whenever I click the button above ,I can see that the values on form two are not executed as expected.
Is this the normal JSF behavior?
To 'trick' it, I usually insert a hidden button in form two and trigger it using JavaScript code when the button in form one is clicked. But that's a 'trick' and makes me work extra when I'm not sure I have to.
I should mention the rendering another form is possible.
Could the prependid attribute be causing problems?
Thanks in Advance!
UPDATE Adding more information that might be relevant - adding the prependid="false" to the forms as it is used in the actual code.
No, that's not possible with <f:ajax>. It just submits the parent form. The execute merely tells JSF which components it has to process based on the submitted data, not which request parameters the client side have to send. The button has really to go in the form where it belongs.

p:commandButton update doesn't work in ui:include

I want to update a part of a page by PPR.
This is the part of page that i want to update:
<h:panelGroup id="aggiungiAuto"
rendered="#{!autoBean.operazioneOk}">
<ui:include src="../component/aggiungi_auto.xhtml"/>
</h:panelGroup>
While this is the commandButton present in aggiungi_auto.xhtml
<p:commandButton value="Submit"
update="growl aggiungiAuto aggiungiFoto"
actionListener="#{autoBean.insert}"/>
Any Idea?
JS/Ajax works on the client side, not on the server side. JSF works on the server side, not on the client side. When you instruct JSF to not render the component to HTML, then nothing will be present in the client side, so JS/Ajax will be unable to locate the HTML element to refresh/update.
You need to wrap it in another <h:panelGroup>.
<h:panelGroup id="aggiungiAuto">
<h:panelGroup rendered="#{!autoBean.operazioneOk}">
<ui:include src="../component/aggiungi_auto.xhtml"/>
</h:panelGroup>
</h:panelGroup>
This way the <span id="aggiuniAuto"> is always present in the client side, so JS/Ajax will be able to update it with the new HTML data generated by JSF.
So I was having this kind of a problem with PrimeFaces (the above answer not being sufficient this time), and I also discovered a solution.
Part of the problem I think was that I was using ui:include recursively. For whatever reason, PrimeFaces was irrationally causing UI components to be bound to the backend data out-of-sync; e.g., when an "Add" button was clicked, a new value would be created in the UI, but then the data for it would be ripped out of the values for the section below, etc...
The explanation? "[O]n a viewscoped bean, a hidden field is added to the form to hold post-back data[;] if that field is not included with the process, then the bean will lose context." This particular problem is prevalent with ui:include recursion especially. Solution (all regarding the p:commandButton or other actionable component):
Ensure that update and process are pointing to a JSF component, not a regular HTML component.
update the next scope up if it breaks (goes out-of-sync with the binding).
Use styleClass's for update (not e.g. PF ID's or #this:#parent kind of stuff), so that jQuery is utilized instead of PF, e.g.: #(.fieldset-class).
process whatever scope is being updated. (This is needed for the post-back data so that the Bean keeps its context for the update...) process="#this" is not needed here, provided that the button is contained by the process value component.
For all buttons without validation wanted, set immediate="true".
If none of the above works (which happened with the Add buttons, probably due to ui:include recursion), set process="#this", immediate="true", and update="#none", and then oncomplete="remoteCommandName();", and have a p:remoteCommand instead with that name with the process, immediate, and update mentioned in the above points.
If none of the above works (which happened with some other buttons, probably due to being yet another layer deeper in the ui:include recursion)... wrap a h:panelGroup around the next c:forEach up and then update the PrimeFaces ID of that in the button itself while keeping its remoteCommand call afterwards, as specified above.
If none of the above works (which happened yet again to me)... Try the following code:
In the p:commandButton(s): oncomplete="$('.FixButtonSC').click();"
In the p:fieldset with a style class of FieldsetSC:
<!-- Fix (hidden) button. -->
<p:commandButton id="FixButton" styleClass="FixButtonSC"
process="#this" update="#(.FieldsetSC)" style="display: none;" />
Hope that helps...

What is <f:ajax execute="#all"> really supposed to do? It POSTs only the enclosing form

sorry if I am being thick but what is the execute="#all" in an f:ajax tag really supposed to do? I expected it to submit all the elements on a page but it seems to POST only the values in the enclosing form, not all forms on page.
For example
<h:body>
<h:form id="form1">
Input1/Form1 <h:inputText id="testinput" value="#{testBean.input1}" />
</h:form>
<h:form id="form2">
Input2/form2 <h:inputText id="testinput2" value="#{testBean.input2}" />
<h:commandButton value="Ok" actionListener="#{testBean.al}">
<f:ajax execute="#all" />
</h:commandButton>
</h:form>
</h:body>
Only form2 is posted on click.
Using mojarra 2.0.2..
The execute="#all" was just a major oversight during designing JSF2 spec. JSF kind of abstracted away too much of its HTML form based nature, forgetting that it's ultimately actually a HTML code generator.
In HTML, submitting a different form than the enclosing one is disallowed. So execute="#all" will never work from that perspective on. It will behave exactly the same as execute="#form". Given that JSF is just a HTML code generator, the same "problem" will hit JSF too. It's not possible to process multiple <h:form> components at once.
If you really need to have this feature for some reason, you should take a step back and reconsider the incorrect way how you look at HTML forms. You need to make sure your forms are designed in such way that you never need information from another form.
See also:
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?.
PrimeFaces already realized early that #all was fundamentally wrong. That's exactly why they never supported #all in process attribute, their equivalent of execute. They initially also never supported #all in update, their equivalent of render. However, the only real world use case where that made sense was handling a full error page during an ajax exception, so they ultimately brought update="#all" back after I created the FullAjaxExceptionHandler. The process="#all" will still have exactly the same effect as process="#form".
However, the very same PrimeFaces library also unintentionally made the imagined behavior of execute="#all" possible via its later introduced partialSubmit="true" feature whereby you explicitly specify all other forms like below (the PFS #(form) is just for simplification, a hardcoded collection like :formId1 :formId2 :formId3 etc is also just possible).
<p:commandButton ... process="#(form)" partialSubmit="true" />
This works because partialSubmit="true" prepares the process="xxx" at client side rather than server side. In other words, instead of sending the entire enclosing form from server to client and then processing the specified inputs, it sends only the specified inputs from server to client and then processes them all. Do note that when partialSubmit is absent or set to false, then it would still only send the enclosing form. This misbehavior should rather not be relied upon. They may fix this misbehavior on their side sooner or later.
See also:
Any significant technical difference between JSF non-AJAX submit and a "#all" AJAX submit?
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Here is a quote from JavaServer Faces 2.0 - The complete reference, page 352:
The execute and render keywords accept a set of special keywords, each with the meaning shown in this table:
#all (using with execute): Every component on the page is submitted and processed. This is useful when you want to do a full-page submit.
I think this quite clearly states that the fields from all forms should be submitted with the AJAX request.
However, even with Mojarra 2.0.3 this doesn't happen. Despite of contents of the execute attribute (whether you put a list of forms or #all) only the enclosing form gets its' fields submitted. So this seems like a bug. I am raising an issue about this unless there are altering views?
It would have to be execute=":form1 form2" (if you have the default separator), but anyway no, it doesn't. It only sends the second one.
If you put #all in the first form, it only sends the first. At least on Safari 5/Firefox 3.6.3 anyway. I guess one would have to look at the mojarra javascript to find out more.
Have you tried this?
<f:ajax execute="form1 form2" />
Does it send both forms' data if you explicitly mention them?
AFAIK, you are right: #all represents the whole page.

Resources