2016-10-21 3 views
0

use bootstrap with JSF 2.1으로 지정하려는 경우 가장 중요한 것은 데이터 토글 속성을 사용할 수 있다는 것입니다. h : inputText에 대한 구현이 정상적으로 작동합니다. 그러나 h : selectOneMenu를 사용하여 동일한 작업을 수행하려고하면 렌더러가 호출되지 않습니다 (startElement 메소드에 중단 점을 지정 함). I used a documentary approach을 사용하여 렌더러 유형 및 구성 요소 패밀리를 찾습니다.JSF에서 사용자 정의 MenuRenderer에 부트 스트랩 속성 추가

이것은 내 SelectRenderer.java입니다. 나는이 UPDATE 내가 내가 javax.faces을 변경

<div class="form-group"> 
    <h:outputLabel class="col-md-4 control-label" for="mySelect">my Label Select</h:outputLabel> 
    <div class="col-md-7"> 
     <h:selectOneMenu id="mySelect" name="mySelect" class="form-control" data-toggle='tooltip'> 
      <f:selectItem itemValue="0" itemLabel="Dummy Label 1" /> 
      <f:selectItem itemValue="1" itemLabel="Dummy Label 1" /> 
     </h:selectOneMenu > 
    </div> 
</div> 

내 얼굴-config.xml에 index.xhtml의

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"> 
    <render-kit> 
     <renderer> 
      <component-family>javax.faces.Input</component-family> 
      <renderer-type>javax.faces.Text</renderer-type> 
      <renderer-class>InputRenderer</renderer-class> 
     </renderer> 
     <renderer> 
      <component-family>javax.faces.SelectOne</component-family> 
      <renderer-type>javax.faces.Menu</renderer-type> 
      <renderer-class>SelectRenderer</renderer-class> 
     </renderer> 
    </render-kit> 
</faces-config> 

단편 참조 dilek's code

import com.sun.faces.renderkit.html_basic.TextRenderer; 

import java.io.IOException; 

import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.context.ResponseWriter; 
import javax.faces.context.ResponseWriterWrapper; 

/** 
* @link https://stackoverflow.com/a/7886942/4253946 
*/ 
public class InputRenderer extends com.sun.faces.renderkit.html_basic.TextRenderer { 

    private static final String[] ATTRIBUTES = { "data-toggle" }; 

    @Override 
    protected void getEndTextToRender(FacesContext context, UIComponent component, 
             String currentValue) throws IOException { 
     final ResponseWriter originalResponseWriter = context.getResponseWriter(); 
     context.setResponseWriter(new ResponseWriterWrapper() { 
      @Override 
      // As of JSF 1.2 this method is now public. 
      public ResponseWriter getWrapped() { 
       return originalResponseWriter; 
      } 

      @Override 
      public void startElement(String name, UIComponent component) throws IOException { 
       super.startElement(name, component); 
       if ("input".equals(name)) { 
        for (String attribute : ATTRIBUTES) { 
         Object value = component.getAttributes().get(attribute); 
         if (value != null) { 
          super.writeAttribute(attribute, value, attribute); 
         } 
        } 
       } 
      } 
     }); 
     super.getEndTextToRender(context, component, currentValue); 
     context.setResponseWriter(originalResponseWriter); // Restore original writer. 
    } 
} 

로했다 javax.faces.SelectOne 에의 입력입니다.

왜 속성이 렌더링 된 HTML에 전달되지 않습니까?

답변

0

UPDATE II - 답 - 나는 dilek's codeVladiator's code 사이의 혼합 방식을 선택했다. AditionalAttributesWritter라는 하나의 도우미 클래스 만 만들면됩니다. 또한, check out the code implementation.

import java.io.IOException; 

import javax.faces.component.UIComponent; 
import javax.faces.context.ResponseWriter; 
import javax.faces.context.ResponseWriterWrapper; 

/** 
* @link https://stackoverflow.com/a/7886942/4253946 
*/ 
public class AditionalAttributesWritter extends ResponseWriterWrapper { 
    private static final String[] ATTRIBUTES = { "data-toggle" }; 
    private ResponseWriter originalResponseWriter; 

    public AditionalAttributesWritter(ResponseWriter originalResponseWriter) { 
     super(); 
     this.originalResponseWriter = originalResponseWriter; 
    } 

    @Override 
    // As of JSF 1.2 this method is now public. 
    public ResponseWriter getWrapped() { 
     return originalResponseWriter; 
    } 

    @Override 
    public void startElement(String name, UIComponent component) throws IOException { 
     super.startElement(name, component); 
     for (String attribute : ATTRIBUTES) { 
      Object value = component.getAttributes().get(attribute); 
      if (value != null) { 
       super.writeAttribute(attribute, value, attribute); 
      } 
     } 
    } 
} 

하는 것이 좋습니다 마지막으로 SelectRenderer이

import com.sun.faces.renderkit.html_basic.MenuRenderer; 

import java.io.IOException; 

import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.context.ResponseWriter; 

/** 
* @link https://stackoverflow.com/questions/27324024/jsf-selectonemenu-extending-menurenderer-for-displaying-a-plain-text-when-there/27337240#27337240 
*/ 
public class SelectRenderer extends MenuRenderer { 
    @Override 
    protected void renderSelect(FacesContext context, UIComponent component) throws IOException { 
     final ResponseWriter originalResponseWriter = context.getResponseWriter(); 
     context.setResponseWriter(new AditionalAttributesWritter(originalResponseWriter)); 
     super.renderSelect(context, component); 
     context.setResponseWriter(originalResponseWriter); // Restore original writer. 
    } 
} 

비슷하고 작동합니다. 이 방법이 충분하지 않다고 생각하면 알려주십시오.