जो समाधान मैंने पाया वह इनपुट रेंडरर के लिए एनकोड मार्कअप विधियों को विस्तार और पुन: कार्यान्वित करना था। मैं एक और सामान्य समाधान चाहता था, लेकिन प्राइमफेस स्रोत कोड को देखने के बाद, मैंने कस्टम गुण जोड़ने के लिए घटक प्रस्तुतकर्ताओं के लिए कोई सामान्य हुक नहीं देखा। मार्कर प्रतिपादन के encodeMarkup(FacesContext context, InputText inputText)
विधियों में लिखा गया है। यह कक्षा-पदानुक्रम को renderPassThruAttributes(FacesContext context, UIComponent component, String[] attributes)
पर कॉल करता है लेकिन यह केवल org.primefaces.util.HTML
से स्थिर अंतिम स्ट्रिंग [] सरणी में फ़ीड करता है।
मेरे मामले में मैं इनपुटमास्क, इनपुटटेक्स्ट, इनपुट टेक्स्टक्स्टा और पासवर्ड घटकों पर 'ऑटोफोकस' विशेषता के लिए समर्थन चाहता था। इसके अलावा, कार्यान्वयन प्रत्येक घटक के लिए समान है, इसलिए मैं इनपुटपुट घटक पर 'ऑटोफोकस' को लागू करने के माध्यम से चलूंगा, लेकिन यह स्पष्ट होना चाहिए कि इसे और अधिक विशेषताओं और अधिक घटकों का समर्थन करने के लिए कैसे बढ़ाया जा सकता है।
एक रेंडरर को विस्तार/ओवरराइड करने के लिए, आपको प्राइमफ़ेस स्रोत उपलब्ध होना होगा और एनकोडमार्क विधि को ढूंढना होगा और इसकी सामग्री कॉपी करना होगा।
protected void encodeMarkup(FacesContext context, InputText inputText) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = inputText.getClientId(context);
writer.startElement("input", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("name", clientId, null);
writer.writeAttribute("type", inputText.getType(), null);
String valueToRender = ComponentUtils.getValueToRender(context, inputText);
if(valueToRender != null) {
writer.writeAttribute("value", valueToRender , null);
}
renderPassThruAttributes(context, inputText, HTML.INPUT_TEXT_ATTRS);
if(inputText.isDisabled()) writer.writeAttribute("disabled", "disabled", null);
if(inputText.isReadonly()) writer.writeAttribute("readonly", "readonly", null);
if(inputText.getStyle() != null) writer.writeAttribute("style", inputText.getStyle(), null);
writer.writeAttribute("class", createStyleClass(inputText), "styleClass");
writer.endElement("input");
}
विस्तार/अपने स्वयं के साथ रेंडरर (महत्वपूर्ण कोड के लिए टिप्पणियों देखें) ओवरराइड करना:: यहाँ InputTextRenderer के लिए उदाहरण है
public class HTML5InputTextRenderer extends InputTextRenderer {
Logger log = Logger.getLogger(HTML5InputTextRenderer.class);
//Define your attributes to support here
private static final String[] html5_attributes = { "autofocus" };
protected void encodeMarkup(FacesContext context, InputText inputText) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = inputText.getClientId(context);
writer.startElement("input", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("name", clientId, null);
writer.writeAttribute("type", inputText.getType(), null);
String valueToRender = ComponentUtils.getValueToRender(context, inputText);
if (valueToRender != null) {
writer.writeAttribute("value", valueToRender, null);
}
renderPassThruAttributes(context, inputText, HTML.INPUT_TEXT_ATTRS);
//Make an extra call to renderPassThruAttributes with your own attributes array
renderPassThruAttributes(context, inputText, html5_attributes);
if (inputText.isDisabled())
writer.writeAttribute("disabled", "disabled", null);
if (inputText.isReadonly())
writer.writeAttribute("readonly", "readonly", null);
if (inputText.getStyle() != null)
writer.writeAttribute("style", inputText.getStyle(), null);
writer.writeAttribute("class", createStyleClass(inputText), "styleClass");
writer.endElement("input");
}
}
में प्रतिपादन ओवरराइड का विन्यास चेहरे-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
<!-- snip... -->
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.InputTextRenderer</renderer-type>
<renderer-class>com.mycompany.HTML5InputTextRenderer</renderer-class>
</renderer>
</render-kit>
<!-- snip... -->
</faces-config>
और यदि आपके पास वेब.एक्सएमएल में कॉन्फ़िगर किए गए चेहरे-कॉन्फ़िगर नहीं हैं, तो बस-इन-केस जोड़ें:
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>
/WEB-INF/faces-config.xml, /faces-config.xml
</param-value>
</context-param>
फिर कुछ मार्कअप में इस का उपयोग करने के लिए:
<p:inputText id="activateUserName" value="${someBean.userName}"
autofocus="on">
</p:inputText>
नोट: JSF विशेषता मानों की जरूरत नहीं है कि के साथ खुश नहीं है। जबकि एचटीएमएल 5 में ऑटोफोकस एक मान का उपयोग नहीं करता है, अगर कोई नहीं दिया जाता है तो जेएसएफ एक त्रुटि फेंक देगा, इसलिए इस तरह के गुण जोड़ने के दौरान कुछ फेंकने वाले मूल्य को परिभाषित करना सुनिश्चित करें।
बढ़िया, यह प्रति घटक समाधान की तुलना में काफी अच्छा लगता है। मुझे यकीन है कि विशिष्ट उपयोग के मामले किसी भी तरह से तर्क कर सकते हैं। अगर मुझे समय मिलता है तो मैं इसे आज़माउंगा क्योंकि ऐसा लगता है कि यह सभी घटकों को घर से बढ़ने से कहीं ज्यादा तेज होगा। – Rich
UIComponent # getCurrentComponent (FacesContext) हस्ताक्षर प्रतीत होता है, इसलिए स्टार्ट एलीमेंट विधि के संदर्भ में जो उपलब्ध नहीं है। मैंने आपके Omnifaces में देखा है कि आपने घटक का उपयोग किया है .getCurrentCompnent() जिसे संदर्भ की आवश्यकता नहीं है, हालांकि यह ओमनीफेस क्लास है जो केवल प्राइमफेस में उपलब्ध नहीं है। उस बिंदु पर मेरे लिए किसी भी घटक को ओवरराइड करना अधिक खतरनाक होगा जो प्रारंभ करने के लिए शून्य हो सकता है। क्या आप सुझाव देते हैं कि मैं ओमनीफेस में खींचूं या क्या कोई और तरीका है? – Rich
'घटक # getCurrentComponent()' फॉर्म OmniFaces सिर्फ 'UIComponent # getCurrentComponent() 'के लिए प्रतिनिधि हैं। अगर आपने इसका परीक्षण किया है या नहीं, तो आप इस बारे में स्पष्ट नहीं हैं, लेकिन यह मेरे लिए काम करता है। – BalusC