Load JSF page by id - jsf

I have a JSF 2.0 app where each page is stored in a cms_page table in the database. That table has the PK column cms_page_id and a URL column (which holds the SEO friendly URL).
When I display a page there is a link called About Us, which has the URL "/com/aboutus.html"
This appears in my XHTML file as:
#{cmsPage.cmsPageUrlName}/>
Which renders
About Us
As far as I know h:outputLink cannot be used to fire any methods in the backing bean.
I can't use h:commandLink, as this will not show the "/com/aboutus.html" URL when you hover over the link. I can't figure out how to fire a backing bean method to navigate to the next page.
The about us link would really be going to /faces/pages.xhtml, but would use PrettyFaces to display the "/com/aboutus.html" URL
Also, what would I to if I went directly to the URL www.test.com/com/aboutus.html?
This URL doesn't exist, the actual URL would be www.test.com/faces/pages.xhtml?url=%2Fcom%2Faboutus.html
Should I be looking at setting up PrettyFaces to do all the work instead?

create Databaseconnection
read column from the database
write the column into your jsf page
please take a look at JSF/JPA documentations or tutorials to solve this.

<ui:include src="#{cmsPage._url}" />
ManagedBean Name
#ManagedBean(name="cmsPage")
#SessionScoped
class Cms_Page{
private String _pageId;
private String _url;
//getter setter
}
Use Custom method to fetch from DAO and set the values inside Cms_Page

Related

Passing parameters: JSF page (form) -> ViewScoped backing bean -> JSP page (confirmation) [duplicate]

I have a browse.xhtml where I browse a list of cars and I want to view the details of the car in details.xhtml when a "View more" button is pressed. Their backing beans are #ViewScoped and are called BrowseBean and DetailsBean, respectively.
Now, I wouldn't like the user/client to see the car ID in the URL, so I would like to avoid using GET params, as presented here and here.
Is there any way to achieve this? I'm using Mojarra 2.2.8 with PrimeFaces 5 and OmniFaces 1.8.1.
Depends on whether you're sending a redirect or merely navigating.
If you're sending a redirect, then put it in the flash scope:
Faces.setFlashAttribute("car", car);
This is available in the #PostConstruct of the next bean as:
Car car = Faces.getFlashAttribute("car");
Or, if you're merely navigating, then put it in the request scope:
Faces.setRequestAttribute("car", car);
This is available in the #PostConstruct of the next bean as:
Car car = Faces.getRequestAttribute("car");
See also:
Injecting one view scoped bean in another view scoped bean causes it to be recreated
How to pass objects from one page to another page in JSF without writing a converter
Note that I assume that you're very well aware about the design choice of having two entirely separate views which cannot exist (be idempotent) without the other view, instead of having e.g. a single view with conditionally rendered content. And that you already know how exactly the view should behave when it's actually being requested idempotently (i.e. via a bookmark, shared link, by a searchbot, etc). If not, then I strongly recommend to carefully read the answer on this question: How to navigate in JSF? How to make URL reflect current page (and not previous one).
Update: in case you're not using OmniFaces, use respectively the following:
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("car");

Pass an object between #ViewScoped beans without using GET params

I have a browse.xhtml where I browse a list of cars and I want to view the details of the car in details.xhtml when a "View more" button is pressed. Their backing beans are #ViewScoped and are called BrowseBean and DetailsBean, respectively.
Now, I wouldn't like the user/client to see the car ID in the URL, so I would like to avoid using GET params, as presented here and here.
Is there any way to achieve this? I'm using Mojarra 2.2.8 with PrimeFaces 5 and OmniFaces 1.8.1.
Depends on whether you're sending a redirect or merely navigating.
If you're sending a redirect, then put it in the flash scope:
Faces.setFlashAttribute("car", car);
This is available in the #PostConstruct of the next bean as:
Car car = Faces.getFlashAttribute("car");
Or, if you're merely navigating, then put it in the request scope:
Faces.setRequestAttribute("car", car);
This is available in the #PostConstruct of the next bean as:
Car car = Faces.getRequestAttribute("car");
See also:
Injecting one view scoped bean in another view scoped bean causes it to be recreated
How to pass objects from one page to another page in JSF without writing a converter
Note that I assume that you're very well aware about the design choice of having two entirely separate views which cannot exist (be idempotent) without the other view, instead of having e.g. a single view with conditionally rendered content. And that you already know how exactly the view should behave when it's actually being requested idempotently (i.e. via a bookmark, shared link, by a searchbot, etc). If not, then I strongly recommend to carefully read the answer on this question: How to navigate in JSF? How to make URL reflect current page (and not previous one).
Update: in case you're not using OmniFaces, use respectively the following:
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("car");

JSF: Bookmarkability with ViewScoped

I am trying to make my app "Bookmarkable", and i am using view parameters to achieve it.
And i think i still do not get the right way to do it right in JSF, even after reading this, and many others.
My problem is that the get parameters get lost after any non-ajax postback, i mean, the parameter value is still set in the bean and the app works correctly, but it gets removed from the URL making the URL invalid.
For instance, having an URL like http://company.com/users?id=4, as soon as that page executes a non-ajax postback (for uploading data, for instance) the URL becomes just http://company.com/users. The app continues to work correctly, but the link is not any more "Bookmarkable".
Is there any way to prevent the non-ajax postbacks removing the viewParams from the URL?
My use case is to be able to bookmark a page to EDIT an object, and there i need to be able to upload data (if not i would not use non-ajax postbacks). I know i would not need any postback if i would want to bookmark the page to only VIEW the data of the object, but that is not my case.
I could also do a redirect to the same page with the same params, and let the app to recreate the view scoped bean, but then i really do not see any benefit over request scoped beans...
Any suggestion is very appreciated.
This behaviour is "by design". The <h:form> generates a HTML <form> element with an action URL without any view parameters. The synchronous POST request just submits to exactly that URL which thus get reflected as-is in browser's address bar. If you intend to keep the view parameters in the URL, while using ajax is not an option, then you basically need to create a custom ViewHandler which has the getActionURL() overridden to include the view parameters. This method is used by <h:form> to generate the action URL.
public String getActionURL(FacesContext context, String viewId) {
String originalActionURL = super.getActionURL(context, viewId);
String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
return newActionURL;
}
Or, as you're based on the comments already using OmniFaces, you could also use its <o:form> component which basically extends the <h:form> with the includeViewParams attribute which works much like the same as in <h:link> and <h:button>.
<o:form includeViewParams="true">
...
</o:form>
This way all <f:viewParam> values will end up in the form action URL.
See also:
Handling view parameters in JSF after post

JSF: bean scope; session vs request

I have a managed bean called UserSearchHandler, it has a doSearch method that populates UserSearchHandler.searchResults which are displayed in a table on the userSearch.xhtml page.
I have another managed bean called UserHandler, it has a showUser method and so on.
In the search results table, the user name is a link that, when clicked, is supposed to show user details on a userView.xhtml page. The table and link looks like this:
<p:dataTable var="user" value="#{userSearchHandler.searchResults" >
// ... and so on ... then
<h:commandLink value="#{user.firstName}" action="#{userHandler.showUser}">
<f:setPropertyActionListener target="#{userHandler.userIdToShow}" value="#{profile.id}"/>
</h:commandLink>
Everything works fine when the managed beans are set to session scope.
However, when I change the scope on the beans to request, the search works and the table gets populated, but when I click on the name link nothing happens. I put a break point on the userHandler.showUser method and it never gets hit when the userSearchHandler is set to "request" scope.
Can anyone help explain why this is, or what I'm doing wrong?
That's because the #{userSearchHandler.searchResults} is empty during the new request and therefore JSF is unable to locate the associated row where the commandlink is been invoked in order invoke the action (and to pass/set properties if any).
You need to ensure that the same #{userSearchHandler.searchResults} is precreated during bean's construction/initialization. If it's to be created based on a specific set of parameters, then you've to pass them along with the form as well.
That's exactly the reason why solutions like Tomahawk's <t:saveState /> and new JSF 2.0 view scope exist.
See also:
What are the main disadvantages of JSF 2.0?
I have a couple of ideas. If you're using a in your navigation you can try taking that out. Doing so would mean the browser will not make a new HTTP request when it renders the second window. It is the new HTTP request which clears the request scoped beans by. If that is not an option, you may be able to pass a parameter in your link such as a record id, which could allow you to pull data from your data source matching that id.

Keeping current JSF pagination state when going to another page and coming back to the page that contains the paginator

I'm using the Tomahawk t:dataScroller for pagination. It is working really well. There is only one issue that I'll try to explain:
Page A contains the t:dataTable, which is paginated with the t:dataScroller. There are links in the dataTable that can redirect me to another page, say page B. When I go back from B to A, the state of the pagination is restarted.
What I mean is that, if, in Page A, I'm at the 5th page, and then move to page B, when I go back to A, I'll be at the 1st page on A.
Does anyone have gone through this? Does anybody have any idea?
You can take control of 'first' property of the datatable. What you need to this,
Declare a public/protected variable in your session bean,
#ManagedBean
#SessionScoped
public class DataTableController implements java.io.Serializable {
protected int first;
// getters and setters...
Bind it with the 'first' property of datatable
<p:dataTable id="results-table" var="result"
...
first="#{dataTableController.first}"
While navigating between the pages, store the 'first' record value using something like this,
public void onPageChange(PageEvent event) {
this.setFirst(((DataTable) event.getSource()).getFirst());
}
For more details, follow the link.
http://forum.primefaces.org/viewtopic.php?f=3&t=25399#p80324
BTW Thanks for the comments

Resources