1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.extremecomponents.table.view;
17
18 import java.util.Iterator;
19 import java.util.List;
20
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.extremecomponents.table.bean.Export;
25 import org.extremecomponents.table.bean.Form;
26 import org.extremecomponents.table.bean.Table;
27 import org.extremecomponents.table.bean.TableSection;
28 import org.extremecomponents.table.model.ExportHandler;
29 import org.extremecomponents.table.model.FilterHandler;
30 import org.extremecomponents.table.model.ParameterRegistry;
31 import org.extremecomponents.table.model.TableModel;
32 import org.extremecomponents.table.model.TableModelUtils;
33 import org.extremecomponents.table.model.ViewHandler;
34 import org.extremecomponents.util.HtmlBuilder;
35
36
37 /***
38 * The default implementation of the table. The notion
39 * is that you can easily plug in different parts of the view as
40 * needed or desired.
41 *
42 * @author Jeff Johnston
43 */
44 public class HtmlView implements View
45 {
46 private static Log logger = LogFactory.getLog(HtmlView.class);
47 public final static String PAGINATION_EXPORT_REGION = "paginationExportRegion";
48 public final static String PAGINATION = "pagination";
49 public final static String PAGINATION_TITLE = "paginationTitle";
50 public final static String PAGINATION_HEADER = "paginationHeader";
51 public final static String EXPORT_TOOLBAR = "exportToolBar";
52 public final static String FORM_BUTTONS = "formButtons";
53 public final static String FILTER = "filter";
54 public final static String TABLE_TITLE = "tableTitle";
55 private HtmlBuilder html = new HtmlBuilder();
56
57 public void beforeBody(TableModel model)
58 {
59 paginationExport(model);
60 tableStart(model);
61 header(model);
62 filter(model);
63 formStart(model);
64 }
65
66 public void body(TableModel model, String value, boolean startRow, boolean endRow)
67 {
68 if (startRow)
69 {
70 html.tr(1).close();
71 }
72
73 html.append(value);
74
75 if (endRow)
76 {
77 html.trEnd(1);
78 }
79 }
80
81 public Object afterBody(TableModel model)
82 {
83 tableEnd(model);
84
85 return html.toString();
86 }
87
88 /***
89 * The pagination and export will display together.
90 */
91 public void paginationExport(TableModel model)
92 {
93 html.table(0).styleClass(PAGINATION_EXPORT_REGION).width(model.getTable().getWidth()).close();
94 html.tr(1).close();
95 html.td(2).close();
96
97 pagination(model);
98
99 html.tdEnd();
100
101 html.td(2).align("right").valign("bottom").style("padding-right:15px").close();
102
103 export(model);
104
105 html.tdEnd();
106 html.trEnd(1);
107 html.tableEnd(0);
108 }
109
110 /***
111 * The pagination that will hover over the table.
112 */
113 public void pagination(TableModel model)
114 {
115 if (!model.getTable().doPagination())
116 {
117 return;
118 }
119
120 List pagination = model.getPageHandler().getPagination(model);
121
122 html.table(2).border("0").cellPadding("0").cellSpacing("0").styleClass(PAGINATION).close();
123
124
125 Table table = model.getTable();
126
127 if (StringUtils.isNotEmpty(table.getTitle()))
128 {
129 html.tr(3).close();
130 html.th(4).styleClass(PAGINATION_TITLE).colSpan("" + pagination.size()).close();
131 html.append(table.getTitle());
132 html.thEnd().trEnd(3);
133 }
134
135
136 html.tr(3).close();
137 html.td(4);
138
139 if (pagination.size() > 0)
140 {
141 html.styleClass(PAGINATION_HEADER);
142 }
143
144 html.colSpan("" + pagination.size()).close();
145
146 TableSection section = model.getTableSection();
147
148 if (section.getTotalRows() == 0)
149 {
150 html.append("There were no results found.");
151 }
152 else
153 {
154 html.append(section.getTotalRows() + " results found, displaying " + (section.getRowStart() + 1) + " to " + section.getRowEnd());
155 }
156
157 html.tdEnd();
158 html.trEnd(3);
159
160
161 html.tr(3);
162 html.close();
163
164 if (pagination.size() > 0)
165 {
166 for (Iterator iter = pagination.iterator(); iter.hasNext();)
167 {
168 html.append((String) iter.next());
169 }
170 }
171
172 html.trEnd(3);
173 html.tableEnd(2);
174 html.newline();
175 html.tabs(2);
176 }
177
178 public void export(TableModel model)
179 {
180 if (!model.getExportHandler().hasExports())
181 {
182 return;
183 }
184
185 html.table(2).styleClass(EXPORT_TOOLBAR).close();
186 html.tr(3).close();
187
188 for (Iterator iter = model.getExportHandler().getExports().iterator(); iter.hasNext();)
189 {
190 html.td(4).close();
191
192 Export export = (Export) iter.next();
193 exportHtml(model, export);
194 html.tdEnd();
195 }
196
197 html.trEnd(3);
198 html.tableEnd(2);
199 }
200
201 private void exportHtml(TableModel model, Export export)
202 {
203 html.a();
204 html.quote();
205
206 String action = model.getTable().getAction();
207
208 if (StringUtils.isNotEmpty(action))
209 {
210 html.append(action);
211 }
212
213 html.question().append(Table.EXTREME_TABLE).equals().append(model.getTableKey()).ampersand().append(model.getTableKey() + ParameterRegistry.EXPORT).equals().append(export.getView()).ampersand().append(model.getTableKey() + ExportHandler.EXPORT_NAME).equals().append(export.getName());
214 html.append(model.getRegistry().getURLParameterString(true, true, true));
215 html.quote();
216 html.close();
217
218 if (StringUtils.isNotEmpty(export.getImage()))
219 {
220 String title = (export.getTitle() == null) ? "Export" : export.getTitle();
221 html.img(export.getImage(), title);
222 }
223 else
224 {
225 html.append(" " + export.getView() + " ");
226 }
227
228 html.aEnd();
229 }
230
231 /***
232 * The opening table tag along with all the attributes of the table.
233 */
234 public void tableStart(TableModel model)
235 {
236 Table table = model.getTable();
237
238 html.table(0);
239 html.id(table.getId());
240 html.border(table.getBorder());
241 html.cellSpacing(table.getCellspacing());
242 html.cellPadding(table.getCellpadding());
243 html.width(table.getWidth());
244
245 String styleClass = table.getStyleClass();
246
247 if (StringUtils.isNotBlank(styleClass))
248 {
249 html.styleClass(styleClass);
250 }
251
252 String style = table.getStyle();
253
254 if (StringUtils.isNotBlank(style))
255 {
256 html.style(style);
257 }
258
259 html.close();
260
261 if (!model.getTable().doPagination() && StringUtils.isNotBlank(table.getTitle()))
262 {
263 html.tr(1).close();
264 html.th(2).styleClass(TABLE_TITLE).colSpan("" + model.getColumnMetaData().columnCount()).close();
265 html.append(table.getTitle());
266 html.thEnd();
267 html.trEnd(1);
268 }
269 }
270
271 /***
272 * Closes the table.
273 */
274 public void tableEnd(TableModel model)
275 {
276 html.tableEnd(0);
277 formButtons(model);
278 }
279
280 /***
281 * The header row of the table. This is typically the first row of the table.
282 */
283 public void header(TableModel model)
284 {
285 html.tr(1).close();
286
287 for (Iterator iter = TableModelUtils.getHeader(model, ViewHandler.HTML).iterator();
288 iter.hasNext();)
289 {
290 html.append((String) iter.next());
291 }
292
293 html.trEnd(1);
294 }
295
296 /***
297 * The filter row of the table. Typically sits below the header (if enabled).
298 * Will contain input or select type fields to allow the user to filter the result set.
299 */
300 public void filter(TableModel model)
301 {
302 List filter = model.getFilterHandler().getFilter(model);
303
304 if (!model.getTable().doFilter())
305 {
306 return;
307 }
308
309 filterFormStart(model);
310
311 html.tr(1).styleClass(FILTER).close();
312
313 for (Iterator iter = filter.iterator(); iter.hasNext();)
314 {
315 String value = (String) iter.next();
316
317 html.td(2).close();
318
319 if (iter.hasNext())
320 {
321 html.append(value);
322 }
323 else
324 {
325 html.table(2).cellPadding("0").cellSpacing("0").border("0").width("100%").close();
326
327 html.tr(3).close();
328
329 html.td(4).width("100%").close();
330 html.append(value);
331 html.tdEnd();
332
333 html.td(4).align("right").close();
334 filterFomButtons(model);
335 html.tdEnd();
336
337 html.trEnd(3);
338 html.tableEnd(2);
339 }
340
341 html.tdEnd();
342 }
343
344 html.trEnd(1);
345 filterFormEnd();
346 }
347
348 /***
349 * Get the HTML for the start of the form <form> tag. The filter will need to be
350 * wrapped in a form tag so that it can be submitted.
351 */
352 private void filterFormStart(TableModel model)
353 {
354 html.form();
355 html.name(model.getTableKey() + "filter");
356
357 String action = model.getTable().getAction();
358
359 if (StringUtils.isNotEmpty(action))
360 {
361 html.action(action);
362 }
363
364 html.close();
365
366 String hiddenFields = model.getRegistry().getFormHiddenFields(false, true, false);
367
368 if (StringUtils.isNotEmpty(hiddenFields))
369 {
370 html.append(hiddenFields);
371 }
372 }
373
374 /***
375 * The HTML for the filter search and clear buttons.
376 */
377 private void filterFomButtons(TableModel model)
378 {
379 html.table(4).cellPadding("0").cellSpacing("0").border("0").close();
380 html.tr(5).close();
381
382 html.input("hidden").name(model.getTableKey() + "filter_button").close();
383
384 html.td(6).valign("center").close();
385
386 html.a().quote().append("javascript:document." + model.getTableKey() + "filter." + model.getTableKey() + "filter_button.value='" + FilterHandler.DO_SEARCH + "';document." + model.getTableKey() + "filter.submit()").quote().close();
387
388 String imageSearch = model.getTable().getImage(FilterHandler.SEARCH_IMAGE);
389
390 if (StringUtils.isNotEmpty(imageSearch))
391 {
392 html.img(imageSearch, "Search");
393 }
394 else
395 {
396 html.append(" Filter ");
397 }
398
399 html.aEnd();
400
401 html.tdEnd();
402 html.td(6).valign("center").close();
403
404 html.a().quote().append("javascript:document." + model.getTableKey() + "filter." + model.getTableKey() + "filter_button.value='" + FilterHandler.DO_CLEAR + "';document." + model.getTableKey() + "filter.submit()").quote().close();
405
406 String imageClear = model.getTable().getImage(FilterHandler.CLEAR_IMAGE);
407
408 if (StringUtils.isNotEmpty(imageClear))
409 {
410 html.img(imageClear, "Clear");
411 }
412 else
413 {
414 html.append(" Clear ");
415 }
416
417 html.aEnd();
418
419 html.tdEnd();
420 html.trEnd(5);
421 html.tableEnd(4);
422 html.format(4, 1);
423 html.newline();
424 }
425
426 /***
427 * Get the HTML for the end of the form <form> tag.
428 */
429 private void filterFormEnd()
430 {
431 html.formEnd();
432 }
433
434 /***
435 * The form will come right before the body section.
436 */
437 private void formStart(TableModel model)
438 {
439 Form form = model.getFormHandler().getForm();
440
441 if (form != null)
442 {
443 String name = form.getName();
444 String action = form.getAction();
445 String method = form.getMethod();
446
447 html.form().name(name).action(action).method(method);
448
449 String onsubmit = form.getOnsubmit();
450
451 if (StringUtils.isNotEmpty(onsubmit))
452 {
453 html.onsubmit(onsubmit);
454 }
455
456 html.close();
457
458
459 html.append(model.getRegistry().getFormHiddenFields(true, true, true));
460 html.append(model.getFormHandler().getHiddenFields());
461 }
462 }
463
464 public void formButtons(TableModel model)
465 {
466 String formButtons = model.getFormHandler().getFormButtons();
467
468 if (StringUtils.isNotEmpty(formButtons))
469 {
470 html.newline();
471 html.span().styleClass(FORM_BUTTONS).close();
472 html.append(formButtons);
473 html.spanEnd();
474 html.formEnd();
475 }
476 }
477 }