12

placeholderコンポーネントの属性を処理するレンダラーを作成しようとしてい<h:inputText>ます。JSF 2.0を読んだ後、私はこのパスに向かいました。必要なHTML5属性を取り除き、それは正しいようです。これが私のカスタムレンダラーです

public class InputRenderer extends com.sun.faces.renderkit.html_basic.TextRenderer{

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) 
    throws IOException {
        System.out.println("Rendering :"+component.getClientId());

        String placeholder = (String)component.getAttributes().get("placeholder");
        if(placeholder != null) { 
            ResponseWriter writer = context.getResponseWriter();
            writer.writeAttribute("placeholder", placeholder, "placeholder");
        }

        super.encodeBegin(context, component);

    }


    @Override
    public void decode(FacesContext context, UIComponent component) {
        super.decode(context, component);
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) 
    throws IOException {
        super.encodeEnd(context, component);
    }
}

そして、このレンダラーは、facesconfigに次のように登録されます。

 <render-kit>
    <renderer>
        <component-family>javax.faces.Input</component-family>
        <renderer-type>javax.faces.Text</renderer-type>
        <renderer-class>com.example.renderer.InputRenderer</renderer-class>
    </renderer>
</render-kit>

これは問題なく登録され、問題はありません。

私の意図は、placeholder属性を処理して挿入し、処理をsuperに委任することです。間違った場所に属性を挿入しているため、上記のコードは機能しません。実行後に挿入する必要がありますwriter.startElement('input')。ただし、startElementはスーパーのencodeBegin()メソッドのどこかで発生している必要があります。では、カスタム属性(この場合は「プレースホルダー」)を挿入してから実行フローを続行するにはどうすればよいですか?

注意:上記のコードはplaceholder属性を追加しますが、意図する入力コンポーネントには追加しません。入力の親に書き込みます(コンポーネント自体が実際にストリームに書き込まれる前に属性を書き込もうとしているため、属性を現在のコンポーネントに適用します)

4

3 に答える 3

21

これが私のやり方です。プレースホルダーとデータテーマの属性を追加しました。さらに属性を追加する場合は、その名前を属性配列に追加するだけです。

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

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

public class InputRender extends TextRenderer {

    @Override
    protected void getEndTextToRender(FacesContext context,
            UIComponent component,
            String currentValue)
     throws java.io.IOException{

        String [] attributes = {"placeholder","data-theme"};

        ResponseWriter writer = context.getResponseWriter();

        for(String attribute : attributes)
        {
            String value = (String)component.getAttributes().get(attribute);
            if(value != null) {                             
                writer.writeAttribute(attribute, value, attribute);
            }
        }

        super.getEndTextToRender(context, component, currentValue);

    }

}

これをfaces-config.xmlファイルに追加する必要があります。

 <render-kit>
    <renderer>
        <component-family>javax.faces.Input</component-family>
        <renderer-type>javax.faces.Text</renderer-type>
        <renderer-class>your.package.InputRenderer</renderer-class>
    </renderer>
</render-kit>
于 2012-07-10T15:14:18.740 に答える
7

ResponseWriters の startElement メソッドをオーバーライドするだけで、そのメソッドは 1 回だけ呼び出されてから、元の responsewriter オブジェクトに復元できます。

import javax.faces.context.*;
import java.io.IOException;

public class InputRenderer extends com.sun.faces.renderkit.html_basic.TextRenderer{

      // Put all of the attributes you want to render here...
      private static final String[] ATTRIBUTES = {"required","placeholder"};

    @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.
    }



}
于 2011-10-25T08:59:30.373 に答える
3

そして、MyFaces 2.0.8+ をオーバーライドするには

package com.hsop.abc.eld;

import java.io.IOException;

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

import org.apache.myfaces.renderkit.html.HtmlTextRenderer;

public class InputRenderer extends HtmlTextRenderer
{
    @Override
    protected void renderInputBegin(FacesContext context, UIComponent component)
            throws IOException
    {
        // TODO Auto-generated method stub
        super.renderInputBegin(context, component);

    Object placeholder = component.getAttributes().get("placeholder");
    if(placeholder != null) { 
        ResponseWriter writer = context.getResponseWriter();
        writer.writeAttribute("placeholder", placeholder, "placeholder");
    }

    }
}
于 2013-12-13T05:36:08.593 に答える