それとは異なるレンダラーを使用する特定のコンポーネントが必要な場合は<p:autoComplete>
、独自のファミリとコンポーネントタイプを使用してカスタムコンポーネントを作成することはできません。PrimeFaces AutoComplete
(およびそのレンダラー)を拡張するだけで、ボイラープレートコードを保存できます。
カスタムコンポーネントでは、これらの属性のゲッターを提供する必要があります。セッターを指定することもできます。これにより、ビュー側から常にデフォルト値をオーバーライドできます。それらのゲッター/セッターは、順番にに委任する必要がありStateHelper
ます。
属性には少しだけ問題がありx-webkit-*
ます。これ-
は、Java識別子の不正な文字です。したがって、標準のレンダラーはタグ属性名とまったく同じコンポーネントプロパティ名に依存しているため、ゲッター/セッターの名前を変更し、レンダラーを多少変更する必要があります。更新x-webkit-speech
:それはそのままレンダリングする必要があることを理解しています(したがって、ゲッター/セッターは必要x-webkit-grammer
ありません)。これは実際にはタイプミスx-webkit-grammar
です。
SiteSearch
コンポーネントは次のようになります。
@FacesComponent(SiteSearch.COMPONENT_TYPE)
public class SiteSearch extends AutoComplete {
public static final String COMPONENT_FAMILY = "com.example";
public static final String COMPONENT_TYPE = "com.example.SiteSearch";
private enum PropertyKeys {
grammar, onspeechchange, placeholder
}
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
@Override
public String getRendererType() {
return SiteSearchRenderer.RENDERER_TYPE;
}
public String getGrammar() {
return (String) getStateHelper().eval(PropertyKeys.grammar, "builtin:search");
}
public void setGrammar(String grammar) {
getStateHelper().put(PropertyKeys.grammar, grammar);
}
public String getOnspeechchange() {
return (String) getStateHelper().eval(PropertyKeys.onspeechchange, "submit()");
}
public void setOnspeechchange(String onspeechchange) {
getStateHelper().put(PropertyKeys.onspeechchange, onspeechchange);
}
public String getPlaceholder() {
return (String) getStateHelper().eval(PropertyKeys.placeholder, "Enter a Search Term");
}
public void setPlaceholder(String placeholder) {
getStateHelper().put(PropertyKeys.placeholder, placeholder);
}
}
ゲッターにはすべてのデフォルト値が指定されていることに注意してください。eval()
が返される場合はnull
、代わりにデフォルト値が返されます。また、属性名をある程度無効にして、レンダラーを適宜変更するだけで、将来の非Webkitブラウザーで再利用できるようにしました。
上記のコンポーネントのSiteSearchRenderer
レンダラーは次のようになります。
@FacesRenderer(
componentFamily=SiteSearch.COMPONENT_FAMILY,
rendererType=SiteSearchRenderer.RENDERER_TYPE
)
public class SiteSearchRenderer extends AutoCompleteRenderer {
public static final String RENDERER_TYPE = "com.example.SiteSearchRenderer";
@Override
protected void renderPassThruAttributes(FacesContext facesContext, UIComponent component, String[] attrs) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
writer.writeAttribute("x-webkit-speech", "x-webkit-speech", null);
writer.writeAttribute("x-webkit-grammar", component.getAttributes().get("grammar"), "grammar");
writer.writeAttribute("onwebkitspeechchange", component.getAttributes().get("onspeechchange"), "onspeechchange");
writer.writeAttribute("placeholder", component.getAttributes().get("placeholder"), "placeholder");
super.renderPassThruAttributes(facesContext, component, attrs);
}
}
ビューで使用するには、もちろんタグとして登録する必要があります。ファイルを作成し/WEB-INF/my.taglib.xml
ます。
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/ui</namespace>
<tag>
<tag-name>siteSearch</tag-name>
<component>
<component-type>com.example.SiteSearch</component-type>
<renderer-type>com.example.SiteSearchRenderer</renderer-type>
</component>
</tag>
</facelet-taglib>
これにはもう<renderer>
インは必要ないことに注意してください。faces-config.xml
アノテーションは、実際のカスタムコンポーネントでその@FacesRenderer
役割を果たします。したがって、前の質問に基づいて作成した<renderer>
エントリを削除します。faces-config.xml
次に、次のコンテキストパラメータでカスタムtaglibがあることをJSFに伝えますweb.xml
。
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
最後に、次のように使用できます。
<html ... xmlns:my="http://example.com/ui">
...
<my:siteSearch />
コンポーネントに設定されているデフォルトを上書きする追加の属性を指定することもできます。
<my:siteSearch grammar="builtin:language" onspeechchange="alert('peek-a-boo')" placeholder="Search" />
<attribute>
属性のIDEオートコンプリートの場合、の<tag>
宣言ですべてを個別に指定する必要がありますmy.taglib.xml
。