2017-04-16 61 views
0

我正在编写一个用于收集某些数据的应用程序。在这个应用程序中我可以创建一些字段。每个领域都有自己的名称和类型(单行文本,文本区域,单选按钮等)。如何通过JSF和PrimeFaces动态添加UI组件

因此,当用户打开页面时,应用程序会将所有字段呈现给他以收集数据。 动态创建的所有字段,以便我的应用程序将呈现哪些字段类型我不知道。

所以,我的问题,如何动态添加ui组件?例如我有selectOne菜单与字段类型的枚举。 当我选择,例如,“文本区域”我需要添加视图元素文本区域。

我尝试了一些,但它不起作用。

我的JSF页面:从我的托管bean

<h:form> 
       <p:panel id="panel" header="Create/Edit field" style="margin-bottom:10px;"> 
        <p:messages id="messages"/> 
        <h:panelGroup layout="block" styleClass="row"> 
         <h:panelGroup layout="block" styleClass="col-sm-4"> 
          <h:panelGrid columns="3" cellpadding="5"> 
           <h:outputLabel for="fieldName" value="Field name:"/> 
           <p:inputText id="fieldName" value="#{field.name}" required="true"/> 

           <p:outputLabel for="fieldType" value="Field type:"/> 
           <p:selectOneMenu id="fieldType" value="#{editFieldController.currentType}" 
               styleClass="selectpicker" style="width: 100%"> 
            <p:ajax listener="#{editFieldController.onSelectType}"/> 
            <f:selectItems value="#{editFieldController.types}"/> 
           </p:selectOneMenu> 
          </h:panelGrid> 
         </h:panelGroup> 
         <h:panelGroup layout="block" styleClass="col-sm-4"> 
          <h:panelGrid columns="2"> 
           <h:outputText value="Is Active: "/> 
           <p:selectBooleanCheckbox value="#{field.isActive}"/> 
           <h:outputText value="Is Required: "/> 
           <p:selectBooleanCheckbox value="#{field.isRequired}"/> 
          </h:panelGrid> 
         </h:panelGroup> 

         <h:panelGroup layout="block" styleClass="row"> 
          <h:panelGrid binding="#{editFieldController.dynamicGrid}"> 
          <h1> Its type info</h1> 
          </h:panelGrid> 
         </h:panelGroup> 
        </h:panelGroup> 
       </p:panel> 
       <p:commandButton value="Submit" update="panel"/> 
      </h:form> 

方法,它包含哪些元素我要补充视图逻辑:

public void onSelectType(){ 
    switch (currentType){ 
     case MULTI_LINE_TEXT: 
      Application app = FacesContext.getCurrentInstance().getApplication(); 
      if(dynamicGrid == null){ 
       dynamicGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE); 
      } 
      dynamicGrid.getChildren().add(new InputTextarea()); 
      break; 
     case SINGLE_LINE_TEXT: 
      System.out.println(); 
      break; 
     case RADIO_BUTTON: 
      break; 
    } 
} 

我试着调试和dynamicGrid儿童名单增量时我在selectOne菜单中选择“MULTI_LINE_TEXT”。但是,我认为我没有这个文本区域。对于动态表单

+0

对我来说,你需要更新p:ajax中的内容。例如update =“panel”或update =“@ form” –

+0

@Jaqen H'ghar谢谢,它的工作原理,但仅限于输入文本区域和输入文本。我试图添加收音机,复选框,日期和没有发生。面板儿童列表增加,但我没有看到广播,复选框和日期在视图。 我加了他们的像dynamicGrid.getChildren()。add(new SelectOneRadio()); – Darthoo

+0

@Jaqen H'ghar,小小的更新。我重新启动服务器,现在它工作。万分感谢 – Darthoo

回答

0

更声明性方法:

  • 创建至少包含输入窗口小部件类型
  • 简单field元数据对象经由视图豆或另一服务提供这些字段的元数据对象的列表
  • 使用p:repeat遍历这个列表
  • 每个输入控件类型把一个标签控件,对重复内
    • 将它们的rendered属性绑定到检查小部件类型的表达式,例如, #{field.type == 'TEXTAREA'}
    • 将输入小部件的value绑定到视图bean中的Map,例如, #{myView.fieldValues[field.id]}

根据动态的需要程度,可能还需要更新p:repeat如果字段改变。