Я пытаюсь создать повторно используемый компонент, который условно отображает соответствующий компонент ввода jsf на основе некоторых критериев. Я хочу отобразить тег h: inputText, если поле не содержит списка допустимых значений, или тег h: selectOneMenu, если указаны некоторые допустимые значения.
Я попытался установить привязку к переменной c: set и использовать переменную в нескольких тегах.
Я также пытался использовать обычный атрибут «value» вместо атрибута «binding».
@FacesComponent("extendedInput")
public class ExtendedInput extends UIInput implements NamingContainer {
// Fields -------------------------------------------------------------------------------------
private UIInput choice;
// Actions ------------------------------------------------------------------------------------
public ExtendedInput() {
}
@Override
public void decode(FacesContext context) {
super.decode(context);
}
/**
* Returns the component family of {@link UINamingContainer}.
* (that's just required by composite component)
*/
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
/**
* Set the selected and available values of the day, month and year fields based on the model.
*/
@Override
public void encodeBegin(FacesContext context) throws IOException {
setDisplayInputText(true);
setDisplaySelectOne(false);
//get map from session scoped bean.
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
PageOne page = (PageOne) viewMap.get("pageOne");
String attributeName = (String) getAttributes().get("fieldName");
AttributeMap attr = page.getFieldMap().get(attributeName);
String allowedValues = attr.getAllowedValues();
Map<String, String > selectOptions = new HashMap<String,String>();
if (allowedValues != null && !allowedValues.isEmpty()) {
setDisplayInputText(false);
setDisplaySelectOne(true);
String[] keyValString = allowedValues.split(";");
for (String valString : keyValString) {
String[] opt = valString.split("=");
selectOptions.put(opt[0], opt[1]);
}
}
setChoices(selectOptions);
String opt = getValue().toString();
choice.setValue(opt);
super.encodeBegin(context);
}
//... getter / setters
}
Моя проблема в том, что я не могу использовать одну и ту же привязку для обоих компонентов, указанных ниже, даже если не обе они отображаются одновременно.
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<cc:interface componentType="extendedInput">
<cc:attribute name="value" type="java.lang.Object"
shortDescription="value for bean property" />
<cc:attribute name="fieldName" type="java.lang.String" required="true"
shortDescription="name of the attribute we are working with" />
</cc:interface>
<cc:implementation>
<span id="#{cc.clientId}" style="white-space:nowrap">
<h:selectOneMenu id="day" rendered="#{cc.displaySelectOne}" binding="#{cc.choice}">
<f:selectItem itemLabel="Select One" itemValue="x" />
<f:selectItems value="#{cc.choices.entrySet()}" var="opt"
itemLabel="#{opt.value}" itemValue="#{opt.key}" />
</h:selectOneMenu>
<h:inputText id="normalInput" rendered="#{cc.displayInputText}" binding="#{cc.choice}"/>
</span>
</cc:implementation>
</ui:component>