How to move within only one part of the page - jsf

I have read many answers written mainly by BalusC but still no luck.
So I included via ajax rendering, a page in the part of the main page and it works perfect, whenever I click the button on the main bar the subpage xhtml is shown in the proper place. Now the problem is that i want to implement in that subpage a "selectOneMenu" so whenever a user clicks on one of the options he will be redirected to another xhtml which should appear on the same part of the page (instead of the previous page). I have already thought of many ideas to solve that(including conditional rendering), but I believe that there has to be much simpler and more correct way to solve it. Maybe JSF has some kind of container tag which could be used?
PS
By the way that is my first post so sorry if I didnt make something clear.
UPDATE
It appeared to me that maybe I should somehow use ajax onValueChange which would read the value (via the actionListener ?) so when the user clicks on subpage the main page would read the value and render part with the new content. Is that even possible?

You can use valueChange Listener to get the new value and in your bean using FacesContext you can redirect the page but make sure that you add ajax call to your selectonemenu if you dont want your page to refreshed.
<h:selectOneMenu value="#{some.value}"
valueChangeListener="#{some.valuechanged}">
<f:ajax event="change" listener="#{some.listen}" />
</h:selectOneMenu>

Related

h:commandButton with an action and then page-navigation in JSF?

Is it possible to have a commandButton that executes a method of a certain backing bean and then also navigates to a different page?
I know that I could return a String in the method that the commandButton calls, but the method is also used on the target-page, meaning it's often called from that same page.
So for calls that come from the same page, the redirect would be unnecessary and I would like to avoid that.
The options that I have in mind right now:
Create a separate method for the "remote" call of the method that does the same logic and also redirects to the page
Use an additional h:button and use JavaScript so that if the commandButton is pressed, the h:button is pressed at the same time (Probably bad practice tho)
Any option I am missing? Is there any way to tell the commandButton itself that it's supposed to navigate somewhere or do I have to implement this in the backing-beans?
Your title and first sentence are 'dangerous' and sort of not on topic since to both, the answer is yes and you sort of describe (= answer) that in your second paragraph already yourself.
The real question further on effectively asks about conditional navigation. But let me state first that your solution of two methods is also not wrong if you just make sure you don't do actual work in the bean (which you should not).
Now conditional navigation is by itself not difficult
returning null (to stay on the same page) without a refresh, "" to stay on the same page with a refesh,
return the new page (with redirect).
All basic JSF which I assume you are already aware of and this just requires something to do one or the other
So then the question remains if you can
detect the page you are on when the method is executed or
pass on a parameter to the action
which in turn can be used to return null or the other new page in an if/else.
Page1:
<h:commandButton action="#{mybean.action(true))" />
Page2:
<h:commandButton action="#{mybean.action(false))" />
Bean:
public String action(boolean navigate) {
doWork();
if (navigate) {
return "page2.xhtml?faces-redirect=true";
} else {
return null;
}
And if you'd want it, you could even pass null or the page name as a parameter to the method call.
Implementing detection of the source page of the action has the advantage that in the UI you do not need any knowledge on how to navigate, you always call the same method without any parameters and each new page you'd use this action on navigates to the right page without the developer needing any knowledge.
So take you pick.
I'm not completely sure if I got you right, but you could do something like this:
<h:commandButton value="Click" action="otherPage.xhtml?faces-redirect=true">
<f:actionListener binding="#{bean.method}" />
</h:commandButton>
Keep in mind that actionListener will be fired first and after that action from commandButton. Hope it helps.
Update:
Due to the fact that there was no further thinking you can use commandButton with or without redirect.
<h:commandButton value="Click" action="{bean.method}"/>

JSF CustomeScope reset for specified view

How can I control what customscope is created during request. Right now I have solution that when I click the commandLink:
<h:commandLink action="orders">
<f:actionListener type="com.mk.web.jsf.scope.ResetScopeListener" />
<span data-shortcut="F6" class="start_link">Orders</span>
</h:commandLink>
The custom scope is destroyed and a new one is created. But the problem is that the custom scope only resets if I enter the customers action using this commandLink from above.
When I enter to customers action by directly entering the url in browser the custom scope is not reset. How can I make that is customers action is loading even by commandLink or by url then always this custom scope should be reset. Can somebody give me some advice how to achieve this?
Thanks...
Typically you use a custom scope when you want your beans to live longer than the original request but shorter than the session. Based on your scenario though, it seems to me that your custom scope is behaving slightly like a request scope. Anyway, maybe I'm not understanding your scenario fully but one thing that comes to mind is that you can use system events in case a user decides to go to the next page when they type the address directly. So suppose the user tries to go to nextPage.xhtml, it could be defined like this
<f:event type="preRenderView" listener="#{bean.performPossibleCustomScopeCleanUp}" />
<h:head>
</head>
The (pseudo) method above will fire before the view root (aka nextPage.xhtml) is rendered. Inside the method you can check to see if your custom scope is still "alive" and you will handle it as needed. Keep in mind though that this event will be fired every time the page is requested. For instance, if you click the h:commandLink performPossibleCustomScopeCleanUp will still be invoked. There are ways around that
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
Just scroll down to the section Performing business action on GET parameters of the answer
An even better approach would be to implement a custom NavigationHandler through JSF's ConfigurableNavigationHandler API so you can keep track of the URL and perform actions as needed.
I didn't dig too dig so you might actually find a better code sample. Hope this helps.

Semantics of "?faces-redirect=true" in <commandlink action=...> and why not use it everywhere

I would like to understand what are the semantics behind appending the "?faces-redirect=true" in the action property of a <h:commandlink> tag in JSF2.0. Whether with it or with out it, the application indeed navigates to the target page specified in the action. So at first glance it seems that the only effect is cosmetic, i.e. to provide feedback to the user (if he is looking at the browser's visited URL) that he has moved to a new page. But if it is so innocuous and side-effects-free I cannot see why it is not the default behaviour. I suspect that it has to do with the post-based mechanism of JSF2.0. I 've noticed when browsing through a JSF application that the URLs one sees at his browser (when ?faces-redirect=true is not used) are the ones of the "previous" "page".
meta-NB. I am behind a firewall and plagued with the "SO requires external JavaScript from another domain" issue so I apologize for the absence of formatting. I will also provide feedback on your answers in a few hours, when I can access from another domain.
Page-to-page navigation should not be performed using POST at all. You should be using normal <h:link> or <h:button> for this instead of <h:commandLink> or <h:commandButton>.
So instead of
<h:commandLink value="Next page" action=nextpage.xhtml?faces-redirect=true" />
you should actually be using
<h:link value="Next page" outcome="nextpage.xhtml" />
This has the major benefit that the website is now SEO friendly. Searchbots namely doesn't index forms.
Use the <h:commandLink> only if you need to submit a form with some user input. But more than often the result is just presented in the same page, if necesary conditionally rendered/included. Only on successful submits which absolutely needs to go to a different page (e.g. login/logout), you should indeed be sending a redirect. This is the so-called Post-Redirect-Get pattern.
See also
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?

jsf, richfaces, popup window

I would like to make a list-detail view with richfaces. There will be a link for every record in the list that should open a new window containing record details.
I tried to implement the link this way:
<a4j:commandLink oncomplete="window.open('/pages/serviceDetail.jsf','popupWindow', 'dependent=yes, menubar=no, toolbar=no, height=500, width=400')" actionListener="#{monitoringBean.recordDetail}" value="details" />
I use <a4j:keepAlive beanName="monitoringBean" ajaxOnly="false" /> for both the list and the detail page. recordDetail method fills the data of the selected record to a variable of the bean that I would like to display on the detail page.
The problem is that keepalive doesn't work, so I get new bean instance on the detail page every time. So the the previously selected record from the other bean is not accessible here.
Is there a way to pass parameter (id) to the detail page to handle record selection. Or is there any way to make keepalive work? (I this this would be the easiest).
Thanks
Avoid using window.open(..) - it will fail on most browser configurations nowadays (due to pop-up blocking).
Use <rich:modalPanel> instead.

Problem With JSF 1.1 and PopUp

I am trying to popup a window when someone clicks a button on the data table.
<h:commandButton
action="#{cacheController.popupDetails}"
immediate="false"
onclick="popup()"
value="View Details"
styleClass="submit">
</h:commandButton>
The associated popup function is
function popup() {
window.open('RDDetails.jsf','popupWindow', 'dependent=yes, menubar=no, toolbar=no, height=500, width=400');
}
Now in the new 'RDDetails.jsf" file, I am trying to access the same managedBean cacheController. But the problem is, the pop-up window and JSF lifecycle is not in sync. As a result, the popup first displays blank and when I refresh, it pulls out the proper data.
Is there anyway I can click on a button which will do some processing in the managed bean and then opens a pop up which rerieves the processed data from the managed bean.
I am using JSF 1.1.
You're here basically firing two independent requests: one associated with the form submit and other which opens the RDDetails.jsf in a popup. You'll need to combine this in one request. You can achieve this in basically two ways:
Get rid of the onclick and just add target="_blank" to the <h:form> so that it get submitted into a new window/tab.
Block the default action by adding return false; to the onclick and do the business logic in the constructor of the bean associated with RDDetails.jsf. The only (major) caveat is here that the model won't be updated with the form fields. Thus, you'll need to pass the form fields as request parameters of the popup URL manually with help of JavaScript. You can then make use of managed property entries in the faces-config.xml to inject the GET request parameters into the model.
First way is obviously the easiest, but this doesn't give you a "fullworthy" popup/modal dialog. The second way is a bit harder (unless you've already a good grasp on both JavaScript and JSF). I would then consider to look for a component library which provides a ready-to-use popup component.
See my example:
<h:commandLink action="#{controller.myAction}" onmousedown="document.forms['idform'].target='_blank';">
I'm using jsf 1.1

Resources