How to display data table in JSF page with database data - java

I have a table in a database which is used for storing application configuration data.
This is the table structure - it's very simple example:
SessionTTL MaxActiveUsers
---------------------- ----------------------
30 787
I want to display the table data in this way:
<table border="1">
<tr>
<td>SessionTTL</td>
<td>30</td>
</tr>
<tr>
<td>MaxActiveUsers</td>
<td>787</td>
</tr>
<tr>
<td>option</td>
<td>value</td>
</tr>
<tr>
<td>option</td>
<td>value</td>
</tr>
</table>
I tried to display the data using this JSF code and this Java code, but the result was not what I want:
<h:dataTable id="books"
columnClasses="list-column-center,
list-column-right, list-column-center,
list-column-right" headerClass="list-header"
rowClasses="list-row" styleClass="list-
background" value="#{DashboardController.getDashboardList()}" var="store">
<h:column>
<h:outputText value="Session Timeout"/>
<h:outputText value="Maximum Logged Users"/>
</h:column>
<h:column>
<h:outputText value="#{store.sessionTTL} minutes"/>
<h:outputText value="#{store.maxActiveUsers}"/>
</h:column>
</h:dataTable>
public List<Dashboard> getDashboardList()throws SQLException{
List<Dashboard> list = new ArrayList<Dashboard>();
if(ds == null) {
throw new SQLException("Can't get data source");
}
Connection conn = ds.getConnection();
if(conn == null) {
throw new SQLException("Can't get database connection");
}
PreparedStatement ps = conn.prepareStatement("SELECT * from GLOBALSETTINGS");
try{
//get data from database
ResultSet result = ps.executeQuery();
while (result.next()){
Dashboard cust = new Dashboard();
cust.setSessionTTL(result.getString("SessionTTL"));
cust.setMaxActiveUsers(result.getString("MaxActiveUsers"));
list.add(cust);
}
}
catch(Exception e1){
// Log the exception.
}
finally{
try{
ps.close();
conn.close();
}
catch(Exception e2){
// Log the exception.
}
}
return list;
}
How I can display the data the way I want?
Best wishes

You must not assign the get method with the parenthesis. You must use a List attribute from your managed bean.
value="#{DashboardController.getDashboardList()}" //WRONG!
Your managed bean should look like this:
public class DashboardController {
private List<Dashboard> lstDashboard;
public DashboardController() {
try {
lstDashboard = getDashboardList();
} catch (Exception e) {
//log the exception or something else...
}
}
//getter and setter...
public List<Dashboard> getLstDashboard() {
return this.lstDashboard;
}
public void setLstDashboard(List<Dashboard> lstDashboard) {
this.lstDashboard = lstDashboard;
}
//your other methods here...
}
Second, you set the design of every column in your table, not the design of the rows. You're setting 1 column with 2 values and another column with the real output.
Fixing your datatable code:
<h:dataTable id="books"
columnClasses="list-column-center,
list-column-right, list-column-center,
list-column-right" headerClass="list-header"
rowClasses="list-row"
styleClass="list-background"
value="#{DashboardController.lstDashboard}"
var="store">
<h:column>
<f:facet name="header">
<h:outputText value="Session Timeout" />
</f:facet>
<h:outputText value="#{store.sessionTTL} minutes"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="MaxActiveUsers" />
</f:facet>
<h:outputText value="#{store.maxActiveUsers}"/>
</h:column>
</h:dataTable>
#BalusC is the StackOverflow JSF expert. He has a very nice example about using JSF DataTable in his blog entry.

Besides some design flaws that I already remarked in your previous questions, at least you have to use the correct value attribute for your dataTable.
Replace:
value="#{DashboardController.getDashboardList()}"
with:
value="#{DashboardController.dashboardList}"
The "get" prefix will automatically be added. The brackets can be omitted.

getDataList() you can write some normal getter method. you write some of the method dataList() and implement your business code in that method.
Method declaration in the xhtml or jsp file in dataTable in jsf.
<h:dataTable id="books" type="submit" value="#{DashboardController.dataList}" var="dashbord">
<h: column name="ID">
<f:facet name="header">
<h:outputText value="#{dashbord.id}"/>
</f:facet>
</h:column>
...your another columns...
</h:dataTable>

Related

How do I show the user a list of movies, let him select a movie and save the movie in a table?i [duplicate]

This question already has answers here:
What is a stack trace, and how can I use it to debug my application errors?
(7 answers)
JSF Controller, Service and DAO
(2 answers)
Closed 2 years ago.
I have small web application where the user should book movies. I created JSF pages and this way I display a list of movies available in the database:
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{bundleMovie.ListMovieTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:outputText escape="false" value="#{bundleMovie.ListMovieEmpty}" rendered="#{movieController.items.rowCount == 0}"/>
<h:panelGroup rendered="#{movieController.items.rowCount > 0}">
<h:outputText value="#{movieController.pagination.pageFirstItem + 1}..#{movieController.pagination.pageLastItem + 1}/#{movieController.pagination.itemsCount}"/>
<h:commandLink action="#{movieController.previous}" value="#{bundleMovie.Previous} #{movieController.pagination.pageSize}" rendered="#{movieController.pagination.hasPreviousPage}"/>
<h:commandLink action="#{movieController.next}" value="#{bundleMovie.Next} #{movieController.pagination.pageSize}" rendered="#{movieController.pagination.hasNextPage}"/>
<h:dataTable value="#{movieController.items}" var="item" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieId}"/>
</f:facet>
<h:outputText value="#{item.movieId}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieName}"/>
</f:facet>
<h:outputText value="#{item.movieName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieGenre}"/>
</f:facet>
<h:outputText value="#{item.movieGenre}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieRating}"/>
</f:facet>
<h:outputText value="#{item.movieRating}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundleMovie.ListMovieTitle_movieDate}"/>
</f:facet>
<h:outputText value="#{item.movieDate}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{movieController.bookAMovie(movie)}" value="Book" />
</h:column>
</h:dataTable>
</h:panelGroup>
<br />
<h:link outcome="/faces/adminIndex.jsp" value="Return to home page"/>
<br />
<br />
</h:form>
</ui:define>
</ui:composition>
As you can see, method <h:commandLink action="#{movieController.bookAMovie(movie)}" value="Book" /> should save the user selection in the new table, that table is bookedmovie while the data from the table is displayed to the user movie.
Method is:
public int bookAMovie(Movie movie) throws ClassNotFoundException {
String INSERT_USERS_SQL = "INSERT INTO bookedmovie"
+ " (bookedmoviename, bookedmoviegenre, bookedmovierating) VALUES "
+ " (?, ?, ?);";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/cs230projekat?useSSL=false", "root", "");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setString(1, movie.getMovieName());
preparedStatement.setString(2, movie.getMovieGenre());
preparedStatement.setDouble(3, movie.getMovieRating());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
} catch (SQLException e) {
// process sql exception
printSQLException(e);
}
return result;
}
I dont know how to fix this. It doesn't have to be this way, if anyone can help in any way, it suits me. Only that the user is shown movies from the database, that the user can select one movie and that his selection is stored in a new table.
Regarding Java code, below code is working fine.
I am able to run it.
Just make sure, you had added appropriate library of MySQL in your project also Make sure UserName/Password should be correct.Right now you had provided empty password.
As you didn't provided any error stack. I can't able to direct comment on that.
class Sample3 {
public static void main(String[] args) throws ClassNotFoundException {
bookAMovie(Movie.builder().movieGenre("Comic").movieRating(8).movieName("Movie1").build());
}
public static int bookAMovie(Movie movie) throws ClassNotFoundException {
String INSERT_USERS_SQL = "INSERT INTO bookedmovie"
+ " (bookedmoviename, bookedmoviegenre, bookedmovierating) VALUES "
+ " (?, ?, ?);";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?useSSL=false", "root", "PASSWORD");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setString(1, movie.getMovieName());
preparedStatement.setString(2, movie.getMovieGenre());
preparedStatement.setDouble(3, movie.getMovieRating());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("SELECT * FROM sample.bookedmovie");
List<Map<String, String>> mapList = getList(resultSet);
System.out.println(mapList);
} catch (SQLException e) {
// process sql exception
e.printStackTrace();
}
return result;
}
public static List<Map<String, String>> getList(ResultSet resultSet) throws SQLException {
List<Map<String, String>> mapList = new ArrayList<>();
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnNumber = resultSetMetaData.getColumnCount();
while (resultSet.next()) {
Map<String, String> map = new HashMap<>();
int count = 1;
while (count <= columnNumber) {
String columnName = resultSetMetaData.getColumnName(count);
map.put(columnName, resultSet.getString(columnName));
count++;
}
mapList.add(map);
}
return mapList;
}
}
#Data
#Builder
class Movie {
public String movieName;
public String movieGenre;
public double movieRating;
}
Here i had attached success screenshot from Java run and same record has been inserted in MySQL as well.enter image description here
MySQL

JSF <h:inputText> / <h:outputText> not rendering according to boolean value

I have a <h:dataTable> that is populated from an Entity class and displays different products. I want to be able to click a <h:commandLink> and edit row that the link belongs to. I have structured it mostly the same way as this nice example and article at mkyong.
The table (with some columns excluded):
<h:form>
<h:dataTable id="gnomeTable" value="#{gnome.productList}"
var="item"
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="List of available gnomes for sale" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="GnomeID" />
</f:facet>
<h:outputText value="#{item.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.name}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Available"/>
</f:facet>
<h:outputText value="#{item.available}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.available}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{gnome.editAction(item)}" rendered="#{not item.editable}" />
</h:column>
</h:dataTable>
<h:commandButton value="Save Changes" action="#{gnome.saveAction}" />
</h:form>
The Bean methods:
public String saveAction() {
for (Gnome g : productList) {
g.setEditable(false);
}
return null;
}
public String editAction(Gnome gnome) {
gnome.setEditable(true);
return null;
}
The property boolean editable in the entity class is annotated as #Transient since it's not a part of the persistant data and I don't want the entity manager to touch it:
#Transient
private boolean editable;
I thought this would result in the boolean variable being set to true when the Edit-button is clicked, the row re-renders with the fields now as <h:inputText>, but nothing happens. I have debugged it and made sure that the variable is set to true, which it is.
I also found this SO question that I thought perhaps could be something similar to the problem I am experiencing. The difference though is that a refresh of the page doesn't change anything.
What am I missing?
Edit 1:
In the first version of this question I had by mistake pasted the wrong code. The one that is included now is my current code, that in theory should work but does not.
Edit 2:
Initialization of productList, where Gnome is the entity class.
private List<Gnome> productList = new ArrayList<>();
public List<Gnome> getProductList() {
productList = gnomeFacade.findAll();
return productList;
}
public void setProductList(List<Gnome> productList) {
this.productList = productList;
}
After testing your example, the only possible error is that you are using a RequestScoped bean. In order to make it work, you need at least ViewScoped or SessionScoped. Ortherwise, the productList changed content is lost at every requests (button action).
According to the edit, the second mistake is how data is took. You need to load your data somewhere else than getter like this :
#PostConstruct
public void init()
{
productList = gnomeFacade.findAll();
}
public List<Gnome> getProductList()
{
return productList;
}
Ortherwise, at every actions your list is reset.

Richfaces 3 datatable sorting not working

I've been googling this for 2 days now and trying various attempts that i've seen posted on the web, but nothing seems to be working for me.
I'm trying to get a richfaces 3 datatable to have sorted columns and when i click the column header, nothing actually gets sorted.
Anyone have any idea what i'm missing? Do i need to implement an attribute on my backing bean or something?
<rich:extendedDataTable id="resultsTable" value="#{tableBacking.results}" var="results" rowKeyVar="row">
<rich:column>
<f:facet name="header">
<h:outputText value="Row Number" />
</f:facet>
</rich:column>
<rich:columns value="#{tableBacking.columns == null ? '' : tableBacking.columns}"
var="columns" index="ind" id="column#{ind}"
sortBy="#{results[ind].data}" rendered="#{tableBacking.columns != null}">
<f:facet name="header">
<h:outputText value="#{columns.columnDescription}" />
</f:facet>
<h:outputText value="#{results[ind].data}" />
</rich:columns>
</rich:extendedDataTable>
TableLookupBacking bean
public class TableLookupBacking{
private List<List<TableData>> results = null;
private List<TableData> columns = new ArrayList<TableData>();
public void search() {
getData("");
}
private void getData(String whereClause) {
try {
DataDao dd = new DataDao();
results = dd.getData(WebDataViewerConstants.SCHEMA_NAME, selectedTable, whereClause);
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unable to retrieve data with selected search criteria in getData."));
}
}
// columns get set in another method that is triggered off something else the user does
// Getters and Setters
}
I finally figured it out. All i needed to do was to add sortOrder="#{tableBacking.sortOrder[columns]}" to my rich:columns tag and then in my backer just add the following:
private Map<String, Object> sortOrder = new HashMap<String, Object>();
// setter and getter

get row from rich:datatable binding table

I am using java 6 jsf 1.2 and richfaces 3.3.3
When I call the function getRowData on the Binded UIDataTable
public void priorityChanged(ValueChangeEvent event) {
Task currentTask = (Task) table.getRowData();
with
<h:selectOneMenu id="id182_#{rkv}" value="#{dataItem.priority}"
valueChangeListener="#{customerAdminHandler.priorityChanged}"
onchange="submit()">
<f:selectItems value="#{customerAdminHandler.priorityTypes}" />
</h:selectOneMenu>
i get an exception on the table.getRowData();
java.lang.IllegalArgumentException
at javax.faces.model.ListDataModel.getRowData(ListDataModel.java:150)
at org.ajax4jsf.model.SequenceDataModel.getRowData(SequenceDataModel.java:147)
at org.ajax4jsf.component.UIDataAdaptorBase.getRowData(UIDataAdaptorBase.java:257)
I bypassed the problem by using
<f:setPropertyActionListener value="#{dataItem}"
target="#{customerProductsHandler.currentApp}" />
instead of a binding table.
the same code worked for me on a clean environment so i guess there is some sort of jar problem.
anyway , for future reference I found the following information usefull for using a binding table
Richfaces 3.3 uses:
org.richfaces.component.html.HtmlDataTable
Richfaces 4 uses:
org.richfaces.component.UIDataTable
jsf1.2 uses:
javax.faces.component.html.HtmlDataTable;
jsf 2 uses:
import javax.faces.model.DataModel;
Have you binded your rich:dataTable to a component attribute of your managed bean? Plus, the type of the attribute must be org.richfaces.component.html.HtmlDataTable, at least this is how we achieved to select one row of the datatable (using the example code of #BalusC here).
The jsp code:
<script type="text/javascript">
function dataTableSelectOneRadio(radio) {
var id = radio.name.substring(radio.name.lastIndexOf(':'));
var el = radio.form.elements;
for (var i = 0; i < el.length; i++) {
if(el[i].name != undefined) {
if (el[i].name.substring(el[i].name.lastIndexOf(':')) == id) {
el[i].checked = false;
}
}
}
radio.checked = true;
}
</script>
<!-- some html/jsp code -->
<rich:dataTable id="dtDocCartera" style="width:100%"
binding="#{busquedaDocCartera.hdtCredito}"
value="#{busquedaDocCartera.lstCredito}" var="credito" rows="15">
<rich:column>
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<h:selectOneRadio onclick="dataTableSelectOneRadio(this)"
valueChangeListener="#{busquedaDocCartera.setSelectedItem}">
<f:selectItem itemValue="null"/>
</h:selectOneRadio>
</rich:column>
<rich:column style="text-align:center">
<f:facet name="header">
<h:outputText value="Some Data" />
</f:facet>
<h:outputText value="#{credito.data}" />
</rich:column>
</rich:dataTable>
And this is our managed bean:
#KeepAlive(ajaxOnly=false)
public class PBusquedaDocCartera {
private HtmlDataTable hdtCredito;
private List<ECredito> lstCredito;
//This will be the selected data
private ECredito credito;
//getters and setters for attributes...
public void setSelectedItem(ValueChangeEvent event) {
try {
credito = (ECredito)hdtCredito.getRowData();
} catch (Exception objEx) {
//logging errors...
}
}
}

h:dataTable has no value

HI,
Have used JSF h:data Table - the jsf datatable is coming empty, my sp is returning values hence getList returns values but only headers are seen in the browser, table values are not seen in the browser.
Following is my JSP
<h:panelGrid>
<f:facet name="header">
<h:outputText value="Employee Details" />
</f:facet>
<h:dataTable value="#{dataTableBean.list}" var="loc"
bgcolor="#F1F1F1" border="10" cellpadding="5" cellspacing="3"
first="0" rows="5" width="50%">
<h:column>
<f:facet name="header">
<h:outputText value="Sponsor ID" />
</f:facet>
<h:outputText value="#{loc.sponsorID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Sponsor Name" />
</f:facet>
<h:outputText value="#{loc.sponsorName}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Distributor ID" />
</f:facet>
<h:outputText value="#{loc.distributorID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Distributor Name" />
</f:facet>
<h:outputText value="#{loc.distributorName}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:form>
MY Bean
public class DataTableBean {
private List<BillTransPay> list;
public List<BillTransPay> getList() {
String SP_BILLPAY = "{call sp_aw_BillTransPay(?,?,?,?,?,?,?)}";
Connection con = null;
ResultSet rs = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = java.sql.DriverManager
.getConnection(conString);
CallableStatement cbls = con
.prepareCall("{call sp_aw_BillTransPay(?,?,?,?,?,?,?)}");
cbls.setString(1, "csf");
cbls.setString(2, "20100101");
cbls.setString(3, "20100301");
cbls.setString(4, "B");
cbls.setString(5, "01CS");
cbls.setString(6, "ALL");
cbls.setInt(7, 14000);
rs = cbls.executeQuery();
list = new ArrayList<BillTransPay>();
while (rs.next()) {
BillTransPay btp = new BillTransPay();
btp.setSponsorID(rs.getString("SponsorCode"));
btp.setSponsorName(rs.getString("SponsorName"));
btp.setDistributorID(rs.getString("DistID"));
btp.setDistributorName(rs.getString("DistName"));
list.add(btp);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
public void setList(List<BillTransPay> list) {
this.list = list;
}
}
Faces-Config.xml
**<managed-bean>
<managed-bean-name>dataTableBean</managed-bean-name>
<managed-bean-class>
com.SQLProcess.dto.DataTableBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>**
Just run a debugger or add a System.out.println(list); right before return list; to see if the method get called and the list really contains items.
Said that, this expensive DB job should really not be done in a getter. It can be called multiple times during a request. You don't want to unnecessarily hit/stress your DB. Move the DB job into the bean's constructor. Also, you're leaking DB resources by not explicitly closing the Connection, Statement and ResultSet. You need to close them in finally block of the same try as where you have acquired them.

Categories