JSF jumping to anchor right away - jsf

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.

Related

All tabs of tabpanel refreshed, when event happens in any one of the tab (Richface 3.3.4)

We have a tabPanel which has multiple tabs. When any event is performed in any of the tabs (e.g. click 'ajaxSubmit' button in tab1) all tabs are refreshed which is causing performance issues (e.g. getter of 'table' value is always invoked from tab3).
We tried to wrap the content of each tab in <a4j:region>, but the getters of components in tab3 are still invoked.
Please find the sample code snippet below:
<r:tabPanel id="tabWorkingPanel" styleClass="otTMcontainer" selectedTab="#{tabHandlerBean.activeTab}">
<rich:tab id="tab1">
<h:commandButton value="ajaxSubmit"/>
</rich:tab>
<rich:tab id="tab2" />
<rich:tab id="tab3">
<rich:dataTable id="table" value="#{bean.someValue}">...</rich:dataTable>
</rich:tab>
</r:tabPanel>
I think you should be using reRender so that only relevant tabs are refreshed. I think you should also wrap the contents of each tab in a form so that not everything is submitted on each submit, though perhaps that's what you were trying to do with region. I would carefully read the documentation to make sure you're using these correctly.
I have not used RichFaces, so I'm not positive this will work, but a similar approach works for PrimeFaces.
BalusC's description of process and update may be useful. He's discussing PrimeFaces, but I think the same concepts apply.

Primefaces dynamic label for progressbar

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.

Open new window by POST using h:commandButton

I need to open a JSF page in a new window by POST on click of a <h:commandButton>. I know I can acheive this using the JavaScript. But I would like to achive this using JSF and not JavaScript.
How can I achieve this? I'm using JSF 2.0.
The only non-JS way is to set target="_blank" in the parent <h:form>.
<h:form target="_blank">
...
<h:commandButton value="Open in new Window" />
</h:form>
This however affects all non-ajax(!) actions which are performed in the very same form. So if you're smart, make the action which shouldn't open in a new window an ajax action. However, ajax is also JavaScript and you mentioned that you don't want to use JS (I hope you don't get shocked once you discover that PrimeFaces is actually full of JavaScript).
If you absolutely need to restrict it to a single action, then you really can't go around asking little help to JavaScript.
<h:form>
...
<h:commandButton value="Open in new Window" onclick="this.form.target='_blank'" />
</h:form>
When you restrict the target only to a single action, maybe you want to get the form in its initial state.
With the oncklick action you set the target of the form to a _blan page.
After the click, the page is opened in a new tab/page (triggers the action event).
At last, the onblur action is triggered and set the form again to its initial state (the rest of the buttons will open in the _self page)
With this code, you can restrict to only a h:commandbutton to open in a new page.
The rest of the buttons will be opened in the self page:
<h:commandButton
onclick="this.form.target='_blank'"
onblur="this.form.target='_self'"
id="listadoRebuts"
action="#{giaquaBusquedaCorte.abrirListadoRebuts}"
value="#{msg.seqVisorbtnRecibos}">
</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()

How to Refresh only components in certain 'box'

Say I have a websites with 3 panel grid (just for example..) and I would like to have buttons inside each grid that only cause the contents of that grid to refresh so the rest of the page doesn't necessarily have to refresh.
How do I do that?
I tried to have a form sorround that grid but it seems like the rest of the page still gets refreshed.
A Note - I'm trying to achieve something like what happens when you work with a picklist. when you move the objects between the lists there doesn't seem to be any page refresh...
Thanks!
If you are using RichFaces, you should definitivly check the Ajax chapter of the RichFaces manual. I think you will find everything you need to know there.
Here a small example for partial page rendering:
<a4j:commandButton value="update" reRender="infoBlock"/>
<h:panelGrid id="infoBlock">
<!-- Some content-->
</h:panelGrid>

Resources