【问题标题】:How to retain the dynamically generated form fields when the page reloads in struts2?struts2中页面重载时如何保留动态生成的表单域?
【发布时间】:2023-03-25 16:07:01
【问题描述】:

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

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

<%@ 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";
 }
}

你能建议我如何处理这种情况吗?

谢谢。

提前致谢。

【问题讨论】:

    标签: struts2


    【解决方案1】:

    这里要记住的主要事情是,当验证失败时,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>
    

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

    这里有一些更多信息的链接。

    【讨论】:

    • 感谢达斯汀的回复。抱歉格式不正确,这是我的第一篇文章,我只是复制并粘贴了代码并删除了多余的空格并将所有花括号移到单行中以减少长度。 “addComponent”不是一个列表,它是jsp中所有字段的所有字符串数组的POJO对象。我编辑了问题本身,因为我不知道如何再次发布剩余的代码,所以请再次参考问题并帮助我解决这个问题,或者通过我尝试实施的方式或建议我一个好方法。谢谢。
    • 好的,更新了我的回复以匹配您提供的信息。问题的格式现在看起来好多了,感谢您更新它。希望这会有所帮助!
    • 嗨达斯汀感谢更新。我按照您的建议尝试了,但仍然无法正常工作。如果我只在表单中输入您的代码,那么页面第一次加载时除了 3 个按钮之外什么都不会出现,但是当我尝试使用这两个代码时,第一次会出现一行,我可以在提交后添加多行,我可以得到这些多行额外的行填充了所有数据,如果我添加任何额外的行或尝试删除现有的行,它就不会发生。你能告诉我我在这里做错了什么吗?即使我尝试用 List 替换 String 数组,但得到了相同的结果。请帮我。谢谢!
    【解决方案2】:

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

    【讨论】:

    • 感谢anu的回复,至于我的要求,我需要尽可能避免客户端验证,所以我现在不选择它。如果我无法处理服务器端,那么我会接受你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多