I want to place a table on my page. I have two tables in my database for example users and locations. Every location has more than one user. I want to list these locations and show the users who live in these locations.
Los Angeles
John Locke
Dr. Jack
Mr. Eco
Like the below image, could someone do this in JSF?
Thanks.
You can use RichFaces to do such thing:
<h:form>
<rich:dataList var="city" value="#{myBean.allCity}">
<h:outputText value="#{city.name}" ></h:outputText>
<rich:dataList var="user" value="#{city.users}">
<h:outputText value="#{user.name}" ></h:outputText>
</rich:dataList>
</rich:dataList>
</h:form>
Where allCity - list of the City, and every City has list of the user inside.
See http://livedemo.exadel.com/richfaces-demo/richfaces/dataLists.jsf?c=dataList&tab=usage for example.
Backing bean:
myBean:
public class MyBean(){
private ArrayList<City> allCity= new ArrayList<City>();
#PostConstruct
public void init(){
//fill Array list
}
public ArrayList<City> getAllCity() {
return allCity;
}
}
City:
public class City{
private ArrayList<User> users= new ArrayList<User>();
public City( ArrayList<User> users){
this.users = users;
// you can get data from database in myBean, and pass it hear with cinstructor;
}
public ArrayList<User> getUsers() {
return allCity;
}
}
User
public class User{
private String name;
//constructor and others fields;
public String getName(){
return name;
}
}
Only MyBean you register as backing-bean. I show you only base structure of class, how you fill it with data is you choice.
Related
I'm new with JSF / Java and relational DB queries.
I'm trying to Display data from two tables in one datatable.
I have two tables tblUser and tblCity.
For These tables I've got two models Users and City.
Also got a UserDAO and a UserController.
I'd like to know how to select user data from tblUser and select City data from tblCity and Display them on my view. With MVC style.
Model:
public class User{
private Integer user_id;
private String user_name;
private Integer City_id;
//getter and setter
...
}
public class City{
private Integer city_id;
private String city_name;
//getter and setter
...
}
My Controller
#ManagedBean
#SessionScoped
public List<User> showUser(){
List<User> users = new ArrayList<>();
users= userDAO.showUserList();
return users;
}
My DAO
#ManagedBean
#RequestScoped
public class userDAO{
/**
* Creates a new instance of patientDAO
*/
private final connectToDB con = new connectToDB();
public userDAO() {
}
public List<User> showUserList() {
Connection dbConnection = null;
dbConnection = con.getDBConnection();
PreparedStatement pstmt = dbConnection
.prepareStatement("select a.user_id, a.user_name, b.city_name"
+ " from users a, cities b WHERE a.city_id = b.city_id");
ResultSet rs = pstmt.executeQuery();
List<User> users = new ArrayList<>();
List<City> cities = new ArrayList<>();
while (rs.next()) {
User user = new User();
City city = new City();
user.setUser_Id(rs.getInt("user_id"));
user.setUser_Id(rs.getString("user_name"));
city.setCity_Name(rs.getInt("city_name"));
users.add(user);
cities.add(city);
}
// close resources
rs.close();
pstmt.close();
dbConnection.close();
return users;
}
}
My View
<p:dataTable id="userDT" var="user" value="#{userController.showUserList()}">
<p:column width="200" headerText="User Name">
<h:outputText value="#{user.user_name}" />
</p:column>
<p:column width="200" headerText="City Name">
<h:outputText value="#{...}" />
</p:column>
</p:dataTable>
Supposing that one User has one City, you can add a city attribute to the User class:
public class User{
...
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
...
}
In your userDAO, at the end of the while loop of the showUserList() method, put the city in the user object:
...
while (rs.next()) {
User user = new User();
City city = new City();
user.setUser_Id(rs.getInt("user_id"));
user.setUser_Id(rs.getString("user_name"));
city.setCity_Name(rs.getInt("city_name"));
user.setCity(city);
users.add(user);
}
...
The list of cities in the showUserList() method is not used outside the method, you can delete it.
And finally, edit the view like this:
...
<p:column width="200" headerText="City Name">
<h:outputText value="#{user.city.city_name}" />
</p:column>
...
sorry if this is a poor question but this one feature have been driving me mad for days so i thought id post it here to see if you guys can help me
basically all i want to do from a jsf page have the user search a user and for me to return all the details
<h:form id="searchForm">
<h:outputLabel value="Search: " style="font-weight:bold" />
<h:inputText id="search" value="#{userdetailsController.search}" />
<h:commandButton value="Search" action="index"/>
</h:form>
that is the jsf page, working fine
it calls my userdetailsController class
#Named("userdetailsController")
#SessionScoped
public class UserdetailsController implements Serializable {
private Userdetails current;
private DataModel items = null;
#EJB
private Richard.beans.UserdetailsFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
private String search;
public String getSearch() {
System.out.println("inGetSearch");
return search;
}
public void setSearch(String search) {
this.search = search;
}
......
a contactsService class
#Stateless
public class ContactsService {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
#EJB
private UserdetailsFacade cf;
public List<Userdetails> searchByString(String string) {
return cf.searchByString(string);
}
public List<Userdetails> getAllPersons() {
return cf.findAll();
}
}
an AbstractFacade class
/* trying out a search function */
public List<T> searchByString(String string) {
System.out.println("in SearchByString");
return getEntityManager().createNamedQuery("Userdetails.findByUsername").setParameter("string", "%" + string + "%").getResultList();
}
and the Userdetails class with the query i am trying to search
#NamedQuery(name = "Userdetails.findByUsername", query = "SELECT u FROM Userdetails u WHERE u.username = :username")})
currently only the getters and settings are working in Getsearch
how can i make this work as i have spent days on this feature and are still no closer, sorry this is my first time at this
thanks guys
EDIT
would adding
public List<Userdetails> getAllPersons() {
if (search == null) {
return cs.getAllPersons();
}
return cs.searchByString(search);
}
in the UserdetailsController be enough ?
You're not invoking any action here:
<h:commandButton value="Search" action="index"/>
So it's indeed logical that it isn't "doing anything".
You need to invoke a managed bean action which in turn executes the desired code to obtain the desired data from the DB and assign to a property:
<h:commandButton value="Search" action="#{userdetailsController.submit}" />
with inside UserdetailsController:
private String search;
private List<UserDetail> items; // No need for DataModel here.
#EJB
private UserdetailsFacade ejbFacade;
public String submit() {
items = ejbFacade.searchByString(search);
return "index";
}
Your whole ContactsService seems useless by the way.
As per your attempt in the getter method in the update of your question, please don't do that. You should never call the DB in a getter method for the reasons mentioned in Why JSF calls getters multiple times
I would like to know if it possible to push a value from inside a <ui:repeat> to a map, a set or a list?
I would like to pass the value of the <h:inputtext> to a set.
Code:
<ui:repeat var="_par" value="#{cmsFilterParameterHandler.normaleSuchParameter()}">
<p:outputLabel value="#{_par.bezeichnung}" />
<p:spacer width="5px" />
<p:inputText id="me" value="#{??? push me to a set ???}"/>
<br /><br />
</ui:repeat>
With a Set, it is not possible as it doesn't allow referencing items by index or key. It's however possible with a List and a Map by just specifying the list index and map key in the input value.
With a List:
private List<String> list; // +getter (no setter necessary)
#PostConstruct
public void init() {
list = createAndFillItSomehow();
}
<ui:repeat value="#{bean.list}" varStatus="loop">
<h:inputText value="#{bean.list[loop.index]}" />
</ui:repeat>
With a Map (only if your environment supports EL 2.2 or JBoss EL):
private Map<String, String> map; // +getter (no setter necessary)
#PostConstruct
public void init() {
map = createAndFillItSomehow();
}
<ui:repeat value="#{bean.map.entrySet().toArray()}" var="entry">
<h:inputText value="#{bean.map[entry.key]}" />
</ui:repeat>
Noted should be that the canonical approach is to use a List of fullworthy javabeans. Let's assume a Javabean class named Par with properties id and value which maps exactly to a par table in DB with columns id and value:
private List<Par> pars; // +getter (no setter necessary)
#PostConstruct
public void init() {
pars = createAndFillItSomehow();
}
<ui:repeat value="#{bean.pars}" var="par">
<h:inputText value="#{par.value}" />
</ui:repeat>
Either way, it works as good when using <p:inputText>, it's in no way related to PrimeFaces, it's in the context of this question merely a jQuery based JSF UI component library. Just replace h: by p: to turn it on.
I'm not sure, if I understood your requirements correctly.
I suppose the following: You need a List of Strings in some backend and an ui:repeat tag to iterate over those strings with input-fields to edit them. Maybe there are some syntax-issues, but my idea should be clear:
public class Backend {
private List<String> myStrings;
public MyStringWrapper getMyStringWrapper(int index) {
return new MyStringWrapper(index);
}
public class MyStringWrapper {
private final int index;
public MyStringWrapper(int index) { this.index = index; }
public String getContent() { return myStrings.get(index); }
public void setContent(String newContent) { myStrings.add(index, newContent); }
}
}
In the frontend you use as follows:
<ui:repeat var="_index" value="#{backend.getIndexSequence()}">
<p:inputText value="#{backend.getMyStringWrapper(_index).content}"/>
</ui:repeat>
Of course, you have to provide a getIndexSequence-method which produces a list of ints ranging from 0 to the size of the strings.
Do you mean like this?
<p:inputText id="me" value="#{_par.input}"/>
in BackBean:
public class Par implements Serializable {
private String inputText;
private String bezeichnung;
public Par()
{
}
public void setInput(String input)
{
this.inputText = input;
}
public String getInput()
{
return this.inputText
}
public void setBezeichnung(String bezeichnung)
{
this.bezeichnung = bezeichnung;
}
public String getBezeichnung()
{
return this.bezeichnung
}
}
I do know that similar problem was announced here few times but I spent a lot of time and still have no idea why that code doesn't work :/
This is my JSF page:
<h:form>
<h:selectOneMenu value="#{productBean.productName}">
<f:selectItems value="#{productBean.products}" var="c" itemValue="#{c.name}"/>
</h:selectOneMenu>
</h:form>
This is my productBean:
public class ProductBean extends Connector
{
private List<Product> products;
private Product product;
private String productName;
//setters and getters
public List<Product> getProducts() throws SQLException
{
resultSet = statement.executeQuery("SELECT * FROM dbo.products");
products = new ArrayList<Product>();
while(resultSet.next())
{
product = new Product();
product.setId_product(resultSet.getInt("id_product"));
product.setName(resultSet.getString("name"));
product.setCategory(resultSet.getInt("category_id"));
product.setIs_available(resultSet.getInt("is_available"));
products.add(product);
}
return products;
}
}
And finally product class:
public class Product
{
private int id_product;
private String name;
private int price;
private int category;
private int is_available;
/setters and getters
}
My goal is to have a menu list with products names. All i got in the expanded list are references.
I also tried to declare everything in the bean class and make ArrayList instead of ArrayList but i think it's not nice. It did't work anyway.
Tell me if I understand it corectly. productBean.productName is some kind of holder. productBean.products is a whole Products list and the c.name means that I want only name from the actual product.
You must also include the itemLabel :
<f:selectItems value="#{productBean.products}" var="c" itemValue="#{c.name}" itemLabel="#{c.name}" />
I'm trying to create a DataTable with Multiple Row Selection but i'm getting an error here's the link of the tutorial http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf :
Here's my xhtml:
<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}"
var="userObj"
selection="#
{projectAdminisrationMB.selectedUsers}"
selectionMode="multiple" rowIndexVar="rowIndex"binding="#{table2}">
<p:column id="column3">
<f:facet name="header">
<h:outputText value=" user "></h:outputText>
</f:facet>
<h:outputText value="#{userObj.name}"/>
/
<h:outputText value="#{userObj.lastName}"></h:outputText>
<h:outputText value="#{userObj.firstName}"></h:outputText>
</p:column>
<f:facet name="footer">
<p:commandButton id="addProjectUser" value=" Add " onclick="dlg1.show()" />
<p:commandButton id="deleteProjectUser" value=" Delete " />
</f:facet>
</p:dataTable>
Managed Bean :
#ManagedBean
#SessionScoped
public class ProjectAdminisrationMB implements Serializable {
private static final long serialVersionUID = 1L;
private String projectName;
private List <User> projectUsersList;
private List<User> projectNoUsersList;
private List<User> selectedUsers;
private String projectAdmin;
public ProjectAdminisrationMB() {
super();
AdministrationProjectFinal administrationProjectFinal =new
AdministrationProjectFinal();
this.projectUsersList=administrationProjectFinal.getUserList();
this.projectNoUsersList=administrationProjectFinal.getNotUserList();
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public List<User> getProjectUsersList() {
return projectUsersList;
}
public void setProjectUsersList(List<User> projectUsersList) {
this.projectUsersList = projectUsersList;
}
public String getProjectAdmin() {
return projectAdmin;
}
public void setProjectAdmin(String projectAdmin) {
this.projectAdmin = projectAdmin;
}
public List<User> getProjectNoUsersList() {
return projectNoUsersList;
}
public void setProjectNoUsersList(List<User> projectNoUsersList) {
this.projectNoUsersList = projectNoUsersList;
}
public List<User> getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(List<User> selectedUsers) {
this.selectedUsers = selectedUsers;
}
}
i'm getting this error:
javax.faces.FacesException: DataModel must implement
org.primefaces.model.SelectableDataModel when selection is enabled.....
just add this attribute rowKey to the datatable tag :
<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}"
var="userObj"
rowKey="#{userObj.name}"selection="#{projectAdminisrationMB.selectedUsers}"
selectionMode="multiple" rowIndexVar="rowIndex"
binding="#{table2}">
You can get this error if you try to add a new item to the underlying list and forget to assign a value to that new item's rowKey.
Alternatively to rowKey you can wrap your data in a custom model which really implements org.primefaces.model.SelectableDataModel. This is helpful if
all of your your classes have the same kind of #Id (e.g. a long) and can implement the same interface (e.g. EjbWithId)
you want to add additional functionalities to your data which are not domain specific and don't belong e.g. User.
The interface may be something like this:
public interface EjbWithId
{
public long getId();
public void setId(long id);
}
Then a generic implementation of SelectableDataModel for all your classes can be used:
public class PrimefacesEjbIdDataModel <T extends EjbWithId>
extends ListDataModel<T> implements SelectableDataModel<T>
{
public PrimefacesEjbIdDataModel(List<T> data)
{
super(data);
}
#Override public T getRowData(String rowKey)
{
List<T> list = (List<T>) getWrappedData();
for(T ejb : list)
{
if(ejb.getId()==(new Integer(rowKey))){return ejb;}
}
return null;
}
#Override public Object getRowKey(T item) {return item.getId();}
}
In your #ManagedBean:
private PrimefacesEjbIdDataModel<User> dmUser; //+getter
dmUser = new PrimefacesEjbIdDataModel<User>(administrationProjectFinal.getUserList());
first check whether you've added
rowKey="#{userObj.id}"
then you need to have the data table List set in filteredValue attribute of your data table in xhtml, instead of value.