How to just update "rendered" property in JSF - ajax

I've got a list of documents and I need to update all at once.
I did something like this:
<ui:repeat id="r_list" value="#{tareaController.controlador.documentosIndexar}" var="documentos" >
where documentosIndexar is the list of documents. It displays all the documents and its properties fine.
I have two panelGrids, one with the viewer of the document and another one with its information.
At the bottom of the information there's the list of documents.
I need to fill the document's information then select another one without losing the previous one.
I'm trying to update the whole ui:repeat and it renders the next document and its information ok but the information of the previous one is lost.
I also tried doing:
<ui:repeat id="r_list">
<p:panelGrid id="pg_document" rendered="#{tareaController.controlador.documentoSeleccionado.id eq documentos.id}">
<---- Document components here ---->
<p:ajax event="rowSelect" update=":f_tarea:r_list:pg_document" listener="#{tareaController.controlador.reemplazarLista(tareaController.documentoSeleccionado)}"/>
</p:panelGrid>
</ui:repeat>
All my components, and well, my page is inside a form called f_tarea, which is from its template.
When I do the above I update that panelGrid from the list, but just that one, and the variable in the rendered condition changed, so all the panelGrid dissapear.
Basically, what I want to do is update JUST the rendered condition on all the panelGrids inside the ui:repeat, so one hides and another one is shown without losing the previous one's information.

Ok. Excuse me I'm a completly stupid.
I tried doing something I haven't done before: downloading the PrimeFaces manual. On the AjaxBehavior section there's the "process" one which process a component in partial request.
I fixed it just by doing:
<p:ajax event="rowSelect" process=":f_tarea:r_list:pg_documento" update=":f_tarea:pg_doc" listener="#{tareaController.controlador.reemplazarLista(tareaController.documentoSeleccionado)}"/>
I won't delete the question in case that it helps someone in the future.

Related

JSF cannot update single form in ui:repeat from outside

I have two problems which are closely related:
I need to update a form inside a tag inside ui:repeat from a dialog at the main page and cannot figure out how (because there are many tags in the ui:repeat and I need to update only one)
naming containers are messed up and lose their "index" when I use id in that form (in case of trying to determine the update path expression...)
reason I need this: updating the 'wholelist' (current situation) breaks all <p:calendar> inside the <p:dialog> somehow (no errors...) (the calendar overlay shows at the first time, but after updating the list it does not appear any more (must reload page again). Also I don't want to update 100 elements each time if only one can be changed
page.xhtml
<h:panelGroup id="wholelist">
<ui:repeat var="entry" value="#{bean.foundEntries}" id="repeatId">
<customTag:someTag entry="#{entry}" />
</ui:repeat>
</h:panelGroup>
...
<p:dialog widgetVar="dialog" id="dialog">
<p:calendar value="#{bean.date}" ... /> <!-- overlay pops up on select until the whole list is refreshed. after that it does not appear until page reload -->
<p:commandButton actionlistener="#{bean.saveSomething()}" update="#{bean.componentToUpdate WHICH DOES NOT WORK...}"/>
</p:dialog>
someTag.xhtml
and within the <customTag:someTag> (which is a tag because of multiple reuses) :
...
<h:form>
... display a lot of data which can be changed by the dialog...
<p:commandButton value="show edit dialog" onComplete="PF('dialog').show()" update=":dialog">
<f:setPropertyActionListener value="??? (#form does not work)" target="#{bean.componentToUpdate}" />
</p:commandButton>
</h:form>
First Question:
I need to refresh one single form from the dialog (=the dialog which needs to know which form I want to refresh, and I have no idea how to do so...)
And how can I get the update-logic working (pass the component to update to the bean so the dialog knows what to update or equal)?
Second Question:
why does JSF generate in case of not defining a id="..." to a naming container within a ui:repeat something like
repeatId:0:j_id_c0_6
repeatId:1:j_id_c0_6
repeatId:2:j_id_c0_6
and when I define a id to the form (<h:form id="formname">) something like
repeatId:formname
repeatId:formname
repeatId:formname
which causes duplicateId (because the lack of the "iterator-number" in the name)?
Does this make sense?
I have solved it; error was elsewhere: I have forgotten in an included tag file which caused the js warning (which broke the calendar).
many thanks

Jsf 2 - ajax event update

I am trying to update a dropdown on change of value in a previous dropdown(in another form,another xhtml file). This is the code that am using as of now :
...
<f:selectItems value="#{createbill.episodeSetting}"/>
<p:ajax event="change" update=":chargesForm:tab2:serviceSetting"></p:ajax>
...
when this value is changed, i require the same value to show up in the other dropdown,which is in a different form(chargesForm) which is in a different file. The important thing to note is that both the dropdowns have the same values.
This code is not functioning as i per the requirement I mentioned above.
Please suggest...

JSF 2.0 - Ajax and Rendered Components

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...

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...

RichFaces: Displaying a notification "popup" when AJAX operation succeeded

We are currently developing a B2B web shop based on Java EE 5, JSF, Facelets and RichFaces. The technology has really worked very well so far, but now I am facing a small problem I just can't figure out how to solve:
Products are listed as tables, where every item can be added to the shopping basket by clicking on a small icon at the end of the row. Adding the product is done via AJAX to avoid the full reload of the page. This works without any problems just by using a h:dataTable and an a4j:commandLink to call an action-method which adds the selected product to the basket. Even the re-rendering of the basket total always visible in the side-bar is working properly.
Due to the nature of AJAX, there is no visible indication (except the changing total at the side) that the operation was successful or has been completed at least. Now I want to add a little "popup" box, which is made visible next to the add-icon when the AJAX-operation is completed, stating that the item was added to the basket. This box should automatically go away after a few seconds.
This is what I think should work (the popup_message and popup_content css-classes make the box float above the position where its markup is):
<h:dataTable ....>
...
<h:column>
<a4j:commandLink action="...">
<rich:effect event="oncomplete" targetId="addedMessage"
type="Appear" />
<rich:effect event="oncomplete" targetId="addedMessage"
type="Appear" params="{delay:3.0, duration:1.0}" />
</a4j:commandLink>
<a4j:outputPanel id="addedMessage" styleClass="popup_message"
style="display: none">
<a4j:outputPanel layout="block" styleClass="popup_content">
<h:outputText value="Item added!" />
</a4j:outputPanel>
</a4j:outputPanel>
</h:column>
</h:dataTable>
Unfortunately, it doesn't display the box at all. If I change the event of the "Appear" effect to onclick it works almost as expected. It is immediately shown when the icon is clicked and it dissapears 3 seconds after the AJAX operation was completed. But I don't want it to appear immediately after the click, because it would be wrong to indicate that the item was added to the basket, when in fact the operation hasn't even started yet. This becomes even more important, when I want to indicate some error or want to include some item specific information into the box, which is only available after the item was added.
So any ideas how to do this? And why adding two effects for the same event does not work?
(I've already looked at the effect-example from the RichFaces live demo. The examples do almost work the same, execept that they add the second effect with explicitly stating the for attribute. But even this does not work for me.)
Update: I've tried using the rich:toolTip for this purpose, which actually seems to be quite flexible. But no matter what I do, I can't attach anything to the "oncomplete" (I've also tried just "complete") event of the a4j:commandLink, except one effect... seems there is some bug/undocumented behaviour regarding that event. I've just found this bug report: RF-3427
you can try rich:notify for this
http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=notify&skin=blueSky
Have you tried rich:status ? I will not post a piece of code. I think the docs will do just fine.
http://livedemo.exadel.com/richfaces-demo/richfaces/status.jsf
Your defining targetId outside the parameters. What you want to do is:
<rich:effect event="oncomplete" type="Appear" params="targetId:'addedMessage',delay:3.0, duration:1.0" />
Try that, and I think it will work.

Resources