开发者

How to retain the dynamically generated form fields when the page reloads in struts2?

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.");
                        bre开发者_开发技巧ak;
                    }
                    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.


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.

  • http://struts.apache.org/2.0.14/docs/iterator.html
  • http://www.roseindia.net/struts/struts2/struts2controltags/iterator-tag.shtml
  • http://www.mkyong.com/struts2/struts-2-iterator-tag-example/


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜