Render XHTML Content with parameter carried by URL [duplicate] - jsf

I am trying to pass parameter between two pages.my User.xhtml page has ui:repeat which displays user.I have access to the user Id as well. I want to click on the user and go to their details page. I have userDetails.xhtml which is blank at the moment.
I have a Bean as well.
Currently I am using h:link to navigate one page to another. And it works.
My mission is : Click on the user and get their details.
Please help, I am pretty new in JSF
Thanks

You can try using <f:param>:
<ui:repeat value="#{userBean.users}" var="u">
...
<h:link outcome="userDetails" value="Details">
<f:param name="userID" value="#{u.id}" />
</h:link>
...
</ui:repeat>
then you can get the id like this:
#ManagedBean
#RequestScoped
public class UserDetailsBean {
#ManagedProperty(value = "#{param.userID}")
private String userID;
// Getters and Setters
}

Related

Primefaces commandButton not updating datatable. Is update attribute required

I changed my <h:commandButton> tag to a PrimeFaces <p:commandButton> tag on a search page and my datatable stopped displaying the results. After adding an update attribute things worked again. I'm just trying to understand whether it is how I implemented the overall functionality (viewscope, action vs actionListener, etc) or is the update attribute really required?
<h:form id="search_form">
<p:inputText id="search" value="#{searchBean.searchString}" />
<p:commandButton update="search_form" value="Search" action="#{searchBean.searchByString}" >
</p:commandButton>
<p:dataTable id="output" var="res" value="#{searchBean.results}" emptyMessage="No results found with given criteria">
etc...
#ViewScoped
#ManagedBean
public class SearchBean {
#Inject
private SearchRepository searchRepository;
private List<Results> res;
private String searchString;
public SearchBean() {
}
public String searchByString()
{
this.setRes(searchRepository.searchBySingleString(searchString));
}
One of the differences between h:commandButton and p:commandButton is that the second one performs an ajax request by default, while the first executes a plain POST request.
In an ajax request, you must specify what you want to process when form is sent and what to update when response happens. The p:commandButton updates nothing by default, that's why your table is not being properly filled.
See also:
Prime Faces Command Button vs. Default Command Button
Primefaces commandButton

How to use component binding in JSF right ? (request-scoped component in session scoped bean)

Mojara 2.1.21
I've updated my question based on comments. I have two situation where a component is bound to server session bean. (Additional links with information: Binding attribute causes duplicate component ID found in the view and https://stackoverflow.com/a/12512672/2692917)
Version 1:
single.xhtml:
<h:outputText value=... binding="#{mysessionbean.out}" />
java:
#SessionScoped #Named public class Mysessionbean {
UIOutput out;
//getter and setter ....
}
Version 2:
template.xhtml:
<h:outputText value=... binding="#{mysessionbean.out}"
view1.xhtml:
<ui:composition template="template.xhtml" />
view2.xhtml:
<ui:composition template="template.xhtml" />
java:
#SessionScoped #Named public class Mysessionbean {
UIOutput out;
//getter and setter ....
}
Version 1 is ok. (At least I've not encounter any errors so far). But in version 2 the duplicate id error is occured if I navigate from one page to another. Why does it happen ?
Is it safe to use (request-scoped) component (in version 1) with session scoped binding ?
Are there another use cases to consider ?
Edit:
Functional requirement 1:
I want to use Primefaces datatable in a view. I need some info from this datatable. (Such as selected row or row index). So binding the datatable helps me to retrieve this info.
Functional requirement 2:
Components binding in composite components. They will be bound to session scoped bean. (And used mainly on one page, but what if I used it on another page ?
Requirements 3
The situation as in "Version 2". Template with primefaces menu and session scoped binding. For this I've used the EL-Binding.
In JSF 2.x, unless you want to manipulate components programmatically (which is at its own also rather fishy), there is no sensible real world use case to bind components to a backing bean. For sure not if they are further not been used in the backing bean itself, or if it are solely their attributes which are been flattened out.
As to the functional requirement of getting the current row of the data table, there are much better ways listed here, How can I pass selected row to commandLink inside dataTable?, for example if your environment supports EL 2.2:
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:commandLink value="Foo" action="#{bean.foo(item)}" />
The two last requirements are totally unclear. At least, if you're doing something like:
<x:someComponent binding="#{bean.someComponent}" />
with in bean
someComponent.setSomeAttribute(someAttribute);
someComponent.setOtherAttribute(otherAttribute);
then you should instead be doing
<x:someComponent someAttribute="#{bean.someAttribute}" otherAttribute="#{bean.otherAttribute}" />
Or, if you intend to be able to use the component somewhere else in the view like so
<h:inputText ... required="#{not empty param[bean.save.clientId]}" />
...
<h:commandButton binding="#{bean.save}" ... />
and the instance is further nowhere been used in the bean, then just get rid of the unnecessary property altogether:
<h:inputText ... required="#{not empty param[save.clientId]}" />
...
<h:commandButton binding="#{save}" ... />
If there is really, really no way for some unclear reason, then split all request scoped properties of the session scoped bean out into a separate request scoped bean which you in turn bind to form actions. The session scoped one can just be injected as a #ManagedProperty of the request scoped one.
See also:
Binding attribute causes duplicate component ID found in the view
How does the 'binding' attribute work in JSF? When and how should it be used?
We ran into a similar problem and I just want to share our solution:
Problem:
In a view there was a (extended largely customized) datatable.
<x:dataTable binding="#{bean.someSomeDataTable}" />
After navigating to another page and back we wanted the datatable to have the exact same state. Previously we solved that by binding the datatable to to backing bean. This worked fine with JSPs. With Facelets we could not do that (Duplicate ID errors). So we used the binding, but only saved/restored the state of the datatable component.
public HtmlDataTable getSomeDataTable()
{
HtmlDataTable htmlDataTable = new HtmlDataTable();
if (tableState != null)
htmlDataTable.restoreState(FacesContext.getCurrentInstance(), tableState);
return htmlDataTable;
}
public void setSomeDataTable(HtmlDataTable table)
{
tableState = table.saveState(FacesContext.getCurrentInstance());
}

#ViewScoped, f:setPropertyActionListener only works once

I have 2 managedBeans: the first one (RequestScoped) sends a parameter to the second one (ViewScoped) through a h:commandLink. Both managedBeans are in the same page, but I use them in different tabs from a rich:TabPanel:
#ManagedBean
#RequestScoped
public class TheRequestScopedManagedBean {
private String number
...
#ManagedBean
#ViewScoped
public class TheViewScopedManagedBean {
private String number;
...
And here's the view, wich uses a rich:dataTable:
(The action method is only for showing the second tab from a rich:tabPanel).
// ... another dataTable's columns
<rich:column>
<f:facet name="header">Number</f:facet>
<b>
<a4j:commandLink value="#{theRequestScopedManagedBean.number}"
render="someRichPanel" action="#{anotherBean.showSecondTab}" immediate="true">
<f:setPropertyActionListener target="#{theViewScopedManagedBean.number}" value="#{theRequestScopedManagedBean.number}" />
</a4j:commandLink>
</b>
</rich:column>
The problem here is that theViewScopedBean shows the value only the first time, and when I try to pass it again, it shows its default value (null).
I've seen several questions on this website. But I really don't know what to do in this case.
action="#{anotherBean.showSecondTab}" is going to result in a navigation case firing. This will in turn result in the views and request scoped beans being destroyed and recreated (as is the expected behaviour for a view scoped bean).
If you're using EL2.2, you could easily just pass the value directly into a method in the view scoped bean. Let's assume your viewscoped bean has a method takeValue, you can pass the parameter directly into the method as in:
<a4j:commandLink value="#{theRequestScopedManagedBean.number}" render="someRichPanel" action="#{theViewScopedBean.takeValue(theRequestScopedManagedBean.number)}" immediate="true"/>
There are still cleaner ways to transmit data between pages.
Communication in JSF2.0

Creating input fields dynamically in JSF 2.0 and linking it to a backing bean

My requirement is something like this. In a JSF(2.0) page, I have a section called Address. I have added a button which says "Add an Address". When the user clicks the button, new address fields(input text) should be generated dynamically (Line1, Line2, City etc..,). And when I click submit, all the values (Address 1, Address 2 ... Address N) should go to an array list.
So I need to
Dynamically generate UI components on click on a button
Link those UI components to a backing bean (Preferably to a list)
Data tables should not be used for the above
It is very difficult to find proper JSF documentations online, so if anyone can help me out it would be great
Update : The answer posted by noone works good, but I want something more robust, like creating dynamic UI components from the Java Controller (The java bean, using HtmlPanelGrid component). I have been able to create components dynamically using htmlPanelGrid, but I cannot find a way to bind those generated components to the address list in the bean (The one which stores details of all the addresses)
I assume that you have a class Address for the addresses. And a AddressBean with a List to keep the adresses.
The code might look like this (for the most basic scenario I can think of):
<h:form id="addressForm">
<h:commandButton value="Add Address" action="#{addressBean.addAddress()}" immediate="true" execute="#this">
<f:ajax render="addressForm" />
</h:commandButton>
<c:forEach items="#{addressBean.addressList}" var="address">
<h:inputText value="#{address.street}" /><br />
</c:forEach>
<h:commandButton value="Save" action="#{addressBean.persistAddresses}" />
</h:form>
#ManagedBean
#ViewScoped
public class AddressBean {
private List<Address> addressList = new ArrayList<Address>(); // getter+setter
public void addAddress() {
addressList.add(new Address());
}
public void persistAddresses() {
// store the addressList filled with addresses
}
}
public class Address {
private String address; // getter+setter
}
<c:forEach> is taken from the JSTL. It might work with <ui:repeat>, but depending on your actual scenario it might not.

View parameter when navigating to another page

I am using JSF2, and I need to be able to pass a parameter from one JSF page to another via a commandLink.
I am on page funding.xhtml (ViewScoped) and have the following link defined:
<p:commandLink styleClass="toolbar"
action="/application/customerApplicationManagement.jsf">
<p:graphicImage url="/resources/gfx/search.png" />
<h:outputText value="#{msg.menu_searchApplications}" styleClass="toolbarLink" />
</p:commandLink>
I need to pass a string value to the customerApplicationManagement page indicating which page I came from so that after selecting an application, I can return to that page. I have tried several suggestions about how to pass this value including f:param, f:viewParam. I have even tried just adding it directly to the url (?fromPage=funding) etc, but they all seem to work only when the value is passed back to the current page, not a new page I am navigating to.
Can someone show me how this can best be accomplished.
Use <f:param> and <f:viewParam>:
Source page:
<p:commandLink styleClass="toolbar"
action="/application/customerApplicationManagement.jsf">
<p:graphicImage url="/resources/gfx/search.png" />
<h:outputText value="#{msg.menu_searchApplications}" styleClass="toolbarLink" />
<f:param name="fromPage" value="funding.xhtml" />
</p:commandLink>
Destination page (bound):
<f:metadata>
<f:viewParam name="fromPage" value="#{destinationBacking.fromPage}" />
</f:metadata />
<h:link value="Go back!" outcome="#{destinationBacking.fromPage}" />
Destination page (unbound):
<f:metadata>
<f:viewParam name="fromPage" />
</f:metadata />
<h:link value="Go back!" outcome="fromPage" />
Backing bean (only if you want to bind the param):
#ManagedBean
#ViewScoped
public class DestinationBacking{
String fromPage;
public String getFromPage(){
return fromPage;
}
public void setFromPage(String frompage){
fromPage = frompage;
}
}
Your view path will be binded to fromPage property from the destination backing bean and after you can use it to return to the original page.
Also I want to say that this way is a bit 'hackeable' by the end user, I mean, you're passing the original path through pure url. See also other ways to achieve that, as flash scope, which is very useful specially if you're working with #ViewScoped beans.
I don't know the specifics of the methods you tried to achieve your goal and hence we cant tell what was wrong with them, but if we consider your code 'as is' you don't have anything that will pass the string you want.
Not to repeat ourselves, there are plenty of answers here dedicated to using this or that method, so I will give you the best references, in my opinion, of course.
How can I pass a parameter to a commandlink inside a datatable;
ViewParam vs #ManagedProperty;
What can <f:metadata> and <f:viewParam> be used for.
Regarding the usage of back buttons in JSF you could also take a look at my own answer on How to get back to the same page in JSF.
By the way, using POST for page-to-page navigation is considered to be a bad practice. If all you need is to navigate to another page you'd better use plain <h:link> or <h:button> instead.

Resources