How to implement a dynamic list with a JSF 2.0 Composite Component?

后端 未结 1 464
忘掉有多难
忘掉有多难 2020-11-27 05:26

I asked this question and although the answer directly satisfied my needs I am left with a feeling that there has to a simpler solution for this specific problem.

I

相关标签:
1条回答
  • 2020-11-27 05:36

    I'd use a <h:dataTable> in a composite component with a backing UIComponent which you can bind by componentType attribute of the <composite:interface>. In the backing UIComponent you can then maintain the DataModel and define the actions.

    dynamicFieldList.xhtml

    <ui:composition
        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"
    >
        <cc:interface componentType="dynamicFieldList">
            <cc:attribute name="value" type="java.util.List" required="true" />
        </cc:interface>
        <cc:implementation>
            <h:dataTable id="table" binding="#{cc.table}" value="#{cc.attrs.value}" var="field">
                <h:column><h:outputLabel value="#{field.label}" /></h:column>
                <h:column><h:inputText value="#{field.value}" /></h:column>
                <h:column><h:commandButton value="remove" action="#{cc.remove}" /></h:column>
            </h:dataTable>
            <h:commandButton value="add" action="#{cc.add}" />
        </cc:implementation>
    </ui:composition>
    

    (the <h:inputText> can if necessary be your composite field component)

    com.example.DynamicFieldList

    @FacesComponent(value="dynamicFieldList") // To be specified in componentType attribute.
    @SuppressWarnings({"rawtypes", "unchecked"}) // We don't care about the actual model item type anyway.
    public class DynamicFieldList extends UINamingContainer {
    
        private UIData table;
    
        public void add() {
            ((List) getAttributes().get("value")).add(new Field("somelabel"));
        }
    
        public void remove() {
            ((List) getAttributes().get("value")).remove(table.getRowData());
        }
    
        public UIData getTable() {
            return table;
        }
    
        public void setTable(UIData table) {
            this.table = table;
        }
    
    }
    

    Use it as follows:

    <h:form>
        <my:dynamicFieldList value="#{bean.fields}" />
    </h:form>
    

    with just this

    @ManagedBean
    @ViewScoped
    public class Bean implements Serializable {
    
        private List<Field> fields;
    
        public Bean() {
            fields = new ArrayList<>();
        }
    
        public List<Field> getFields() {
            return fields;
        }
    
    }
    

    and

    public class Field implements Serializable {
    
        private String label;
        private String value;
    
        public Field() {
            //
        }
    
        public Field(String label) {
            this.label = label;
        }
    
        public String getLabel() {
            return label;
        }
    
        public void setLabel(String label) {
            this.label = label;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题