【问题标题】:Struts2 - Dynamic form fields and database data retrievalStruts2 - 动态表单字段和数据库数据检索
【发布时间】:2012-02-01 02:06:54
【问题描述】:

我正在使用 Struts2 开发一个注册网络应用程序,需要一些指导。

背景:

在注册表单上,有一组五个表单域:1 个文本框和 4 个下拉选择框。这五个字段描述了一个人在教育环境中的主要位置:文本字段允许用户插入他们的职位,下拉菜单允许用户选择他们所属的学校、机构、部门和部门。下拉菜单使用存储在数据库中的选项进行初始化(在注册操作中,数组列表在显示表单之前使用这些值进行初始化)。例如:

<s:select emptyOption="true" key="school1.schoolId" list="schoolList" listKey="schoolId" listValue="schoolName" required="true" />

问题:

我需要为用户提供添加 X 个辅助职位的能力。在注册表单上,用户可以单击“添加另一个从属关系”按钮,并显示一组新的 5 个表单字段。这些字段也需要验证,并在用户单击表单的提交按钮时保存。

解决这个问题的最佳方法是什么?

到目前为止,我只为每个表单字段声明了数组列表,如下所示:

private List<String> jobTitles = new ArrayList<String>();
private List<School> schools = new ArrayList<School>();
private List<Institution> institutions = new ArrayList<Institution>();
private List<Department> departments = new ArrayList<Department>();
private List<Division> divisions = new ArrayList<Division>();

但我不知道如何进行。如何显示主要职位的前 5 个字段?如果我使用 Javascript 动态插入新的表单字段,如何使用存储在数据库中的选项初始化动态下拉菜单?如果页面重新加载,如何保留这些值?

任何帮助表示赞赏 - 谢谢!

【问题讨论】:

    标签: java javascript forms hibernate struts2


    【解决方案1】:

    您需要解决的基本问题是如何将请求参数的索引列表放入您的操作类中。这很简单,我认为您从创建Lists 的输入参数开始就走在了正确的轨道上。我找到了一些关于主题 here 的文档。基本上,您可以使用名称为 jobTitles[0]jobTitles[1] 的表单字段,这些字段将用于填充 jobTitles 列表。

    但是,我认为“从属关系”的概念值得拥有自己的一类:

    class UserAffiliation {
       private String title;
       private String schoolId;
       private String institutionId;
       private String departmentId;
       private String divisionId;
    
       // Make sure that there is a no-args constructor (default or explicit) for Struts to create instances. 
       // Add getters and setters
    }
    

    在你的动作类中:

       private List<UserAffiliation> affiliations;
       ...
       // getter and setter for affiliations
    

    足以捕获用户输入。

    您的 jsp 可能类似于:

    <form action=".." method="post">
      <div class="affiliation">
         <s:textfield name="affiliations[0].title"/>
         <s:select name="affiliations[0].schoolId" list="schools" listKey="schoolId" listValue="schoolName"/>
         ...
      </div>
    
      <s:if test="affiliations != null && affiliations.size > 1">
        <s:iterator value="affiliations" begin="1" status="status">
            <s:textfield name="affiliations[%{#status.index + 1}].title"/>
            <s:select name="affiliations[%{#status.index + 1}].schoolId" list="schools" listKey="schoolId" listValue="schoolName"/>
                ...
        </s:iterator>
      </s:if>
      ....
    </form>
    
    <div id="affilationTemplate" style="display:none;">
       <div class="affiliation">
          <s:textfield name="affiliations[__IDX__].title"/>
          <s:select name="affiliations[__IDX__].schoolId" list="schools" listKey="schoolId" listValue="schoolName"/>
       </div>
       ...
    </div>
    

    注意 div affilationTemplate。您可以使用 JS 获取此模板的 html,将 __IDX__ 替换为适当的索引,并在用户单击“添加另一个从属关系”按钮时附加到表单内容。这可以确保新添加的选择框预先填充了适当的值。

    迭代器块显示用户已提交的任何值(“主要从属关系”除外,它已显示在其上方)。

    注意:当然,如果可能的话,您应该尽量去掉重复的表单元素。我会尝试将它们提取到包含中。

    【讨论】:

    • 自从我的原始帖子(以及许多小时后)以来,我开始与您一样思考附属课程。谢谢你的例子!明天我会试一试,很可能会回来提供额外的反馈/cmets 和问题。感谢您迄今为止的帮助!
    • 太好了,这就是我要找的!谢谢!
    猜你喜欢
    • 2012-06-05
    • 2011-03-18
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 2011-07-04
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多