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

发布于 2024-10-14 05:17:05 字数 5076 浏览 0 评论 0原文

我正在 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";
 }
}

你能建议我如何应对这种情况吗?

谢谢。

提前致谢。

I am developing a web page in struts2,where the page will be having a default row of some input fields along with "add","delete" and "submit" button.When user click on "add" button a new row of input fields should be generated and when clicked on "delete" button unwanted row of fields should be deleted. I am able to do this with java script but I am facing a problem when the page reloads after validation.

When the user submits the page the values entered will be validated in the server side and if any errors in input values it should be displayed on the same page along with the form fields when the user submitted that form. But in my case when the user enters some value and submit the form ,values are validated and errors will be displayed on the same page but all the field values are coming in a same row instead of multiple rows if any. Please refer the code snippet for more details.

<%@ 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>

In the above jsp addComponent is a POJO object .

POJO class -

public class SigmaAddComponent {

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

    //getters and setters for the above attributes.
}

Action class -

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

Can you suggest me how can I go with this situation?

Thanks.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魂牵梦绕锁你心扉 2024-10-21 05:17:05

这里要记住的主要事情是,当验证失败时,struts 只是呈现 jsp 页面,就像您第一次进入页面时一样,只是表单字段已经填充。由于您的 jsp 页面仅显示一行,因此验证后重新生成的表单仅显示一行。

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

<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>

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

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

The main thing to remember here is that when validation fails, struts just renders the jsp page the same as it did when you first entered the page, just with the form fields already populated. Since your jsp page only displays one row, the form only has one row after it gets regenerated after validation.

If you want all the rows to show up, you will need to use an s:iterator tag, to iterate over the saved values. Given the fact that you only have one instance of addComponent, and the values of that object are the arrays, you actually need to iterate over one of the attributes of addComponent, but set the name of the form field to the fully qualified object name, including an array index. You use the iterator status object in order to get the index of the array. Try something like the following in place of your dataTable above:

<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>

If that does not work, you may try just playing around with the syntax a bit. Using an iterator is definitely the best way to go here.

Here are some more links for some more information.

小兔几 2024-10-21 05:17:05

我知道这不是一个很好的帮助,但尝试将您的验证转移到客户端。我面临着同样的问题,并且我实现了客户端验证。但是

I know it is not of a good help but try to move your validation on client side.I was facing the same problem and i implemeted client side validation.But

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文