60 * deletion without notice.</b>
61 */
62 public class Table {
63 private final HtmlStyle tableStyle;
64 private Content caption;
65 private Map<String, Predicate<Element>> tabMap;
66 private String defaultTab;
67 private Set<String> tabs;
68 private HtmlStyle activeTabStyle = HtmlStyle.activeTableTab;
69 private HtmlStyle tabStyle = HtmlStyle.tableTab;
70 private HtmlStyle tabEnd = HtmlStyle.tabEnd;
71 private IntFunction<String> tabScript;
72 private Function<Integer, String> tabId = (i -> "t" + i);
73 private TableHeader header;
74 private List<HtmlStyle> columnStyles;
75 private int rowScopeColumnIndex;
76 private List<HtmlStyle> stripedStyles = Arrays.asList(HtmlStyle.altColor, HtmlStyle.rowColor);
77 private final List<Content> bodyRows;
78 private final List<Integer> bodyRowMasks;
79 private String rowIdPrefix = "i";
80
81 /**
82 * Creates a builder for an HTML table.
83 *
84 * @param style the style class for the {@code <table>} tag
85 */
86 public Table(HtmlStyle style) {
87 this.tableStyle = style;
88 bodyRows = new ArrayList<>();
89 bodyRowMasks = new ArrayList<>();
90 }
91
92 /**
93 * Sets the caption for the table.
94 * This is ignored if the table is configured to provide tabs to select
95 * different subsets of rows within the table.
96 * The caption should be suitable for use as the content of a {@code <caption>}
97 * element.
98 *
99 * <b>For compatibility, the code currently accepts a {@code <caption>} element
260 /**
261 * Sets the prefix used for the {@code id} attribute for each row in the table.
262 * The default is "i".
263 *
264 * <p>Note:
265 * <ul>
266 * <li>The prefix should probably be a value such that the generated ids cannot
267 * clash with any other id, such as those that might be created for fields within
268 * a class.
269 * </ul>
270 *
271 * @param prefix the prefix
272 * @return this object
273 */
274 public Table setRowIdPrefix(String prefix) {
275 rowIdPrefix = prefix;
276 return this;
277 }
278
279 /**
280 * Add a row of data to the table.
281 * Each item of content should be suitable for use as the content of a
282 * {@code <th>} or {@code <td>} cell.
283 * This method should not be used when the table has tabs: use a method
284 * that takes an {@code Element} parameter instead.
285 *
286 * @param contents the contents for the row
287 */
288 public void addRow(Content... contents) {
289 addRow(null, Arrays.asList(contents));
290 }
291
292 /**
293 * Add a row of data to the table.
294 * Each item of content should be suitable for use as the content of a
295 * {@code <th>} or {@code <td> cell}.
296 * This method should not be used when the table has tabs: use a method
297 * that takes an {@code element} parameter instead.
298 *
299 * @param contents the contents for the row
379 }
380
381 /**
382 * Returns whether or not the table is empty.
383 * The table is empty if it has no (body) rows.
384 *
385 * @return true if the table has no rows
386 */
387 public boolean isEmpty() {
388 return bodyRows.isEmpty();
389 }
390
391 /**
392 * Returns the HTML for the table.
393 *
394 * @return the HTML
395 */
396 public Content toContent() {
397 HtmlTree mainDiv = new HtmlTree(HtmlTag.DIV);
398 mainDiv.setStyle(tableStyle);
399 HtmlTree table = new HtmlTree(HtmlTag.TABLE);
400 if (tabMap == null || tabs.size() == 1) {
401 if (tabMap == null) {
402 table.add(caption);
403 } else if (tabs.size() == 1) {
404 String tabName = tabs.iterator().next();
405 table.add(getCaption(new StringContent(tabName)));
406 }
407 table.add(getTableBody());
408 mainDiv.add(table);
409 } else {
410 HtmlTree tablist = new HtmlTree(HtmlTag.DIV)
411 .put(HtmlAttr.ROLE, "tablist")
412 .put(HtmlAttr.ARIA_ORIENTATION, "horizontal");
413
414 int tabIndex = 0;
415 tablist.add(createTab(tabId.apply(tabIndex), activeTabStyle, true, defaultTab));
416 table.put(HtmlAttr.ARIA_LABELLEDBY, tabId.apply(tabIndex));
417 for (String tabName : tabMap.keySet()) {
418 tabIndex++;
|
60 * deletion without notice.</b>
61 */
62 public class Table {
63 private final HtmlStyle tableStyle;
64 private Content caption;
65 private Map<String, Predicate<Element>> tabMap;
66 private String defaultTab;
67 private Set<String> tabs;
68 private HtmlStyle activeTabStyle = HtmlStyle.activeTableTab;
69 private HtmlStyle tabStyle = HtmlStyle.tableTab;
70 private HtmlStyle tabEnd = HtmlStyle.tabEnd;
71 private IntFunction<String> tabScript;
72 private Function<Integer, String> tabId = (i -> "t" + i);
73 private TableHeader header;
74 private List<HtmlStyle> columnStyles;
75 private int rowScopeColumnIndex;
76 private List<HtmlStyle> stripedStyles = Arrays.asList(HtmlStyle.altColor, HtmlStyle.rowColor);
77 private final List<Content> bodyRows;
78 private final List<Integer> bodyRowMasks;
79 private String rowIdPrefix = "i";
80 private String id;
81
82 /**
83 * Creates a builder for an HTML table.
84 *
85 * @param style the style class for the {@code <table>} tag
86 */
87 public Table(HtmlStyle style) {
88 this.tableStyle = style;
89 bodyRows = new ArrayList<>();
90 bodyRowMasks = new ArrayList<>();
91 }
92
93 /**
94 * Sets the caption for the table.
95 * This is ignored if the table is configured to provide tabs to select
96 * different subsets of rows within the table.
97 * The caption should be suitable for use as the content of a {@code <caption>}
98 * element.
99 *
100 * <b>For compatibility, the code currently accepts a {@code <caption>} element
261 /**
262 * Sets the prefix used for the {@code id} attribute for each row in the table.
263 * The default is "i".
264 *
265 * <p>Note:
266 * <ul>
267 * <li>The prefix should probably be a value such that the generated ids cannot
268 * clash with any other id, such as those that might be created for fields within
269 * a class.
270 * </ul>
271 *
272 * @param prefix the prefix
273 * @return this object
274 */
275 public Table setRowIdPrefix(String prefix) {
276 rowIdPrefix = prefix;
277 return this;
278 }
279
280 /**
281 * Sets the id attribute of the table.
282 *
283 * @param id the id
284 * @return this object
285 */
286 public Table setId(String id) {
287 this.id = id;
288 return this;
289 }
290
291 /**
292 * Add a row of data to the table.
293 * Each item of content should be suitable for use as the content of a
294 * {@code <th>} or {@code <td>} cell.
295 * This method should not be used when the table has tabs: use a method
296 * that takes an {@code Element} parameter instead.
297 *
298 * @param contents the contents for the row
299 */
300 public void addRow(Content... contents) {
301 addRow(null, Arrays.asList(contents));
302 }
303
304 /**
305 * Add a row of data to the table.
306 * Each item of content should be suitable for use as the content of a
307 * {@code <th>} or {@code <td> cell}.
308 * This method should not be used when the table has tabs: use a method
309 * that takes an {@code element} parameter instead.
310 *
311 * @param contents the contents for the row
391 }
392
393 /**
394 * Returns whether or not the table is empty.
395 * The table is empty if it has no (body) rows.
396 *
397 * @return true if the table has no rows
398 */
399 public boolean isEmpty() {
400 return bodyRows.isEmpty();
401 }
402
403 /**
404 * Returns the HTML for the table.
405 *
406 * @return the HTML
407 */
408 public Content toContent() {
409 HtmlTree mainDiv = new HtmlTree(HtmlTag.DIV);
410 mainDiv.setStyle(tableStyle);
411 if (id != null) {
412 mainDiv.setId(id);
413 }
414 HtmlTree table = new HtmlTree(HtmlTag.TABLE);
415 if (tabMap == null || tabs.size() == 1) {
416 if (tabMap == null) {
417 table.add(caption);
418 } else if (tabs.size() == 1) {
419 String tabName = tabs.iterator().next();
420 table.add(getCaption(new StringContent(tabName)));
421 }
422 table.add(getTableBody());
423 mainDiv.add(table);
424 } else {
425 HtmlTree tablist = new HtmlTree(HtmlTag.DIV)
426 .put(HtmlAttr.ROLE, "tablist")
427 .put(HtmlAttr.ARIA_ORIENTATION, "horizontal");
428
429 int tabIndex = 0;
430 tablist.add(createTab(tabId.apply(tabIndex), activeTabStyle, true, defaultTab));
431 table.put(HtmlAttr.ARIA_LABELLEDBY, tabId.apply(tabIndex));
432 for (String tabName : tabMap.keySet()) {
433 tabIndex++;
|