Primefaces dynamic label for progressbar - jsf

Hi I am using JSF with Primefaces. I have a long task, during which I want to show user a progress bar, with the progress (int) and status (String) as an indicator. The two parameters are mapped to the two fields of a backend bean. If I use <p:poll>, I can update both, as in the following code:
<p:progressBar id="progress" ajax="false" value="#{backendBean.progress}" widgetVar="pbAjax"
labelTemplate="{value}%: #{backendBean.statusMessage}" style="width:400px; font-size:12px"/>
<p:poll interval="1" id="poll" autoStart="false" update="progress" widgetVar="pbPoll"/>
Once user press a button, pbPoll.start(). This works fine. Now I have two questions:
(1) is it possible to hide the progressbar initially? I know I can put display:none in the css and let it show up when the button is clicked. But the poll update will hide the progressbar again. Maybe use rendered. If so, please tell me how.
(2) can I use without poll since progressBar has ajax function itself? Notice that I set ajax=false in the code above. On their website, it says "dynamic progress label" is added. I tried but somehow the label only displays the "{value}%" without the statusMessage. I wonder if this is because #{statusMessage} requires another fetch, therefore ignored, while both are retrieved in poll.
Thank!

Yes you can. It's actually really easy. Wrap your <p:progressBar/> in a panel like <h:panelGrid/> and set the rendered attribute on the progress bar to a boolean in the backing bean
<h:panelGrid id="progressBarPanel">
<p:progressBar id="progress" interval="100" rendered="#{backendBean.progressBarRendered}" ajax="true" value="#{backendBean.progressMonitor}" widgetVar="pbAjax" labelTemplate="{value}%: #{backendBean.progressMonitor}" style="width:300px; font-size:12px"/>
</h:panelGrid>
and then use a button (or something) to toggle the value of the boolean and update the panel
<p:commandButton value="Test Progress Bar" action="#{addressUpdate.progressBarControl}" oncomplete="pbAjax.start();" update="progressBarPanel"/>
One thing you need to be careful about is that the same button that toggles the progress bar's visibility should not use the onclick event but rather the oncomplete to start the progress bar, the reason being that onclick fires before the request hits the server and as at that time, the progress bar does not exist in the DOM so start() will be undefined.
You're right on that one. If you'll take a look in your developer console, you'd see the following for the ajax response to the progress bar
"thePanel:progress_value":20
And that pretty much sums up what the progress bar cares about during the update, the value binding on the bar. Stick with what you have now if this is a must-have for you.

Related

Bean value is getting set on click of a cancel button in JSF, How to avoid this? [duplicate]

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

CommandButton produces change event causing two axjax requests

I have a <p:inputText> with a nested <p:ajax event="change" listener="myValidate"> and a <p:commandButton actionListener="myValidate" process="#form">.
The problem is, that the myValidate method is called twice, because pushing the commandButton first triggers the onChange-Event (when edtiting the text before clicking CommandBt) what then calls the myValidate method. After that the myValidate is called by the CommandButton actionListener.
How can i prevent the double call?
What I need is:
call myValidate when leaving inputText after change text
call myValidate when pushing CommandButton (what is sadly implicit triggering the other one)
thanx for help in advance.
If you specify update and process, the ajax request will be called onBlur (when the field loses focus):
<p:inputText>
<p:ajax event="change" listener="myValidate" update="myForm" process="#form">
</p:inputText>
But note, if the input loses focus in that way that you click on the command button, than there will be 2 subsequent AJAX calls. It's because the first is triggered by the javascript onBlur event, and the second by the onClick event on the button. However, only in that case (if you go first to the other field, it will work as you expect).
The usual solution is to stick to JSF model and validate the whole form on submitting, not every single field on leaving it.

JSF jumping to anchor right away

When a JSF commandLink is clicked, the scrollposition of the new page will be 0 - which is fine.
I noticed a strange behaviour with one of my jsf pages - but its acuallty quite hard to explain:
Clicking on a link in order to navigate "somewhere" usually freezes the page and when the new response is received, you'll end up on another page and the scrollposition gets reseted. This is fine.
In that particular case the "current" view is immediately scrolling to the top, once a commandlink is clicked, and THEN forwards to the desired navigation outcome.
Its like clicking on a plain link, that has just its anchor set to the top. <a href='#'>
What could be a possible reason for this? It feels very strange, if the page scrolls up the second you click on a link.
All pages have basically the same usage of commandlinks within datatables. No other page encounters that problems. The Controllers are different - but since the scrolling up is done within milliseconds, I dont think, that this is a server-side issue.
I noticed that jsf appends the # to all links, that are generated.
so, when I click on the link, I can see the url changing to .../page.xhtml# for a split second (the split second, the page scrolls up), and then getting re-jsft like .../page.xhtml?cid=4
edit:
for all my pages, the link looks like this:
SVA
However on that said page the return false; at the end is missing... which then makes the link behave like an anchor...
edit2:
The working-as-expected-links are generated, using <h:commandLink> - the ones that are making the page scroll up, are <p:commandLink>s (Primefaces). Indeed, replacing it, solves the issue, but still wonder what's different for the primefaces link.
edit3: Example
working as expected:
<h:form style="display:inline;">
<h:commandLink
action="#{processManagementController.unpinProcess(process)}">
<h:graphicImage
style="display:inline-block; height:16px; width:16px;"
value="/resources/img/pinned.png"
title="Click to unpin this process" />
</h:commandLink>
</h:form>
causes immediate scrolling:
<h:form style="display:inline;">
<p:commandLink ajax="false"
action="#{processManagementController.unpinProcess(process)}">
<h:graphicImage
style="display:inline-block; height:16px; width:16px;"
value="/resources/img/pinned.png"
title="Click to unpin this process" />
</p:commandLink>
</h:form>
It's not scrolled to top due to href="#", but because of the synchronous postback (which results in a complete reload of the page!). The both examples in your "edit3" still scrolls to top for me.
Nest <f:ajax> in the <h:commandLink>, or set ajax="true" on the <p:commandLink> to make it an asynchronous postback and thus get them to behave as intented.

PrimeFaces CommandButton that Doesn't Process Data

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

A way to easily check if an element was rendered in jsf2

I have a button that is supposed to close a modal panel and render several elements.
Is there an easy way to check if an element was rendered after the button was pressed?
example button:
<a4j:commandButton onclick="#{rich:component('modal')}.hide();"
style="background-repeat:no-repeat;width:18px;height:18px;"
image="includes/images/close.gif"
render=":id1 :id2">
<f:setPropertyActionListener target="#{Controller.attribute}" value="false" />
</a4j:commandButton>
I have another button that does not "work" on the un-rendered div.
The conditon of the rendered attribute of all of the button's parent components must be preserved when you're submitting the form. So it should not only evaluate true during the request of presenting the form with the button, but it should also evaluate true during the request of processing the form submit. Easiest is to put the backing bean in the view scope by #ViewScoped.
Also, if you're re-rendering a component which in turn contains a <h:form>, you need to explicitly add the client ID of that <h:form> to the render attribute. E.g. when component with client ID id1 has in turn a <h:form id="formOfId1">.
render=":id1 :id2 :formOfId1"
You can debug this all by just exploring the HTTP traffic in the webbrowser's developer toolset (press F12 in Chrome/IE9/Firebug and check the "Network" section).
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - Points 5 and 7.
I have hit the same problem. My solution was to display the current time inside the element that i want to be rendered.
If, for instance, you want to render a panel, just paste inside that panel the following snippet:
<h:outputText value="#{session.lastAccessedTime}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS" type="date" />
</h:outputText>
If the time is updated after button click, then obviously the component was rendered. But is the opposite also true? If the time is not updated, does this mean the component was not rendered? What if the component got rendered properly, but the time displayed is frozen to the moment the page was first accessed? I had small doubts about that, so i refreshed the page, and the time changed. So the time displayed is not frozen to the initial moment.
Also note that there are multiple ways to get the time; if you don't like to use session time, you could set a property in the backing bean, and initialize it to new Date()

Resources