如何在struts2中重新加载页面时保留动态生成的表单字段?

时间:2011-01-27 06:24:45

标签: struts2

我正在struts2中开发一个网页,其中页面将有一些输入字段的默认行以及“添加”,“删除”和“提交”按钮。当用户点击“添加”按钮时应生成一行输入字段,当单击“删除”按钮时,应删除不需要的字段行。我可以使用java脚本执行此操作,但在验证后页面重新加载时我遇到了问题。

当用户提交页面时,输入的值将在服务器端验证,如果输入值中的任何错误,当用户提交该表单时,它应与表单字段一起显示在同一页面上。但在我的情况下,当用户输入一些值并提交表单时,将验证值并且错误将显示在同一页面上,但所有字段值都在同一行而不是多行(如果有的话)。有关详细信息,请参阅代码段。

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<HTML>
<HEAD>
    <TITLE> Add Page</TITLE>
    <SCRIPT language="javascript">
        function addRow(tableID) {

            var table = document.getElementById(tableID);
            var rowCount = table.rows.length;
            var row = table.insertRow(rowCount);
            var colCount = table.rows[0].cells.length;

            for(var i=0; i<colCount; i++) {
                var newcell = row.insertCell(i);
                newcell.innerHTML = table.rows[0].cells[i].innerHTML;
                //alert(newcell.childNodes);
                switch(newcell.childNodes[0].type) {
                    case "text":
                            newcell.childNodes[0].value = "";
                            break;
                    case "checkbox":
                            newcell.childNodes[0].checked = false;
                            break;   }}}
        function deleteRow(tableID) {
            try {
            var table = document.getElementById(tableID);
            var rowCount = table.rows.length;
             var count=0;
            for(var i=0; i<rowCount; i++) {
                var row = table.rows[i];
                var chkbox = row.cells[0].childNodes[0];
                if(null != chkbox && true == chkbox.checked) {
                    count++;
                    if(rowCount <= 1) {
                        alert("Cannot delete all the rows.");
                        break;
                    }
                    table.deleteRow(i);
                    rowCount--;
                    i--;  }  }
            if(count==0)
            {
                alert("Please select the rows to be deleted !");
            }}catch(e) { alert(e);} }
    </SCRIPT>
</HEAD>
<BODY>
<s:if test="hasActionErrors()">
    <s:iterator value="actionErrors">
        <span class="errorMessage" style="padding-left: 160px;"><s:property escape="false" /> </span>
    </s:iterator>
</s:if>
<br />
<s:if test="hasActionMessages()">
    <s:iterator value="actionMessages">
        <span class="infoMessage" style="color: green; padding-left: 160px;"><s:property escape="false" /> </span>
    </s:iterator>
</s:if>
 <s:form method="post" theme="simple" action="addComponentDetails">
    <INPUT type="button" value="Add Row" onclick="addRow('dataTable')" />
    <INPUT type="button" value="Delete Row" onclick="deleteRow('dataTable')" />
 <table border="1">
 <tr><td ></td>
 <td ><s:text name="label.addComponent.partNumber" /></td>
 <td ><s:text name="label.addComponent.componentDescription" /></td>
 <td ><s:text name="label.addComponent.quantity" /></td>
 <td ><s:text name="label.addComponent.unitPrice" /></td>
 <td ><s:text name="label.addComponent.totalPrice" /></td>
 </tr>
 </table>
    <table id="dataTable" border="1">
        <tr>
        <td><s:checkbox name="test" id="chk" /></td>
            <td><s:textfield name="addComponent.partNumber" id="txt" /></td>
            <td><s:textfield name="addComponent.componentDescription" id="txt"/></td>
            <td><s:textfield name="addComponent.quantity" id="txt"/></td>
            <td><s:textfield name="addComponent.unitPrice" id="txt"/></td>
            <td><s:textfield name="addComponent.totalPrice" id="txt"/></td>
        </tr>
    </table>
    <s:submit name="submit" value="Add details"/>
 </s:form>
</BODY>
</HTML>

在上面的jsp中,addComponent是一个POJO对象。

POJO课程 -

public class SigmaAddComponent {

 private String partNumber[],componentDescription[],quantity[],unitPrice[],totalPrice[];

    //getters and setters for the above attributes.
}

动作类 -

 import com.bo.SigmaAddComponentBO;
    import com.exception.SigmaException;
    import com.opensymphony.xwork2.ActionSupport;
    import com.vo.SigmaAddComponent;

    public class SigmaAction extends ActionSupport
    {
 SigmaAddComponent addComponent = new SigmaAddComponent();

 //Getter and setter for addComponent

 public String addComponentDetails()
 {
  try
  {
   new SigmaAddComponentBO().validateDetails(addComponent);
  }
  catch (SigmaException se)
  {
    addActionError((se.getErrorMsg()));
  }
  return "success";
 }
}

你能否告诉我如何应对这种情况?

感谢。

提前致谢。

2 个答案:

答案 0 :(得分:2)

这里要记住的主要事情是,当验证失败时,struts只会渲染jsp页面,就像第一次进入页面时一样,只需填写表单字段。由于您的jsp页面只显示一行,因此表单在验证后重新生成后只有一行。

如果要显示所有行,则需要使用s:iterator标记来迭代保存的值。鉴于您只有一个addComponent实例,并且该对象的值是数组,您实际上需要迭代addComponent的一个属性,但是将表单字段的名称设置为完全限定的对象名称,包括数组索引。您可以使用迭代器状态对象来获取数组的索引。尝试使用以下内容代替上面的dataTable:

<table id="dataTable" border="1">
    <s:iterator value="addComponent.partNumber" status="componentStatus">
    <tr>
        <td><s:checkbox name="test" id="chk" /></td>
        <td><s:textfield name="addComponent.partNumber[%{#componentStatus.index}]" id="txt" /></td>
        <td><s:textfield name="addComponent.componentDescription[%{#componentStatus.index}]" id="txt"/></td>
        <td><s:textfield name="addComponent.quantity[%{#componentStatus.index}]" id="txt"/></td>
        <td><s:textfield name="addComponent.unitPrice[%{#componentStatus.index}]" id="txt"/></td>
        <td><s:textfield name="addComponent.totalPrice[%{#componentStatus.index}]" id="txt"/></td>
    </tr>
    </s:iterator>
</table>

如果这不起作用,您可以尝试稍微使用语法。使用迭代器绝对是最好的方法。

以下是一些更多信息的链接。

答案 1 :(得分:0)

我知道这不是一个很好的帮助,但尝试在客户端进行验证。我遇到了同样的问题,我实施了客户端验证。但