how does PrimeFaces' AjaxStatus work? - ajax

I am trying to understand PrimeFaces' AjaxStatus indicator.
There are two facets - start and complete.
Can anybody tell me, what really determines start and complete.
I am just trying to make the indicator GIF image visible when user clicks a button and make it disappear when he click another button.
If whatever I am trying to achieve does not make any sense, an explanation would be really helpful.
Thanks.

ajaxStatus component works with globally set components. This means that a commandButton with the attribute:
global="true"
will trigger a process that will make use of ajaxStatus component (will update it's output).
This said, ajaxStatus start facet will work when the listener method is called and will update when the complete status is reached, this is, when the lifecycle of the call ends.
As I understand, this will not take care of the success or failure of the process. For this statuses, you also have other facets available: error and success.
<p:ajaxStatus>
<f:facet name="prestart">
<h:outputText value="Starting..." /> </f:facet>
<f:facet name="error"> <h:outputText value="Error" />
</f:facet>
<f:facet name="success"> <h:outputText value="Success" />
</f:facet>
<f:facet name="default"> <h:outputText value="Idle" />
</f:facet>
<f:facet name="start"> <h:outputText value="Please Wait" />
</f:facet>
<f:facet name="complete"> <h:outputText value="Done" />
</f:facet>
</p:ajaxStatus>
There is an ajax loading gif bundled with PrimeFaces:
<h:graphicImage library="primefaces" name="jquery/ui/ui-anim_basic_16x16.gif" />

Related

Howto validate an entity shared over multiple tabs

I am having an entity with many attributes which should be displayed in multiple tabs in a p:tabView. It might look like the following.
I have one h:form which surrounds the p:tabView. In the tabs I have a single p:message for every input element.
<p:column>
<p:outputLabel value="Name" for="name_input" />
</p:column>
<p:column>
<p:message for="name_input" display="icon" />
</p:column>
<p:column>
<p:inputText id="name_input" value="#{bean.person.name}">
<p:ajax /> <!-- put value into backingbean on tabchange -->
<f:validateRequired />
</p:inputText>
</p:column>
I have made the following observations.
1) Problem: validation is only executed in tabs which have been activated
If I switch to edit mode and the current tab has no validation errors and I do not change the tab, then my entity gets saved and validation error on other tabs are ignored.
If I switch to edit mode and navigate to a tab which has validation error and then navigate to the first tab with no validation error, then a vaidation error is displayed (but only from those tab, that I visited).
(I hope this is understandable, at least a little bit) It does not make a difference if I set dynamic=true/false and cache=false in the p:tabView.
2) Problem: no message icon on tab change
If I switch to edit mode and click on every tab so that every validation error are recognized (like in scenario b) I get a proper validation message (icon) and the p:inputText is displayed with a red border. So everything seems to be fine. But if I navigate to another tab with validation errors there is no message icon displayed, only the red border is around the particular p:inputText. As far as I would guess, the JSF lifecycle is executed on tab change but no validation takes place so for this lifecycle roundtrip everything is OK and the message icon disappears (on the other hand it is a mystery to me why the red border does not disappear...).
3) Problem: no visual hint in the tab
For the user experience I would very much like to have a visual hint (i. e. a red background on a tab-title) so that a user knows where the problems occur.
I have read Validating one form with multiple tabs, how to switch tabs without losing validation errors? Using Myfaces and Trinidad but neither the wizard (it is not a "wizardy" task it is just an edit of a big entity) nor the do-it-yourself-with-javascrip-and-css (main problem is the corporated identity I am using pretty often tabViews in other situations) is a good option for me.
Does anyone have a solution/hint for any of my problems?
I am using JSF 2.2, Primefaces 5.3.
OK, a colleague of mine came up with the answer.
First of all, my first two problems vanished into thin air. With the attributes dynamic="false" and cache="false" in the <p:tabView /> this works as desired (I do not know what I tested back then).
And the visual hint in the tab. There is a <f:facet name="title" /> which can be used to display the tab title and additional messages. The <p:message /> components are doubled, firstly inside the column at the input component and secondly in the title-facet. With a little CSS one can adjust the icons in the title at will.
<p:tabView dynamic="false" cache="false">
<f:facet name="title">
Address
<p:message for="name_input" display="icon" />
</f:facet>
...
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Name" for="name_input" />
</p:column>
<p:column>
<p:message for="name_input" display="icon" />
</p:column>
<p:column>
<p:inputText id="name_input" value="#{bean.person.name}">
<p:ajax />
<f:validateRequired />
</p:inputText>
</p:column>
</p:row>
....
</p:panelGrid>
</p:tabView>

<h:dataTable> not updating/refreshing after <f:ajax> has been performed

I am having some issues with my <h:dataTable> where I cannot get it to update/refresh upon submitting an <f:ajax> request which, resides within this table component. The <f:ajax> listener attribute triggers a specific row to be removed from the <h:dataTable>. Could someone please assist me in getting this to work.
Code fragment from my JSF page:
<h:dataTable id="table1">
<h:column>
<f:facet name="header">Object Name:</f:facet>
<h:outputText value="#{object.name}"/>
</h:column>
<h:column>
<f:facet name="header">Action:</f:facet>
<h:form>
<h:commandButton value="Delete">
<f:ajax listener="#{objectBean.delete(object.id)}" render=":table1"/>
</h:commandButton>
</h:form>
</h:column>
</h:dataTable>
I have also tried to wrap this <h:dataTable> component within a <h:panelGroup> component and it still did not work unfortunately. Any tips on getting this to work?
Refer to : Datatable not rendering with ajax call in jsf
Move your to wrap the whole datatable, check your network traffic in chrome F12 to see what the sent/returned response is and see if its giving you back the right table to update.

How to Display 'Loading...' image before rendering on ajax calls

I have written this code
<a4j:ajax event="valueChange" render="second,third" immediate="true" />
I want to display a progreess bar or 'Loading...' image while we are getting the response from server.
Is there a component availble that will allow us to do this?
A component already exists within the a4j library. Use the <a4j:status> component. Say you're loader (animated gif) is called ai.gif, then your code would look like this.
<a4j:status>
<f:facet name="start">
<h:graphicImage value="/images/ai.gif" alt="ai" />
</f:facet>
<f:facet name="stop">
<!-- no image; successfully loaded, or could display a checkmark or something -->
</f:facet>
</a4j:status>
See Also
RichFaces Showcase - Ajax Output/Containers
RichFaces Dev Guide - JBoss

Fire AJAX twice from same component (simultaneously)

Well, I want to fire AJAX from one component but for two destinations, let some code clear out what I mean with that :
<p:growl id="growl" showDetail="true" sticky="true" />
<p:inputText value="#{someBean.someProperty}" >
<f:ajax event="blur" render="growl" listener="#{someBean.someListenerMethod}"/>
<f:ajax event="blur" render="updatable" />
</p:inputText>
<h:outputText value="#{someBean.someProperty}" id="updatable" />
So once the blur event occures, the <h:outputText> and the <p:growl> will be "AJAXed" (in primefaces tongue : updated). I had this example in mind and anther one that replaces the second <f:ajax> with an update attribute in <p:inputText>, but neither done me good.
Hopefully, you're going to know better and aid me solving this out, thanks in advance.
You can add more than one item inside the render attribute :
<f:ajax event="blur" render="growl updatable" listener="#{someBean.someListenerMethod}"/>

Primefaces components to update when commandButton is clicked

Lets say we have button
<h:form>
<p:commandButton id="refreshButton" value="refresh all depending components"/>
</h:form>
Along the way I will add components that should be updated when the button is clicked. So using the update="text1,text2" will not suffice, as text3 might be added later on and shouldn't require changes to the refresh button.
<h:outputText id="text1" value="{bean.someValue1}></h:outputText>
<h:outputText id="text2" value="{bean.someValue2}></h:outputText>
... and later ...
<h:outputText id="text3" value="{bean.someValue3}></h:outputText>
What I want to do is to bind the components to the button, rather than the button having dependencies to the components
What you're asking is not possible. As least, not using the standard ways in the view.
But what is possible is to reference a common parent instead.
<p:commandButton ... update="texts" />
...
<h:panelGroup id="texts">
<h:outputText id="text1" ... />
<h:outputText id="text2" ... />
...
<h:outputText id="text3" ... />
</h:panelGroup>
Depending on the concrete functional requirement, which isn't clear from the question, there may be better solutions. But if it boils down to laziness and/or avoiding to "forget" to change the button, then I'm afraid that there's no magic fix.
I did a a temporary quickfix by using
<p:outputPanel autoUpdate="true">
<h:outputText id="text3" ... />
<p:outputPanel />
Guess it performance wise is not perfect, as it will be updated on all ajax events and not just the ones I'm interested in. But luckily this component is interested in all of them any ways, so it is not a problem atm.

Resources