001 package org.apache.myfaces.tobago.renderkit.html; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.lang.StringUtils; 021 import org.apache.commons.logging.Log; 022 import org.apache.commons.logging.LogFactory; 023 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_FOCUS; 024 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INLINE; 025 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INNER_HEIGHT; 026 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INNER_WIDTH; 027 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_HEIGHT; 028 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_WIDTH; 029 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE; 030 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_BODY; 031 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_HEADER; 032 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TIP; 033 import static org.apache.myfaces.tobago.TobagoConstants.FACET_LAYOUT; 034 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_OUT; 035 import org.apache.myfaces.tobago.component.ComponentUtil; 036 import org.apache.myfaces.tobago.component.SupportsMarkup; 037 import org.apache.myfaces.tobago.component.UICommand; 038 import org.apache.myfaces.tobago.component.UIData; 039 import org.apache.myfaces.tobago.component.UIPage; 040 import org.apache.myfaces.tobago.context.ResourceManagerUtil; 041 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey; 042 import org.apache.myfaces.tobago.renderkit.LayoutInformationProvider; 043 import org.apache.myfaces.tobago.renderkit.LayoutableRendererBase; 044 import org.apache.myfaces.tobago.renderkit.RenderUtil; 045 import org.apache.myfaces.tobago.renderkit.RendererBaseWrapper; 046 import org.apache.myfaces.tobago.util.LayoutUtil; 047 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter; 048 import org.apache.myfaces.tobago.webapp.TobagoResponseWriterWrapper; 049 050 import javax.faces.component.NamingContainer; 051 import javax.faces.component.UIComponent; 052 import javax.faces.component.UIInput; 053 import javax.faces.context.FacesContext; 054 import javax.faces.context.ResponseWriter; 055 import javax.faces.model.SelectItem; 056 import javax.faces.model.SelectItemGroup; 057 import java.io.IOException; 058 import java.util.Arrays; 059 import java.util.List; 060 import java.util.Map; 061 import java.util.StringTokenizer; 062 063 /* 064 * User: weber 065 * Date: Jan 11, 2005 066 * Time: 4:59:36 PM 067 */ 068 public final class HtmlRendererUtil { 069 070 private static final Log LOG = LogFactory.getLog(HtmlRendererUtil.class); 071 072 private HtmlRendererUtil() { 073 // to prevent instantiation 074 } 075 076 public static void renderFocusId(FacesContext facesContext, UIComponent component) 077 throws IOException { 078 079 if (ComponentUtil.getBooleanAttribute(component, ATTR_FOCUS)) { 080 UIPage page = ComponentUtil.findPage(facesContext, component); 081 String id = component.getClientId(facesContext); 082 if (!StringUtils.isBlank(page.getFocusId()) && !page.getFocusId().equals(id)) { 083 LOG.warn("page focusId = \"" + page.getFocusId() + "\" ignoring new value \"" 084 + id + "\""); 085 } else { 086 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 087 writer.writeJavascript("Tobago.focusId = '" + id + "';"); 088 } 089 } 090 } 091 092 public static void prepareRender(FacesContext facesContext, UIComponent component) { 093 // xxx find a better way for this question: isTobago or isLayoutable something like that. 094 LayoutableRendererBase layoutRendererBase = ComponentUtil.getRenderer(facesContext, component); 095 if (layoutRendererBase != null && !(layoutRendererBase instanceof RendererBaseWrapper)) { 096 createCssClass(facesContext, component); 097 layoutWidth(facesContext, component); 098 layoutHeight(facesContext, component); 099 } 100 } 101 102 public static HtmlStyleMap prepareInnerStyle(UIComponent component) { 103 HtmlStyleMap htmlStyleMap = new HtmlStyleMap(); 104 Integer innerSpaceInteger = (Integer) 105 component.getAttributes().get(ATTR_INNER_WIDTH); 106 if (innerSpaceInteger != null && innerSpaceInteger != -1) { 107 htmlStyleMap.put("width", innerSpaceInteger); 108 } 109 innerSpaceInteger = (Integer) 110 component.getAttributes().get(ATTR_INNER_HEIGHT); 111 if (innerSpaceInteger != null && innerSpaceInteger != -1) { 112 htmlStyleMap.put("height", innerSpaceInteger); 113 } 114 return htmlStyleMap; 115 } 116 117 118 public static void createCssClass(FacesContext facesContext, UIComponent component) { 119 String rendererName = getRendererName(facesContext, component); 120 if (rendererName != null) { 121 StyleClasses classes = StyleClasses.ensureStyleClasses(component); 122 classes.updateClassAttributeAndMarkup(component, rendererName); 123 } 124 } 125 126 public static String getRendererName(FacesContext facesContext, UIComponent component) { 127 final String rendererType = component.getRendererType(); 128 //final String family = component.getFamily(); 129 if (rendererType != null//&& !"facelets".equals(family) 130 ) { 131 LayoutableRendererBase layoutableRendererBase = ComponentUtil.getRenderer(facesContext, component); 132 if (layoutableRendererBase != null) { 133 return layoutableRendererBase.getRendererName(rendererType); 134 } 135 } 136 return null; 137 } 138 139 public static void writeLabelWithAccessKey(TobagoResponseWriter writer, LabelWithAccessKey label) 140 throws IOException { 141 int pos = label.getPos(); 142 String text = label.getText(); 143 if (pos == -1) { 144 writer.writeText(text); 145 } else { 146 writer.writeText(text.substring(0, pos)); 147 writer.startElement(HtmlConstants.U, null); 148 writer.writeText(Character.toString(text.charAt(pos))); 149 writer.endElement(HtmlConstants.U); 150 writer.writeText(text.substring(pos + 1)); 151 } 152 } 153 154 public static void setDefaultTransition(FacesContext facesContext, boolean transition) 155 throws IOException { 156 writeScriptLoader(facesContext, null, new String[]{"Tobago.transition = " + transition + ";"}); 157 } 158 159 public static void addClickAcceleratorKey( 160 FacesContext facesContext, String clientId, char key) 161 throws IOException { 162 addClickAcceleratorKey(facesContext, clientId, key, null); 163 } 164 165 public static void addClickAcceleratorKey( 166 FacesContext facesContext, String clientId, char key, String modifier) 167 throws IOException { 168 String str 169 = createOnclickAcceleratorKeyJsStatement(clientId, key, modifier); 170 writeScriptLoader(facesContext, null, new String[]{str}); 171 } 172 173 public static void addAcceleratorKey( 174 FacesContext facesContext, String func, char key) throws IOException { 175 addAcceleratorKey(facesContext, func, key, null); 176 } 177 178 public static void addAcceleratorKey( 179 FacesContext facesContext, String func, char key, String modifier) 180 throws IOException { 181 String str = createAcceleratorKeyJsStatement(func, key, modifier); 182 writeScriptLoader(facesContext, null, new String[]{str}); 183 } 184 185 public static String createOnclickAcceleratorKeyJsStatement( 186 String clientId, char key, String modifier) { 187 String func = "Tobago.clickOnElement('" + clientId + "');"; 188 return createAcceleratorKeyJsStatement(func, key, modifier); 189 } 190 191 public static String createAcceleratorKeyJsStatement( 192 String func, char key, String modifier) { 193 StringBuilder buffer = new StringBuilder(); 194 buffer.append("new Tobago.AcceleratorKey(function() {"); 195 buffer.append(func); 196 if (!func.endsWith(";")) { 197 buffer.append(';'); 198 } 199 buffer.append("}, \""); 200 buffer.append(key); 201 if (modifier != null) { 202 buffer.append("\", \""); 203 buffer.append(modifier); 204 } 205 buffer.append("\");"); 206 return buffer.toString(); 207 } 208 209 public static String getLayoutSpaceStyle(UIComponent component) { 210 StringBuilder sb = new StringBuilder(); 211 Integer space = LayoutUtil.getLayoutSpace(component, ATTR_LAYOUT_WIDTH, ATTR_LAYOUT_WIDTH); 212 if (space != null) { 213 sb.append(" width: "); 214 sb.append(space); 215 sb.append("px;"); 216 } 217 space = LayoutUtil.getLayoutSpace(component, ATTR_LAYOUT_HEIGHT, ATTR_LAYOUT_HEIGHT); 218 if (space != null) { 219 sb.append(" height: "); 220 sb.append(space); 221 sb.append("px;"); 222 } 223 return sb.toString(); 224 } 225 226 public static Integer getStyleAttributeIntValue(HtmlStyleMap style, String name) { 227 if (style == null) { 228 return null; 229 } 230 return style.getInt(name); 231 } 232 233 public static String getStyleAttributeValue(String style, String name) { 234 if (style == null) { 235 return null; 236 } 237 String value = null; 238 StringTokenizer st = new StringTokenizer(style, ";"); 239 while (st.hasMoreTokens()) { 240 String attribute = st.nextToken().trim(); 241 if (attribute.startsWith(name)) { 242 value = attribute.substring(attribute.indexOf(':') + 1).trim(); 243 } 244 } 245 return value; 246 } 247 248 249 public static void replaceStyleAttribute(UIComponent component, String styleAttribute, String value) { 250 HtmlStyleMap style = ensureStyleAttributeMap(component); 251 style.put(styleAttribute, value); 252 } 253 254 public static void replaceStyleAttribute(UIComponent component, String attribute, 255 String styleAttribute, String value) { 256 HtmlStyleMap style = ensureStyleAttributeMap(component, attribute); 257 style.put(styleAttribute, value); 258 } 259 260 public static void replaceStyleAttribute(UIComponent component, String styleAttribute, int value) { 261 HtmlStyleMap style = ensureStyleAttributeMap(component); 262 style.put(styleAttribute, value); 263 } 264 265 public static void replaceStyleAttribute(UIComponent component, String attribute, 266 String styleAttribute, int value) { 267 HtmlStyleMap style = ensureStyleAttributeMap(component, attribute); 268 style.put(styleAttribute, value); 269 270 } 271 272 private static HtmlStyleMap ensureStyleAttributeMap(UIComponent component) { 273 return ensureStyleAttributeMap(component, ATTR_STYLE); 274 } 275 276 private static HtmlStyleMap ensureStyleAttributeMap(UIComponent component, String attribute) { 277 final Map attributes = component.getAttributes(); 278 HtmlStyleMap style = (HtmlStyleMap) attributes.get(attribute); 279 if (style == null) { 280 style = new HtmlStyleMap(); 281 attributes.put(attribute, style); 282 } 283 return style; 284 } 285 286 public static String replaceStyleAttribute(String style, String name, 287 String value) { 288 style = removeStyleAttribute(style != null ? style : "", name); 289 return style + " " + name + ": " + value + ";"; 290 } 291 292 public static String removeStyleAttribute(String style, String name) { 293 if (style == null) { 294 return null; 295 } 296 String pattern = name + "\\s*?:[^;]*?;"; 297 return style.replaceAll(pattern, "").trim(); 298 } 299 300 public static void removeStyleAttribute(UIComponent component, String name) { 301 ensureStyleAttributeMap(component).remove(name); 302 } 303 304 /** 305 * @deprecated Please use StyleClasses.ensureStyleClasses(component).add(clazz); 306 */ 307 @Deprecated 308 public static void addCssClass(UIComponent component, String clazz) { 309 StyleClasses.ensureStyleClasses(component).addFullQualifiedClass(clazz); 310 } 311 312 public static void layoutWidth(FacesContext facesContext, UIComponent component) { 313 layoutSpace(facesContext, component, true); 314 } 315 316 public static void layoutHeight(FacesContext facesContext, UIComponent component) { 317 layoutSpace(facesContext, component, false); 318 } 319 320 public static void layoutSpace(FacesContext facesContext, UIComponent component, 321 boolean width) { 322 323 // prepare html 'style' attribute 324 Integer layoutSpace; 325 String layoutAttribute; 326 String styleAttribute; 327 if (width) { 328 layoutSpace = LayoutUtil.getLayoutWidth(component); 329 layoutAttribute = ATTR_LAYOUT_WIDTH; 330 styleAttribute = HtmlAttributes.WIDTH; 331 } else { 332 layoutSpace = LayoutUtil.getLayoutHeight(component); 333 layoutAttribute = ATTR_LAYOUT_HEIGHT; 334 styleAttribute = HtmlAttributes.HEIGHT; 335 } 336 int space = -1; 337 if (layoutSpace != null) { 338 space = layoutSpace.intValue(); 339 } 340 if (space == -1 && (!RENDERER_TYPE_OUT.equals(component.getRendererType()))) { 341 UIComponent parent = component.getParent(); 342 space = LayoutUtil.getInnerSpace(facesContext, parent, width); 343 if (space > 0 && !ComponentUtil.isFacetOf(component, parent)) { 344 component.getAttributes().put(layoutAttribute, Integer.valueOf(space)); 345 if (width) { 346 component.getAttributes().remove(ATTR_INNER_WIDTH); 347 } else { 348 component.getAttributes().remove(ATTR_INNER_HEIGHT); 349 } 350 } 351 } 352 if (space > 0) { 353 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, component); 354 if (layoutSpace != null 355 || !ComponentUtil.getBooleanAttribute(component, ATTR_INLINE)) { 356 int styleSpace = space; 357 if (renderer != null) { 358 if (width) { 359 styleSpace -= renderer.getComponentExtraWidth(facesContext, component); 360 } else { 361 styleSpace -= renderer.getComponentExtraHeight(facesContext, component); 362 } 363 } 364 365 replaceStyleAttribute(component, styleAttribute, styleSpace); 366 367 } 368 UIComponent layout = component.getFacet(FACET_LAYOUT); 369 if (layout != null) { 370 int layoutSpace2 = LayoutUtil.getInnerSpace(facesContext, component, 371 width); 372 if (layoutSpace2 > 0) { 373 layout.getAttributes().put(layoutAttribute, Integer.valueOf(layoutSpace2)); 374 } 375 } 376 } 377 } 378 379 public static void createHeaderAndBodyStyles(FacesContext facesContext, UIComponent component) { 380 createHeaderAndBodyStyles(facesContext, component, true); 381 createHeaderAndBodyStyles(facesContext, component, false); 382 } 383 384 public static void createHeaderAndBodyStyles(FacesContext facesContext, UIComponent component, boolean width) { 385 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, component); 386 HtmlStyleMap style = (HtmlStyleMap) component.getAttributes().get(ATTR_STYLE); 387 Integer styleSpace = null; 388 try { 389 styleSpace = style.getInt(width ? "width" : "height"); 390 } catch (Exception e) { 391 /* ignore */ 392 } 393 if (styleSpace != null) { 394 int bodySpace = 0; 395 int headerSpace = 0; 396 if (!width) { 397 if (renderer != null) { 398 headerSpace = renderer.getHeaderHeight(facesContext, component); 399 } 400 bodySpace = styleSpace - headerSpace; 401 } 402 HtmlStyleMap headerStyle = ensureStyleAttributeMap(component, ATTR_STYLE_HEADER); 403 HtmlStyleMap bodyStyle = ensureStyleAttributeMap(component, ATTR_STYLE_BODY); 404 if (width) { 405 headerStyle.put("width", styleSpace); 406 bodyStyle.put("width", styleSpace); 407 } else { 408 headerStyle.put("height", headerSpace); 409 bodyStyle.put("height", bodySpace); 410 } 411 } 412 } 413 414 /** 415 * @deprecated Please use StyleClasses.ensureStyleClasses(component).updateClassAttribute(renderer, component); 416 */ 417 @Deprecated 418 public static void updateClassAttribute(String cssClass, String rendererName, UIComponent component) { 419 throw new UnsupportedOperationException( 420 "Please use StyleClasses.ensureStyleClasses(component).updateClassAttribute(renderer, component)"); 421 } 422 423 /** 424 * @deprecated Please use StyleClasses.addMarkupClass() 425 */ 426 @Deprecated 427 public static void addMarkupClass(UIComponent component, String rendererName, 428 String subComponent, StringBuilder tobagoClass) { 429 throw new UnsupportedOperationException("Please use StyleClasses.addMarkupClass()"); 430 } 431 432 /** 433 * @deprecated Please use StyleClasses.addMarkupClass() 434 */ 435 @Deprecated 436 public static void addMarkupClass(UIComponent component, String rendererName, StyleClasses classes) { 437 classes.addMarkupClass(component, rendererName); 438 } 439 440 public static void addImageSources(FacesContext facesContext, TobagoResponseWriter writer, String src, String id) 441 throws IOException { 442 StringBuilder buffer = new StringBuilder(); 443 buffer.append("new Tobago.Image('"); 444 buffer.append(id); 445 buffer.append("','"); 446 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, src, false)); 447 buffer.append("','"); 448 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, createSrc(src, "Disabled"), true)); 449 buffer.append("','"); 450 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, createSrc(src, "Hover"), true)); 451 buffer.append("');"); 452 writer.writeJavascript(buffer.toString()); 453 } 454 455 public static String createSrc(String src, String ext) { 456 int dot = src.lastIndexOf('.'); 457 if (dot == -1) { 458 LOG.warn("Image src without extension: '" + src + "'"); 459 return src; 460 } else { 461 return src.substring(0, dot) + ext + src.substring(dot); 462 } 463 } 464 465 public static TobagoResponseWriter getTobagoResponseWriter(FacesContext facesContext) { 466 467 ResponseWriter writer = facesContext.getResponseWriter(); 468 if (writer instanceof TobagoResponseWriter) { 469 return (TobagoResponseWriter) writer; 470 } else { 471 return new TobagoResponseWriterWrapper(writer); 472 } 473 } 474 475 /** 476 * @deprecated use TobagoResponseWriter.writeJavascript() 477 */ 478 @Deprecated 479 public static void writeJavascript(ResponseWriter writer, String script) throws IOException { 480 startJavascript(writer); 481 writer.write(script); 482 endJavascript(writer); 483 } 484 485 /** 486 * @deprecated use TobagoResponseWriter.writeJavascript() 487 */ 488 @Deprecated 489 public static void startJavascript(ResponseWriter writer) throws IOException { 490 writer.startElement(HtmlConstants.SCRIPT, null); 491 writer.writeAttribute(HtmlAttributes.TYPE, "text/javascript", null); 492 writer.write("\n<!--\n"); 493 } 494 495 /** 496 * @deprecated use TobagoResponseWriter.writeJavascript() 497 */ 498 @Deprecated 499 public static void endJavascript(ResponseWriter writer) throws IOException { 500 writer.write("\n// -->\n"); 501 writer.endElement(HtmlConstants.SCRIPT); 502 } 503 504 public static void writeScriptLoader(FacesContext facesContext, String script) 505 throws IOException { 506 writeScriptLoader(facesContext, new String[]{script}, null); 507 } 508 509 public static void writeScriptLoader(FacesContext facesContext, String[] scripts, String[] afterLoadCmds) 510 throws IOException { 511 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 512 513 String allScripts = "[]"; 514 if (scripts != null) { 515 allScripts = ResourceManagerUtil.getScriptsAsJSArray(facesContext, scripts); 516 } 517 518 StringBuilder script = new StringBuilder(); 519 script.append("new Tobago.ScriptLoader(\n "); 520 script.append(allScripts); 521 522 if (afterLoadCmds != null && afterLoadCmds.length > 0) { 523 script.append(", \n"); 524 boolean first = true; 525 for (String afterLoadCmd : afterLoadCmds) { 526 String[] splittedStrings = StringUtils.split(afterLoadCmd, '\n'); // split on <CR> to have nicer JS 527 for (String splitted : splittedStrings) { 528 String cmd = StringUtils.replace(splitted, "\\", "\\\\"); 529 cmd = StringUtils.replace(cmd, "\"", "\\\""); 530 script.append(first ? " " : " + "); 531 script.append("\""); 532 script.append(cmd); 533 script.append("\"\n"); 534 first = false; 535 } 536 } 537 } 538 script.append(");"); 539 540 writer.writeJavascript(script.toString()); 541 } 542 543 public static void writeStyleLoader( 544 FacesContext facesContext, String[] styles) throws IOException { 545 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 546 547 StringBuilder builder = new StringBuilder(); 548 builder.append("Tobago.ensureStyleFiles(\n "); 549 builder.append(ResourceManagerUtil.getStylesAsJSArray(facesContext, styles)); 550 builder.append(");"); 551 writer.writeJavascript(builder.toString()); 552 } 553 554 public static String getTitleFromTipAndMessages(FacesContext facesContext, UIComponent component) { 555 String messages = ComponentUtil.getFacesMessageAsString(facesContext, component); 556 return HtmlRendererUtil.addTip(messages, component.getAttributes().get(ATTR_TIP)); 557 } 558 559 public static String addTip(String title, Object tip) { 560 if (tip != null) { 561 if (title != null && title.length() > 0) { 562 title += " :: "; 563 } else { 564 title = ""; 565 } 566 title += tip; 567 } 568 return title; 569 } 570 571 public static void renderSelectItems(UIInput component, List<SelectItem> items, Object[] values, 572 TobagoResponseWriter writer, FacesContext facesContext) throws IOException { 573 574 if (LOG.isDebugEnabled()) { 575 LOG.debug("value = '" + Arrays.toString(values) + "'"); 576 } 577 for (SelectItem item : items) { 578 if (item instanceof SelectItemGroup) { 579 writer.startElement(HtmlConstants.OPTGROUP, null); 580 writer.writeAttribute(HtmlAttributes.LABEL, item.getLabel(), true); 581 if (item.isDisabled()) { 582 writer.writeAttribute(HtmlAttributes.DISABLED, true); 583 } 584 SelectItem[] selectItems = ((SelectItemGroup) item).getSelectItems(); 585 renderSelectItems(component, Arrays.asList(selectItems), values, writer, facesContext); 586 writer.endElement(HtmlConstants.OPTGROUP); 587 } else { 588 writer.startElement(HtmlConstants.OPTION, null); 589 final Object itemValue = item.getValue(); 590 String formattedValue = RenderUtil.getFormattedValue(facesContext, component, itemValue); 591 writer.writeAttribute(HtmlAttributes.VALUE, formattedValue, true); 592 if (item instanceof org.apache.myfaces.tobago.model.SelectItem) { 593 String image = ((org.apache.myfaces.tobago.model.SelectItem) item).getImage(); 594 if (image != null) { 595 String imagePath = ResourceManagerUtil.getImageWithPath(facesContext, image); 596 writer.writeStyleAttribute("background-image=url('" + imagePath + "')"); 597 } 598 } 599 if (item instanceof SupportsMarkup) { 600 StyleClasses optionStyle = new StyleClasses(); 601 optionStyle.addMarkupClass((SupportsMarkup) item, getRendererName(facesContext, component), "option"); 602 writer.writeClassAttribute(optionStyle); 603 } 604 if (RenderUtil.contains(values, item.getValue())) { 605 writer.writeAttribute(HtmlAttributes.SELECTED, true); 606 } 607 if (item.isDisabled()) { 608 writer.writeAttribute(HtmlAttributes.DISABLED, true); 609 } 610 writer.writeText(item.getLabel()); 611 writer.endElement(HtmlConstants.OPTION); 612 } 613 } 614 } 615 616 public static String getComponentId(FacesContext context, UIComponent component, String componentId) { 617 UIComponent partiallyComponent = ComponentUtil.findComponent(component, componentId); 618 if (partiallyComponent != null) { 619 String clientId = partiallyComponent.getClientId(context); 620 if (partiallyComponent instanceof UIData) { 621 int rowIndex = ((UIData) partiallyComponent).getRowIndex(); 622 if (rowIndex >= 0 && clientId.endsWith(Integer.toString(rowIndex))) { 623 return clientId.substring(0, clientId.lastIndexOf(NamingContainer.SEPARATOR_CHAR)); 624 } 625 } 626 return clientId; 627 } 628 LOG.error("No Component found for id " + componentId); 629 return null; 630 } 631 632 public static String toStyleString(String key, Integer value) { 633 StringBuilder buf = new StringBuilder(); 634 buf.append(key); 635 buf.append(":"); 636 buf.append(value); 637 buf.append("px; "); 638 return buf.toString(); 639 } 640 641 public static String toStyleString(String key, String value) { 642 StringBuilder buf = new StringBuilder(); 643 buf.append(key); 644 buf.append(":"); 645 buf.append(value); 646 buf.append("; "); 647 return buf.toString(); 648 } 649 650 public static void renderTip(UIComponent component, TobagoResponseWriter writer) throws IOException { 651 Object objTip = component.getAttributes().get(ATTR_TIP); 652 if (objTip != null) { 653 writer.writeAttribute(HtmlAttributes.TITLE, String.valueOf(objTip), true); 654 } 655 } 656 657 public static void renderImageTip(UIComponent component, TobagoResponseWriter writer) throws IOException { 658 Object objTip = component.getAttributes().get(ATTR_TIP); 659 if (objTip != null) { 660 writer.writeAttribute(HtmlAttributes.ALT, String.valueOf(objTip), true); 661 } else { 662 writer.writeAttribute(HtmlAttributes.ALT, "", false); 663 } 664 } 665 666 public static String getJavascriptString(String str) { 667 if (str != null) { 668 return "\"" + str + "\""; 669 } 670 return null; 671 } 672 673 public static String getRenderedPartiallyJavascriptArray(FacesContext facesContext, UICommand command) { 674 if (command == null) { 675 return null; 676 } 677 String[] list = command.getRenderedPartially(); 678 StringBuilder strBuilder = new StringBuilder(); 679 strBuilder.append("["); 680 for (int i = 0; i < list.length; i++) { 681 if (i != 0) { 682 strBuilder.append(","); 683 } 684 strBuilder.append("\""); 685 strBuilder.append(HtmlRendererUtil.getComponentId(facesContext, command, list[i])); 686 strBuilder.append("\""); 687 } 688 strBuilder.append("]"); 689 return strBuilder.toString(); 690 } 691 692 public static String getJavascriptArray(String[] list) { 693 StringBuilder strBuilder = new StringBuilder(); 694 strBuilder.append("["); 695 for (int i = 0; i < list.length; i++) { 696 if (i != 0) { 697 strBuilder.append(","); 698 } 699 strBuilder.append("\""); 700 strBuilder.append(list[i]); 701 strBuilder.append("\""); 702 } 703 strBuilder.append("]"); 704 return strBuilder.toString(); 705 } 706 }