Show / hide component based on page I'm in - jsf-2

I need to show, or hide a search component in my JSF2 application based on the page the user is on. I'm trying to do this by setting a "fromPage" attribute into the session, for example like this:
session.setAttribute("fromPage", "aboutUs");
These attributes are being set whenever the user clicks on a link in the homepage, and I check for them while serving the site's pages. It works well when I use h:commandLinks.
But when I change to h:link this stops working because apparently all the "outcome" methods of h:links on a page are getting called when the page is rendered, and so the "fromPage" attribute always represents the last "outcome" method called -- and it's useless for my purpose.
So, is there any other way to know which page is the user clicking to? And which page am I on?

Use UIViewRoot#getViewId() to learn which view is currently been opened. The current UIViewRoot is available by the implicit EL variable #{view}.
<p>Hi user, you're on #{view.viewId}.</p>
<h:panelGroup rendered="#{view.viewId == '/aboutUs.xhtml'}">
<p>This will be rendered when the current view is aboutUs.xhtml.</p>
</h:panelGroup>

Related

JSF viewScopedBean and back button issue

I have an application that uses a viewScoped bean for jsf xhtml page. This page consists of two htmlPanelGroup components out of which only one gets rendered depending on an attribute's boolean value in the page bean. When the page loads it displays panelGroup1 for verification of a user input in inputText field. A command button submits the value to the pageBean. If verification succeeds then pageBean method sets a boolean value and returns null and reloads the same page however this time it renders panelGroup2.
Now this panelGroup displays input fields and then a commandButton. This command button's action calls a method in pageBean which first validates the input and then if successful returns the next xhtml name with faces-redirect option set to true.
The problem is that the next page is displayed but when I click on back button, the browser displays "Document Expired" page and asks to reload. If i reload the page, somehow the previous page again gets displayed with panelGroup2! I have used the filter to set the headers and no cache option but still it doesnt work. Ideally if it loads the previous page I would expect it to display it with panelGroup1. Not sure what is the issue here. Can anyone provide any inputs on this?

Struts 2 - Tiles-Result with HTML Anchor

is it somehow possible to add an anchor (or hash) to a Struts 2 Action-URL? To be specific:
I have a html form which can be extended with more fields if the user clicks a button "add more fields". This Button sends a html submit to the backend (Action "thismyaction") where a list object is filled with another set of input fields. The action then returns to a tile "thisismyform" which loads the same jsp as before, where the new fieldset is visible.
(Unfortunately there is no way to achieve that via ajax / JS in this project at the time. I know that you usually add fields that way, but i got the project as it is.)
Each fieldset is counted (fieldset-0, if user adds more fields another set is added "fieldset-1"). The sets always contain the same fields, but enumerated.
What happens here? There is a post to the action which generates another fieldset and redirects back to the same page, where it renders all fieldsets. Important: the result type is "tiles"! I guess this is what makes it difficult.
Now I want to dynamically add an anchor to this URL "thisismyaction.do", like e.g. "thisismyaction.do#fieldset-1". Use Case: User adds another fieldset, post to the action => result type="tiles" => JSP, user sees reload of the page with the new, second fieldset and gets "scrolled" to the second fieldset via the anchor. Is that possible?
I hope I could describe it properly, what I want to achieve... If there are questions, feel free to ask.
Simplest way I can think of right away is
<script type="text/javascript">
window.location.hash = "fieldset-<s:text name="latestIdOfFieldSet" />";
</script>
If you can figure out what's gonna be latestIdOfFieldSet before you render your jsp and set it in your action method. you should get what you are trying to do.

Displaying Data on Page without refreshing

MVS 2010 MVC 3:
I have a Submit page that has severial checkboxes that are been built dynamically as soon as the page load. The user can check one or more checkbox before submitting the form. On the right hand side of the page, there is somewhat a summary of all the previous selections that the user chose. The summary is available from the Submit page and will carry to the other pages. There is an "Add Comment" button at the very top of the page. When the user click it, a popup window with a textbox will display allowing the user to type a comment. How do I display this comment on the page without having a refresh the page?
The main reason for not wanting to do a refresh is because the user could have selected one or more checkboxes, they will lose their states as soon as the page is refreshed.
I tried parent.document.getElementById('DivCommentResult').html(data); - It displayed this message "Microsoft JScript runtime error: Unable to get value of the property 'html': object is null or undefined"
If I understand well, you have to bind the change of your check box to a function that submit a synchone ajax request that obtain the summary you need and replace target content with the result data of your request.
Is it what you want ?
I had to get the parent doucment and retrieve the div id from it.
Once I have it in hand, I set its innerHTML text to the data that I want to display.
var parentDocument = parent.document;
var el = parentDocument.getElementById('commentResult');
Once I have this, I simpley call el.innerHTML = data;

jQuery mobile hiding initial page instead of removing it

I've been searching for a way to remove the initial page container after jQuery mobile loaded the next page content via $.mobile.changePage(...)
What I'm experiencing is that this initial DIV element, created when the page is first shown will always remain on the page - and will only be hidden after calling $.mobile.changePage(...)
I need this initial page container to be removed instead, since some old data reside there that should be reset on first page change.
Anyone has a solution? Been searching the web for it but to no avail.
I have also tried to do $('#first-page').remove() after I called $.mobile.changePage(...), but that will remove the initial page and make the new loaded page hidden!
EDIT: solved by clearing up the initial DIV using .html("")
You could just make next page load without ajax, this should remove the initial page.
data-ajax="false"
Hope this helps!
I take it that you are dynamically creating these pages. There is a hidden method in the API, but you can apply it to any page and then upon that page's exit, it will be removed.
$.mobile._bindPageRemove
So, it might look like this
newpage.attr( "data-" + $.mobile.ns + "external-page", true ).one( 'pagecreate', $.mobile._bindPageRemove );
NOTE: Since this is a hidden method, it is part of the hidden API and could be subject to change without notice upon upgrade. Test carefully upon upgrade if you use this.
I did:
$.mobile.changePage('login.html', {changeHash:false});
changeHash (default: true) Type: Boolean Decides if the hash in the
location bar should be updated. This has the effect of creating a new
browser history entry. It also means that, if set to false, the
incoming page will replace the current page in the browser history, so
the page from which the user is navigating away will not be reachable
via the browser's "Back" button.

Is JSF 2.0 View Scope back-button safe?

Is the JSF 2.0 View Scope "back button" safe? e.g. if I store a model in View Scope and go from page 1, page 2, page 3, to page 4, modifying the model object along the way (via input fields), and then hit the back button twice to go back to page 2 and make changes (taking me again to page 3), will the model in view scope have only changes that were made when page 2 was originally rendered or will it have later pages' changes?
Oracle ADF had/has something called "process scope" that handles this by tokenizing what is placed into session, so each page has its own copy of the model.
To start, the view scope is bound to a particular page/view. Multiple views won't share the same view scoped bean. The view scope starts with an initial GET request and stops when a POST action navigates with a non-null return value.
There are in general the following scenarios, depending on whether the browser is instructed to cache the page or not and the JSF state saving configuration. I'll assume that the navigation between those pages took place by a POST request (as it sounds much like the "Wizard" scenario).
When the back button is pressed:
If browser is instructed to save the page in cache, then browser will load the page from the cache. All previously entered input values will reappear from the browser cache (thus not from the view scoped bean in the server side!). The behavior when you perform a POST request on this page depends further on the javax.faces.STATE_SAVING_METHOD configuration setting:
If set to server (default), then a ViewExpiredException will occur, because the view state is trashed at the server side right after POST navigation from one to other page.
If set to client, then it will just work, because the entire view state is contained in a hidden input field of the form.
Or, if browser is instructed to not save the page in cache, then browser will display a browser-default "Page expired" error page. Only when the POST-redirect-GET pattern was applied for navigation, then the browser will send a brand new GET request on the same URL as the redirect URL. All previously entered input values will by default get cleared out (because the view scoped bean is recreated), but if the browser has "autocomplete" turned on (configureable at browser level), then it will possibly autofill the inputs. This is disableable by adding autocomplete="off" attribute to the input components. When you perform a POST request on this page, it will just work regardless of the JSF state saving method.
It's easier to perform the "Wizard" scenario on a single view which contains conditionally rendered steps and offer a back button on the wizard section itself.
See also:
javax.faces.application.ViewExpiredException: View could not be restored
What scope to use in JSF 2.0 for Wizard pattern?

Resources