| 1 33 34 package com.icesoft.faces.component.ext.renderkit; 35 36 import com.icesoft.faces.component.CSS_DEFAULT; 37 import com.icesoft.faces.component.ext.HtmlDataTable; 38 import com.icesoft.faces.component.ext.RowSelector; 39 import com.icesoft.faces.component.ext.UIColumns; 40 import com.icesoft.faces.component.ext.taglib.Util; 41 import com.icesoft.faces.component.panelseries.UISeries; 42 import com.icesoft.faces.context.DOMContext; 43 import com.icesoft.faces.context.effects.JavascriptContext; 44 import com.icesoft.faces.renderkit.dom_html_basic.HTML; 45 import org.w3c.dom.Element ; 46 import org.w3c.dom.Node ; 47 48 import javax.faces.component.UIColumn; 49 import javax.faces.component.UIComponent; 50 import javax.faces.context.FacesContext; 51 import java.io.IOException ; 52 import java.util.*; 53 54 55 public class TableRenderer 56 extends com.icesoft.faces.renderkit.dom_html_basic.TableRenderer { 57 58 private static final String SELECTED_ROWS = "sel_rows"; 59 60 public String getComponentStyleClass(UIComponent uiComponent) { 61 return (String ) uiComponent.getAttributes().get("styleClass"); 62 63 } 64 65 public String getHeaderClass(UIComponent component) { 66 return (String ) component.getAttributes().get("headerClass"); 67 } 68 69 public String getFooterClass(UIComponent component) { 70 return (String ) component.getAttributes().get("footerClass"); 71 } 72 73 public String [] getRowStyles(UIComponent uiComponent) { 75 if (((String []) getRowStyleClasses(uiComponent)).length <= 0) { 76 String [] rowStyles = new String [2]; 77 rowStyles[0] = Util.getQualifiedStyleClass(uiComponent, 78 CSS_DEFAULT.TABLE_ROW_CLASS1); 79 rowStyles[1] =Util.getQualifiedStyleClass(uiComponent, 80 CSS_DEFAULT.TABLE_ROW_CLASS2); 81 return rowStyles; 82 } else { 83 return getRowStyleClasses(uiComponent); 84 } 85 } 86 87 public String [] getHeaderStyles(UIComponent uiComponent) { 88 if (((String []) getHeaderStyleClasses(uiComponent)).length <= 0) { 89 String [] headerStyles = new String [2]; 90 headerStyles[0] = Util.getQualifiedStyleClass(uiComponent, 91 CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS1); 92 headerStyles[1] =Util.getQualifiedStyleClass(uiComponent, 93 CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS2); 94 return headerStyles; 95 } else { 96 return getHeaderStyleClasses(uiComponent); 97 } 98 } 99 100 public void writeColStyles(String [] columnStyles, int columnStylesMaxIndex, 101 int columnStyleIndex, Element td, 102 int colNumber, 103 UIComponent uiComponent 104 ) { 105 if (columnStyles.length > 0) { 106 if (columnStylesMaxIndex >= 0) { 107 td.setAttribute("class", columnStyles[columnStyleIndex]); 108 } 109 } 110 } 111 112 protected void renderFacet(FacesContext facesContext, 113 UIComponent uiComponent, 114 DOMContext domContext, boolean header) 115 throws IOException { 116 String facet, tag, element, facetClass; 117 if (header) { 118 facet = "header"; 119 tag = HTML.THEAD_ELEM; 120 element = HTML.TH_ELEM; 121 facetClass = getHeaderClass(uiComponent); 122 } else { 123 facet = "footer"; 124 tag = HTML.TFOOT_ELEM; 125 element = HTML.TD_ELEM; 126 facetClass = getFooterClass(uiComponent); 127 } 128 UISeries uiData = (UISeries) uiComponent; 129 uiData.setRowIndex(-1); 130 Element root = (Element ) domContext.getRootNode(); 131 if (isScrollable(uiComponent)) { 132 133 if (header) { 134 root = getScrollableHeaderTableElement(root); 136 137 } else { 138 root = getScrollableBodyTableElement(root); 140 } 141 } 142 UIComponent headerFacet = getFacetByName(uiData, facet); 143 boolean childHeaderFacetExists = 144 childColumnHasFacetWithName(uiData, facet); 145 Element thead = null; 146 if (headerFacet != null || childHeaderFacetExists) { 147 thead = domContext.createElement(tag); 148 root.appendChild(thead); 149 150 151 if (header) { 152 renderTableHeader(facesContext, uiComponent, headerFacet, thead, facetClass, element); 153 renderColumnHeader(facesContext, uiComponent, thead, facet, element, header); 154 } else { 155 renderColumnHeader(facesContext, uiComponent, thead, facet, element, header); 156 renderTableHeader(facesContext, uiComponent, headerFacet, thead, facetClass, element); 157 158 } 159 domContext.setCursorParent(root); 160 } 161 } 162 163 private void renderColumnHeader(FacesContext facesContext, 164 UIComponent uiComponent, 165 Element thead, 166 String facet, 167 String element, 168 boolean header) throws IOException { 169 StringTokenizer columnWitdths = getColumnWidths(uiComponent); 170 DOMContext domContext = 171 DOMContext.getDOMContext(facesContext, uiComponent); 172 Element tr = domContext.createElement("tr"); 173 thead.appendChild(tr); 174 List childList = getRenderedChildColumnsList(uiComponent); 175 Iterator childColumns = childList.iterator(); 176 String width = null; 177 int columnIndex = 1; 178 int headerStyleLength = getHeaderStyles(uiComponent).length; 179 int styleIndex = 0; 180 while (childColumns.hasNext()) { 181 182 UIComponent nextColumn = (UIComponent) childColumns.next(); 183 if (columnWitdths != null && columnWitdths.hasMoreTokens()) { 184 width = columnWitdths.nextToken(); 185 } else { 186 if (isScrollable(uiComponent)) { 187 width = "150px"; 188 } else { 189 width = null; 190 } 191 192 } 193 if (nextColumn instanceof UIColumn) { 194 processUIColumnHeader(facesContext, uiComponent, 195 (UIColumn) nextColumn, tr, domContext, 196 facet, element, width, 197 columnIndex, 198 styleIndex); 199 columnIndex++; 200 } else if (nextColumn instanceof UIColumns) { 201 columnIndex = processUIColumnsHeader(facesContext, 202 uiComponent, 203 (UIColumns) nextColumn, 204 tr, domContext, facet, 205 element, width, columnIndex, 206 styleIndex, 207 headerStyleLength); 208 } 209 210 if (styleIndex++ == (headerStyleLength-1)) { 211 styleIndex = 0; 212 } 213 } 214 if (header && isScrollable(uiComponent)) { 215 tr.appendChild(scrollBarSpacer(domContext, facesContext)); 216 } 217 } 218 private void renderTableHeader(FacesContext facesContext, 219 UIComponent uiComponent, 220 UIComponent headerFacet, 221 Element thead, 222 String facetClass, 223 String element 224 ) throws IOException { 225 DOMContext domContext = 226 DOMContext.getDOMContext(facesContext, uiComponent); 227 if (headerFacet != null && headerFacet.isRendered()) { 228 229 resetFacetChildId(headerFacet); 230 Element tr = domContext.createElement("tr"); 231 thead.appendChild(tr); 232 Element th = domContext.createElement(element); 233 tr.appendChild(th); 234 if (facetClass != null) { 235 th.setAttribute("class", facetClass); 236 } 237 th.setAttribute("colspan", 238 String.valueOf(getNumberOfChildColumns(uiComponent))); 239 th.setAttribute("scope", "colgroup"); 240 domContext.setCursorParent(th); 241 domContext.streamWrite(facesContext, uiComponent, 242 domContext.getRootNode(), th); 243 encodeParentAndChildren(facesContext, headerFacet); 244 if (isScrollable(uiComponent)) { 245 tr.appendChild(scrollBarSpacer(domContext, facesContext)); 246 } 247 } 248 } 249 private void processUIColumnHeader(FacesContext facesContext, 250 UIComponent uiComponent, 251 UIColumn nextColumn, Element tr, 252 DOMContext domContext, String facet, 253 String element, String width, int columnIndex, 254 int styleIndex) 255 throws IOException { 256 HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent; 257 Element th = domContext.createElement(element); 258 tr.appendChild(th); 259 if ("header".equalsIgnoreCase(facet) ){ 260 th.setAttribute("class",getHeaderStyles(uiComponent)[styleIndex]); 261 } else { 262 th.setAttribute("class",getFooterClass(htmlDataTable)); 263 } 264 265 if (width != null) { 266 th.setAttribute("style", "width:" + width + ";overflow:hidden;"); 267 } 268 th.setAttribute("colgroup", "col"); 269 UIComponent nextFacet = getFacetByName(nextColumn, facet); 270 271 if (nextFacet != null) { 272 resetFacetChildId(nextFacet); 273 domContext.setCursorParent(th); 274 domContext.streamWrite(facesContext, uiComponent, 275 domContext.getRootNode(), th); 276 encodeParentAndChildren(facesContext, nextFacet); 277 } 278 } 279 280 private int processUIColumnsHeader(FacesContext facesContext, 281 UIComponent uiComponent, 282 UIColumns nextColumn, Element tr, 283 DOMContext domContext, String facet, 284 String element, String width, int columnIndex, 285 int styleIndex, 286 int headerStyleLength) 287 throws IOException { 288 HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent; 289 int rowIndex = nextColumn.getFirst(); 290 nextColumn.setRowIndex(rowIndex); 292 while (nextColumn.isRowAvailable()) { 293 UIComponent headerFacet = getFacetByName(nextColumn, facet); 294 295 if (headerFacet != null) { 296 Node oldParent = domContext.getCursorParent(); 297 Element th = domContext.createElement(element); 298 tr.appendChild(th); 299 th.setAttribute("class",getHeaderStyles(uiComponent)[styleIndex]); 300 if (width != null) { 301 th.setAttribute("style", "width:" + width + ";"); 302 } 303 th.setAttribute("colgroup", "col"); 304 domContext.setCursorParent(th); 305 domContext.streamWrite(facesContext, uiComponent, 306 domContext.getRootNode(), th); 307 308 encodeParentAndChildren(facesContext, headerFacet); 309 domContext.setCursorParent(oldParent); 310 } 311 if (styleIndex++ == (headerStyleLength-1)) { 312 styleIndex = 0; 313 } 314 rowIndex++; 315 columnIndex++; 316 nextColumn.setRowIndex(rowIndex); 317 } 318 nextColumn.setRowIndex(-1); 319 return columnIndex; 320 } 321 322 323 public void encodeChildren(FacesContext facesContext, 324 UIComponent uiComponent) throws IOException { 325 validateParameters(facesContext, uiComponent, null); 326 DOMContext domContext = 327 DOMContext.getDOMContext(facesContext, uiComponent); 328 Element root = (Element ) domContext.getRootNode(); 329 330 if (isScrollable(uiComponent)) { 331 root = getScrollableBodyTableElement(root); 332 } 333 DOMContext.removeChildrenByTagName(root, HTML.TBODY_ELEM); 334 Element tBody = (Element ) domContext.createElement(HTML.TBODY_ELEM); 335 root.appendChild(tBody); 336 337 HtmlDataTable uiData = (HtmlDataTable) uiComponent; 338 int rowIndex = uiData.getFirst(); 339 if (uiData.getRowCount() >=0 && uiData.getRowCount() <= rowIndex) { 340 domContext.stepOver(); 341 return; 342 } 343 uiData.setRowIndex(rowIndex); 344 int numberOfRowsToDisplay = uiData.getRows(); 345 int countOfRowsDisplayed = 0; 346 String rowStyles[] = getRowStyles(uiComponent); 347 int rowStyleIndex = 0; 348 int rowStylesMaxIndex = rowStyles.length - 1; 349 350 RowSelector rowSelector = getRowSelector(uiComponent); 351 boolean rowSelectorFound = rowSelector != null; 352 boolean toggleOnClick = false; 353 String rowSelectionFunctionName = null; 354 boolean rowSelectorCodeAdded = false; Element scriptNode = null; 356 if (rowSelectorFound) { 357 toggleOnClick = rowSelector.getToggleOnClick().booleanValue(); 358 Element rowSelectedField = 359 domContext.createElement(HTML.INPUT_ELEM); 360 String tableId = uiComponent.getClientId(facesContext); 361 String id = getSelectedRowParameterName(tableId); 362 rowSelectedField.setAttribute(HTML.ID_ATTR, id); 363 rowSelectedField.setAttribute(HTML.NAME_ATTR, id); 364 rowSelectedField.setAttribute(HTML.TYPE_ATTR, "hidden"); 365 root.appendChild(rowSelectedField); 366 rowSelectionFunctionName = "ice_tableRowClicked" + rowSelectorNumber(facesContext); 367 String scriptSrc = "this['" + rowSelectionFunctionName + "'] = function (id){\n"; 368 scriptSrc += "try{ var fld = $('" + id + 369 "');fld.value = id;var nothingEvent = new Object();\n"; 370 scriptSrc += 371 " var form = Ice.util.findForm(fld);iceSubmit(null,fld,nothingEvent);}catch(e){alert(e);}};"; 372 JavascriptContext.addJavascriptCall(facesContext, scriptSrc); 373 scriptNode = domContext.createElement(HTML.SCRIPT_ELEM); 374 scriptNode.setAttribute("language", "javascript"); 375 scriptNode.appendChild(domContext.createTextNode(scriptSrc)); 376 378 } 379 380 String columnStyles[] = getColumnStyleClasses(uiComponent); 381 int columnStyleIndex; 382 int columnStylesMaxIndex = columnStyles.length - 1; 383 while (uiData.isRowAvailable()) { 384 columnStyleIndex = 0; 385 String selectedClass = null; 386 if (rowStylesMaxIndex >= 0) { 387 selectedClass = rowStyles[rowStyleIndex]; 388 } 389 390 Iterator childs = uiData.getChildren().iterator(); 391 Element tr = (Element ) domContext.createElement(HTML.TR_ELEM); 392 if (rowSelectorFound && toggleOnClick) { 393 tr.setAttribute("onclick", rowSelectionFunctionName + "('" + 394 uiData.getRowIndex() + "');"); 395 } 396 String id = uiComponent.getClientId(facesContext); 397 tr.setAttribute(HTML.ID_ATTR, id); 398 if (rowSelectorFound) { 399 if (Boolean.TRUE.equals(rowSelector.getValue())){ 400 selectedClass += " "+ rowSelector.getSelectedClass(); 401 } else { 402 selectedClass += " "+ rowSelector.getStyleClass(); 403 } 404 StringTokenizer st = new StringTokenizer( 405 rowSelector.getMouseOverClass()); 406 StringBuffer omov = new StringBuffer (); 407 StringBuffer omot = new StringBuffer (); 408 while(st.hasMoreTokens()){ 409 String t = st.nextToken(); 410 omov.append("Element.addClassName($('" + id + "'), '" + 411 t + "');"); 412 omot.append("Element.removeClassName($('" + id + "'), '" + 413 t + "');"); 414 } 415 tr.setAttribute(HTML.ONMOUSEOVER_ATTR, omov.toString()); 416 tr.setAttribute(HTML.ONMOUSEOUT_ATTR, omot.toString()); 417 418 } 419 domContext.setCursorParent(tBody); 420 tBody.appendChild(tr); 421 422 tr.setAttribute(HTML.CLASS_ATTR, selectedClass); 423 424 if(rowStylesMaxIndex >= 0){ if (++rowStyleIndex > rowStylesMaxIndex) { 426 rowStyleIndex = 0; 427 } 428 } 429 int colNumber = 1; 430 StringTokenizer columnWitdths = 431 getColumnWidths(uiData); 432 while (childs.hasNext()) { 433 UIComponent nextChild = (UIComponent) childs.next(); 434 if (nextChild.isRendered()) { 435 if (nextChild instanceof UIColumn) { 436 Element td = domContext.createElement(HTML.TD_ELEM); 437 if(!rowSelectorCodeAdded && scriptNode != null){ 438 td.appendChild(scriptNode); 439 } 440 writeColStyles(columnStyles, columnStylesMaxIndex, 441 columnStyleIndex, td, colNumber++, 442 uiComponent); 443 444 if (isScrollable(uiComponent)) { 445 String width = "150px"; 446 if( columnWitdths != null && 447 columnWitdths.hasMoreTokens()) { 448 width = columnWitdths.nextToken(); 449 } 450 td.setAttribute("style", "width:" + width + 451 ";overflow:hidden;"); 452 } 453 454 tr.appendChild(td); 455 457 if (++columnStyleIndex > columnStylesMaxIndex) { 458 columnStyleIndex = 0; 459 } 460 461 Node oldCursorParent = domContext.getCursorParent(); 462 domContext.setCursorParent(td); 463 domContext.streamWrite(facesContext, uiComponent, 464 domContext.getRootNode(), td); 465 466 467 encodeParentAndChildren(facesContext, nextChild); 468 domContext.setCursorParent(oldCursorParent); 469 470 } else if (nextChild instanceof UIColumns) { 471 String width = null; 472 if (isScrollable(uiComponent) && 473 columnWitdths != null && 474 columnWitdths.hasMoreTokens()) { 475 width = columnWitdths.nextToken(); 476 477 } 478 encodeColumns(facesContext, nextChild, domContext, tr, 479 columnStyles, columnStylesMaxIndex, 480 columnStyleIndex, colNumber, width); 481 colNumber = uiData.getColNumber(); 482 } 483 } 484 485 } 486 rowIndex++; 487 countOfRowsDisplayed++; 488 if ((numberOfRowsToDisplay > 0 && 489 countOfRowsDisplayed >= numberOfRowsToDisplay) || 490 (uiData.getRowCount() >=0 && rowIndex >= uiData.getRowCount())) { 491 break; 492 } 493 494 uiData.setRowIndex(rowIndex); 495 } 496 uiData.setRowIndex(-1); 497 domContext.stepOver(); 498 domContext.streamWrite(facesContext, uiComponent); 499 } 500 501 private void encodeColumns(FacesContext facesContext, UIComponent columns, 502 DOMContext domContext, Node tr, 503 String [] columnStyles, int columnStylesMaxIndex, 504 int columnStyleIndex, int colNumber, 505 String width) throws IOException { 506 UIColumns uiList = (UIColumns) columns; 507 int rowIndex = uiList.getFirst(); 508 uiList.setRowIndex(rowIndex); 509 int numberOfRowsToDisplay = uiList.getRows(); 510 int countOfRowsDisplayed = 0; 511 domContext.setCursorParent(tr); 512 Node oldCursorParent = domContext.getCursorParent(); 513 while (uiList.isRowAvailable()) { 514 if ((numberOfRowsToDisplay > 0) && 515 (countOfRowsDisplayed >= numberOfRowsToDisplay)) { 516 break; 517 } 518 Iterator childs; 519 childs = columns.getChildren().iterator(); 520 Element td = domContext.createElement(HTML.TD_ELEM); 521 if (width != null) { 522 523 td.setAttribute("style", 524 "width:" + width + ";overfolw:hidden;"); 525 } 526 domContext.setCursorParent(oldCursorParent); 527 tr.appendChild(td); 528 while (childs.hasNext()) { 529 UIComponent nextChild = (UIComponent) childs.next(); 530 if (nextChild.isRendered()) { 531 domContext.setCursorParent(td); 532 writeColStyles(columnStyles, columnStylesMaxIndex, 533 columnStyleIndex, td, colNumber++, 534 columns.getParent()); 535 if (++columnStyleIndex > columnStylesMaxIndex) { 536 columnStyleIndex = 0; 537 } 538 encodeParentAndChildren(facesContext, nextChild); 539 domContext.setCursorParent(oldCursorParent); 540 } 541 } 542 rowIndex++; 543 countOfRowsDisplayed++; 544 uiList.setRowIndex(rowIndex); 545 } 546 ((HtmlDataTable) uiList.getParent()).setColNumber(colNumber); 547 uiList.setRowIndex(-1); 548 } 549 550 protected List getRenderedChildColumnsList(UIComponent component) { 551 List results = new ArrayList(); 552 Iterator kids = component.getChildren().iterator(); 553 while (kids.hasNext()) { 554 UIComponent kid = (UIComponent) kids.next(); 555 if (((kid instanceof UIColumn) && kid.isRendered()) || 556 kid instanceof UIColumns) { 557 results.add(kid); 558 } 559 } 560 return results; 561 } 562 563 protected boolean childColumnHasFacetWithName(UIComponent component, 564 String facetName) { 565 Iterator childColumns = getRenderedChildColumnsIterator(component); 566 while (childColumns.hasNext()) { 567 UIComponent nextChildColumn = (UIComponent) childColumns.next(); 568 if (getFacetByName(nextChildColumn, facetName) != null) { 569 return true; 570 } 571 } 572 return false; 573 } 574 575 public static String getSelectedRowParameterName(String dataTableId) { 576 int i = dataTableId.lastIndexOf(":"); 578 dataTableId = dataTableId.substring(0, i); 579 return dataTableId + SELECTED_ROWS; 580 } 581 582 583 public static RowSelector getRowSelector(UIComponent comp) { 584 if (comp instanceof RowSelector) { 585 return (RowSelector) comp; 586 } 587 Iterator iter = comp.getChildren().iterator(); 588 while (iter.hasNext()) { 589 UIComponent kid = (UIComponent) iter.next(); 590 if (kid instanceof HtmlDataTable){ 591 continue; 595 } 596 RowSelector rs = getRowSelector(kid); 597 if (rs != null) { 598 return rs; 599 } 600 } 601 return null; 602 } 603 604 private int rowSelectorNumber(FacesContext context){ 605 Map m = context.getExternalContext().getRequestMap(); 606 String key = RowSelector.class.getName() + "-Selector"; 607 Integer I = (Integer )m.get(key); 608 int i = 0; 609 if(I != null){ 610 i = I.intValue(); 611 i++; 612 } 613 614 I = new Integer (i); 615 m.put(key, I); 616 return i; 617 } 618 619 protected int getNumberOfChildColumns(UIComponent component) { 620 int size = getRenderedChildColumnsList(component).size(); 621 Iterator it = getRenderedChildColumnsList(component).iterator(); 622 while (it.hasNext()) { 623 UIComponent uiComponent = (UIComponent)it.next(); 624 if (uiComponent instanceof UIColumns) { 625 size +=((UIColumns)uiComponent).getRowCount(); 626 } 627 } 628 return size; 629 } 630 631 protected String [] getColumnStyleClasses(UIComponent uiComponent) { 632 String [] columnStyles = super.getColumnStyleClasses(uiComponent); 633 if (columnStyles.length == 0) { 634 columnStyles = new String [2]; 635 columnStyles[0] = Util.getQualifiedStyleClass(uiComponent, 636 CSS_DEFAULT.TABLE_COLUMN_CLASS1); 637 columnStyles[1] = Util.getQualifiedStyleClass(uiComponent, 638 CSS_DEFAULT.TABLE_COLUMN_CLASS2); 639 } else { 640 for (int i=0; i < columnStyles.length; i++) { 641 columnStyles[i] = Util.getQualifiedStyleClass(uiComponent, 642 columnStyles[i], 643 CSS_DEFAULT.TABLE_COLUMN_CLASS, 644 "columnClasses" 645 ); 646 } 647 } 648 return columnStyles; 649 } 650 651 public String [] getRowStyleClasses(UIComponent uiComponent) { 652 String [] rowClasses = super.getRowStyleClasses(uiComponent); 653 for (int i=0; i < rowClasses.length; i++) { 654 rowClasses[i] = Util.getQualifiedStyleClass(uiComponent, 655 rowClasses[i], 656 CSS_DEFAULT.TABLE_ROW_CLASS, 657 "rowClasses" 658 ); 659 } 660 return rowClasses; 661 } 662 663 public String [] getHeaderStyleClasses(UIComponent uiComponent) { 664 String [] headerClasses = getStyleClasses(uiComponent, "headerClasses"); 665 for (int i=0; i < headerClasses.length; i++) { 666 headerClasses[i] = Util.getQualifiedStyleClass(uiComponent, 667 headerClasses[i], 668 CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS, 669 "headerClasses" 670 ); 671 } 672 return headerClasses; 673 } 674 675 676 } 677 | Popular Tags |