Struts2 - 动态表单字段和数据库数据检索

时间:2012-01-02 21:15:33

标签: java javascript forms hibernate struts2

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

背景:

在注册表单上,有一组五个表单字段: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动态插入新表单字段,如何使用存储在数据库中的选项初始化动态下拉菜单?如果重新加载页面,如何保留这些值?

感谢任何帮助 - 谢谢!

1 个答案:

答案 0 :(得分:1)

您需要解决的基本问题是如何将索引的请求参数列表添加到您的操作类中。这非常简单,我认为通过创建List输入参数开始,你走在正确的轨道上。我找到了关于这个主题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__替换为适当的索引,并在用户单击“添加其他联属关系”按钮时附加到表单内容。这样可以确保新添加的选择框预先填充了适当的值。

迭代器块显示用户已经提交的值(除了主要联属关系之外,已经显示在其上方)。

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