H:Datatable - : Building HTML Tables From Collections
H:Datatable - : Building HTML Tables From Collections
h:dataTable
For live training on JSF 2.x, please see courses at htt // t http://courses.coreservlets.com/. l t /
Taught by the author of Core Servlets and JSP, More Servlets and JSP and this tutorial. Available at public JSP, tutorial venues, or customized versions can be held on-site at your organization.
C Courses d developed and t l d d taught b M t H ll ht by Marty Hall Courses developed and taught by coreservlets.com experts (edited by Marty)
JSF, servlets/JSP, Ajax, jQuery, Android development, Java 6 programming, custom mix of topics Ajax courses can concentrate on 1EE Training: http://courses.coreservlets.com/several Customized Java library (jQuery, Prototype/Scriptaculous, Ext-JS, Dojo, etc.) or survey
Servlets, JSP, Hibernate/JPA, EJB3, GWT, jQuery, GWT, RESTful Web Services RESTful Web Services, Android. Spring, JSF 2.0, Java 6, Ajax, SOAP-based and Spring, Hibernate, Contact [email protected] for details Developed and taught by well-known author and developer. At public venues or onsite at your location.
Building HTML from a bean property Using a builtin component like h:dataTable Making your own composite component Looping with ui:repeat Basics: h:dataTable and h:Column Headings H di Style sheets Ajax-enabled Ajax enabled tables Tables with conditional values
U i Using h d T bl h:dataTable
Overview
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Problem
What if the action controller method produces data whose length can change? How do you generate output without resorting to JSP scripting and explicit Java looping?
Solutions
There are a number of alternatives, all of which would work well in some circumstances. The issue is how much control the Web page author needs.
7
This section covers h:dataTable, but other alternatives are covered in other tutorial sections
Bean
Have bean getter method spit out string or HTML based on a collection
h:dataTable
Use a builtin component that builds a table from a collection. f ll ti
M k own component that builds some HTML Make t th t b ild construct (e.g., <ul> list) from a collection
ui:repeat
Do explicit looping in results page
h:dataTable
The tutorial section on ui:repeat compares and contrasts the options with a brief example of each. B Bottom li of the comparison: line f h i h:dataTable is usually best when
You want to produce an HTML table from the collection Each entry in the collection corresponds to a table row in a relatively consistent manner
Other options p
There are separate tutorial sections on ui:repeat and composite components
9
Example Notes
Data
Normally, the data is produced in the action controller.
E.g., you collect a bank customer ID and month in a form, and the button says <h:commandButton action="#{user.findChanges}"/> where findChanges finds the bank account changes (deposits and withdrawals) in the month and puts then into an array or List.
Basics
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Simplest Syntax
Attributes
var, value, border l b d
Nested element
h:column
Example
<h:dataTable var="someVar" value="#{someCollection}" border=""> <h:column>#{someVar.property1}</h:column> <h:column>#{someVar.property2} </h:column> { p p y } </h:dataTable>
13
Programmer (Continued)
/** Formats the salary like "$24,567.89". */ public String getFormattedSalary() { return(String.format("$%,.2f", salary)); } /** Returns a String like "Java, C++, and Lisp". * That is, it puts commas and the word "and" into list. */ public String getLanguageList() { StringBuilder langList = new StringBuilder(); for(int i=0; i<languages.length; i++) { if(i < (languages.length 1)) { (languages length-1)) langList.append(languages[i] + ", "); } else { langList.append("and " + languages[i]); } } return(langList.toString()); }
14
16
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" p //j /j / xmlns:h="http://java.sun.com/jsf/html"> <h:head><title>h:dataTable Basics</title> <link href="./css/styles.css" rel= stylesheet type= text/css /> rel="stylesheet" type="text/css"/> </h:head> <h:body>
This first simple example doesnt use any f: tags, but most real h:dataTable examples use f:facet. So, plan ahead and add this namespace from the p beginning. You probably are already using this namespace for h:form, h:outputText, etc. But even if not, y need , you it for h:dataTable and h:column.
17
18
Results
19
Overview
Problem
Regular content gives a snapshot of a row. So, most content inside h:column is repeated for every row.
Solution
Mark headings with f:facet. Shown for first row only.
<h:dataTable var="someVar" value="#{someCollection}"> <h:column> <f:facet name="header">First Heading</f:facet> { p p y } #{someVar.property1} </h:column> </h:dataTable>
rowClasses, columnClasses
List of CSS style names for each row and column. Will use each name in turn and then repeat. Discussed in upcoming section.
first, rows
First entry in collection to use, total number of rows to show.
id, rendered
22
Same as for all h:elements. Use id for Ajax. Use rendered if you will omit the table in certain situations (e.g., if no rows).
23
Results
24
Style Sheets
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Overview
Problem
Using a general style sheet for the entire table does not always work
Might be multiple tables in the page that want different styles Different rows might want different styles
Solution
Explicitly supply CSS style names.
Summary
styleClass captionClass headerClass footerClass styleClass, captionClass, headerClass,
CSS name that will apply to table as a whole, caption (if there is one), first row (if it is a header), and last row (if it is a footer)
rowClasses
Comma-separated list of names. Apply first name to first nonheader row or column, then next name, etc. When you get to end of list, repeat. For instance, two names will apply to odd/even rows.
columnClasses
26
Comma-separated list of names. Apply until you run out, then stop. Do not repeat as with rowClasses. Thus, you normally supply exactly as many entries as you have columns.
Example: Summary
<h:dataTable var="someVar" value="#{someValue}" styleClass="tableStyle" captionClass= captionStyle captionClass="captionStyle" headerClass="headerStyle"
Style for caption ( any). y p (if y) Overall table style. I.e., <table class="tableStyle" >
Style for first table row, if it is a heading (i.e., there is at least one f:facet with name="header").
Apply row1 to first, third, fifth non-heading rows. Apply row2 to second, fourth, sixth non-heading rows.
Apply col1 to first column, col2 to second column, col3 to third column. If there are more than three columns, then no custom class is given to the later columns. Unlike rowClasses, these do not repeat.
28
29
30
31
Results
32
Ajax-Enabled Tables
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Overview
Problem
Wasteful to reload entire page when switching among various tables
Especially if there is a lot of non-table output on the page non table
Solution
Use f:ajax to rebuild the table without reloading the entire j g page.
Notes
O l b i code shown here. Only basic d h h Full details on f:ajax are given in separate tutorial section.
34
Example Overview
CompanyInfo class
Has list of available companies Maps company names to companies
Company class
Stores list of programmers working for the company
Shown earlier in this tutorial
Programmer class
Stores name, skill level, and programming languages
Shown earlier in this tutorial
Desired behavior
U chooses a company name and sees t bl of User h d table f programmers that work for that company. Table should be updated without reloading entire page
35
CompanyInfo
@ManagedBean This information does not change based on user input, so it is application scoped. @ApplicationScoped public class CompanyInfo { private String companyName; private Company[] companies = { new Company1(), new Company2(), new Company3() }; e o pa y (), e o pa y (), e o pa y () private List<SelectItem> companyChoices; Once the user chooses a company name, it will private Map<String, Company> companyMap; be associated with the corresponding Company. public CompanyInfo() { JSF comboboxes (i e h:selectOneMenu) take an array or List of SelectItems (i.e., SelectItems. companyChoices = new ArrayList<SelectItem>(); companyMap = new HashMap<String Company>(); HashMap<String, companyName = companies[0].getCompanyName(); for(Company c: companies) { SelectItem menuChoice = new SelectItem(c.getCompanyName()); companyChoices.add(menuChoice); companyMap.put(c.getCompanyName(), c); }}
36
CompanyInfo (Continued)
Simple accessor methods.
p public String getCompanyName() { g g p y () return(companyName); } public void setCompanyName(String companyName) { this.companyName = companyName; } public List<SelectItem> getCompanyChoices() { return (companyChoices); } public Company getCompany() { return(companyMap.get(companyName)); } }
37
Facelets Code
<div align="center"><b>Company:</b> <h:selectOneMenu value="#{companyInfo companyName}"> value= #{companyInfo.companyName} > <f:selectItems value="#{companyInfo.companyChoices}"/> <f:ajax render="programmerTable"/> When the combobox value changes, fire off a behind-the-scenes JavaScript request to the server. Update the model data for the </h:selectOneMenu> combobox (i.e., call setCompanyName). Then, return the data ( p y ) needed to rebuild the element with the id programmerTable. </div> Replace value for that element only, without reloading entire page. <p/> <h:dataTable var="programmer" value="#{companyInfo.company.programmers}" border="1" id="programmerTable" styleClass="mainTable" l l i bl captionClass="caption1" headerClass="heading" rowClasses= even,odd > rowClasses="even odd"> (Table body almost identical to previous two examples) </h:dataTable>
38
Results
39
Overview
Problem
You would like to let end user edit some table cells. However, you only want certain cells editable, and want a nearby Update button when it is. Update
Solution
When user clicks Edit checkbox, change the output g p from simple text to a textfield followed by an update button. Use Ajax to prevent reloading entire page.
Java Classes
CompanyInfo
Shown earlier
Company
Sh Shown earlier li
Programmer
Partially shown earlier earlier.
Added a boolean property to say whether the skill level is editable. Add d code t setLevel th t resets the boolean property to Added d to tL l that t th b l t t false.
42
Facelets Code
Core h:selectOneMenu and h:dataTable code <h:selectOneMenu ></h:selectOneMenu> is about the same as the previous example. <h:dataTable > (Most columns same as previous examples) <h:column> <f:facet name="header">Experience Level</f:facet> (<i>Edit? If the checkbox is <h:selectBooleanCheckbox value="#{programmer.levelEditable}"> checked, these two elements <f:ajax render="@form"/> (input field and Ajax-enabled </h:selectBooleanCheckbox></i>) submit button) <h:inputText value="#{programmer.level}" size="12" are shown. rendered="#{programmer.levelEditable}"/> <h:commandButton value="Update" rendered="#{programmer.levelEditable}"> <f:ajax render="@form" execute="@form"/> </h:commandButton> <h:outputText value="#{programmer.level}" rendered="#{!programmer.levelEditable}"/> If the checkbox is </h:column> not checked, this (Most columns same as previous examples) one element (giving simple </h:dataTable> output) is shown instead. 44
Results
45
Wrap-Up
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Syntax Summary
<h:dataTable var="row" Variable name to refer to each entry in collection (List array value="#{someBean.someData}" value="#{someBean someData}" Collection (List, array, or a few other types) border="1" It takes effort to use CSS to give table borders, so border is supplied as shortcut styleClass="css-table-style" CSS style for main table (<table class=""> headerClass="css-heading-style" CSS for 1 row, if there is a header defined below h d Cl " h di t l " rowClasses="evenRow,oddRow"> CSS styles for remaining rows, applied alternately <h:column> <f:facet name="header">Col 1 Title</f:facet> Text for first col in first row / #{row.someProperty} Value for first col in all subsequent rows </h:column> <h:column> <f:facet name="header">Col 2 Title</f:facet> Text for second col in first row #{row.someOtherProperty} Value for second col in all subsequent rows. You can also use other JSF constructs here. </h:column> </h:dataTable>
st
47
Questions?
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.