Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struts2 dynamically add, remove list of objects from page

Tags:

struts2

I am trying to build a page on Struts2 that adds values to a database table. The problem is, the page must allow users to input several rows to the database table. When user clicks submit, it must read and write rows to the database table. Users can add or remove rows from page

Therefore I tried to render List value on page. Java code looks like this:

List<Testimate> estimates;
private String removeIndex;

public String execute() throws Exception {
    estimates = new ArrayList<Testimate>();
    for(int i = 0; i < INITIAL_ESTIMATES; i++)
        estimates.add(new Testimate());
    return INPUT;
}
public String add() {
    estimates.add(new Testimate());
    System.out.println(estimates.size());
    return INPUT;
}

public String remove() {
    estimates.remove(Integer.parseInt(getRemoveIndex()));
    System.out.println(estimates.size() + " " + getRemoveIndex());


    return INPUT;
    }   
And the page looks something like this:
<script>
   setRemoveIndex()
   {    
        $('input[name="removeIndex"]').val(removeIndex);
        return true;
   }
</script>
<s:form theme="custom" onsubmit="setRemoveIndex()">
<s:submit action="CEST02_add" cssClass="ButtonSmall" value="Add estimate" />
<s:hidden name="removeIndex"/>
<table>
<s:iterator value="estimates" var="estimate" status="status">
<tr>
   <td><s:textfield name="estimates[%{#status.index}].name"cssClass="product" /></td>
   <td><s:textfield name="estimates[%{#status.index}].price"cssClass="product" /></td>
   <td><s:textfield name="estimates[%{#status.index}].date"cssClass="product" /></td>
   <td><s:textfield name="estimates[%{#status.index}].attr"cssClass="product" /></td>
   <td><s:submit action="CEST02_remove" cssClass="ButtonSmall" value="Remove this estimate" onclick="removeIndex=%{#status.index}"/>
   </td>
</tr>
</s:iterator>
</table>
</s:form>

And when I click "Add estimate" it adds element to the list "estimates". And it prints the size correctly. But when I click "Remove this estimate", it does not change the list "estimates". But it prints that the size of list is reduced by one. And when I click again, the size does not change at all. It does not get any modification.

Can you please tell me what is wrong with this code. I may have some huge misunderstanding how this framework works. If you have any questions or clarifications, please just ask

UPDATE:

I solved my issue with following lines on my JSP. But question still remains why I could not do this on my Action.

<s:iterator value="estimates" var="estimate" status="status">
   <s:if test="#status.index != removeIndex">
like image 253
batbaatar Avatar asked Jan 18 '12 08:01

batbaatar


3 Answers

I tried with your code and its working fine for me.Though i do not understand the inner of your Testimate class so in place of List<Testimate> estimates i took List<String> estimates;.Here is my working code.

Action Class

List<String> estimates;
private int removeIndex;
//there getters and setters

public String execute() throws Exception
    {

        estimates = new ArrayList<String>();
        for(int i = 0; i < 5; i++){
            estimates.add(""+i);
        }
        return SUCCESS;
    }

    public String remove() {
        estimates.remove(getRemoveIndex());
        System.out.println(estimates.size() + " " + getRemoveIndex());
        return SUCCESS;
        }

JSP

<body>
  <script>
  function setRemoveIndex(val)
   {    
       alert(val);
       document.getElementById("removeIndex").value=val;
       //$('input[name="removeIndex"]').val(removeIndex);
       document.myform.action="remove.action";
       document.myform.submit();
        return true;
   }
</script>
<s:form theme="simple" id="myform" name="myform">
<s:submit action="CEST02_add" cssClass="ButtonSmall" value="Add estimate" />
<s:hidden name="removeIndex" id="removeIndex"/>
<table>
<s:iterator value="estimates" var="estimate" status="status">
<tr>
   <td><s:textfield name="estimates[%{#status.index}]"cssClass="product" /></td>
   <td>
   <s:submit action="remove" cssClass="ButtonSmall" value="Remove this estimate" onclick="return setRemoveIndex('%{#status.index}')"/>
   </td>
</tr>
</s:iterator>
</table>
</s:form>
</body>

Struts.xml

 <action name="remove" class="example.HelloWorld" method="remove">
     <result>/example/HelloWorld.jsp</result>
 </action>

This above code is perfectly deleting the List values and i have checked with page refreshing also and values are not getting back.

like image 116
Umesh Awasthi Avatar answered Nov 04 '22 23:11

Umesh Awasthi


Have you tried flushing your Hibernate session in remove() after you remove the item? I think your changes are not being commited.

like image 35
Bruno Silva Avatar answered Nov 04 '22 23:11

Bruno Silva


Please see the below code which works for me as expected:

Action Class

package com.mycompany;

import com.opensymphony.xwork2.ActionSupport;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author james
 */
public class EstimateAction extends ActionSupport {

    private List<Testimate> estimates;
    private String removeIndex;
    private static final int INITIAL_ESTIMATES = 10;

    public List<Testimate> getEstimates() {
        return estimates;
    }

    public void setEstimates(List<Testimate> estimates) {
        this.estimates = estimates;
    }

    public String getRemoveIndex() {
        return removeIndex;
    }

    public void setRemoveIndex(String removeIndex) {
        this.removeIndex = removeIndex;
    }

    public String execute() throws Exception {
        estimates = new ArrayList<Testimate>();
        for (int i = 0; i < INITIAL_ESTIMATES; i++) {
            estimates.add(new Testimate());
        }
        return INPUT;
    }

    public String add() {
        estimates.add(new Testimate());
        System.out.println(estimates.size());
        return INPUT;
    }

    public String remove() {
        estimates.remove(Integer.parseInt(getRemoveIndex()));
        System.out.println(estimates.size() + " " + getRemoveIndex());


        return INPUT;
    }
}

struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <!-- Configuration for the default package. -->
    <constant name="struts.devMode" value="true" />
    <package name="default" extends="struts-default">
        <action name="showEstimates" class="com.mycompany.EstimateAction">
            <result name="input">/estimatePage.jsp</result>
        </action>
        <action name="removeEstimates" class="com.mycompany.EstimateAction" method="remove">
            <result name="input">/estimatePage.jsp</result>
        </action>
    </package>
</struts>

estimatePage.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript">
            function setRemoveIndex(removeIndex)
            {
                document.myForm.action = "removeEstimates.action";    //First set the form to navigate to the specific action
                $('input[name="removeIndex"]').val(removeIndex);
                //alert("Here");
                document.myForm.submit();                             //Submit the form with the action attribute change
                return false;                                         //Cancel the form submission which was triggered earlier
            }
        </script>
    </head>
    <body>
        <s:form name="myForm" onsubmit="setRemoveIndex()">
            <s:submit action="add" cssClass="ButtonSmall" value="Add estimate" />
            <s:hidden name="removeIndex"/>
            <table>
                <s:iterator value="estimates" var="estimate" status="status">
                    <tr>
                        <td><s:textfield name="estimates[%{#status.index}].name"cssClass="product" /></td>
                        <td><s:textfield name="estimates[%{#status.index}].price"cssClass="product" /></td>
                        <td><s:textfield name="estimates[%{#status.index}].date"cssClass="product" /></td>
                        <td><s:textfield name="estimates[%{#status.index}].attr"cssClass="product" /></td>
                        <td><s:submit action="remove" cssClass="ButtonSmall" value="Remove this estimate" onclick="return setRemoveIndex(%{#status.index})"/>
                        </td>
                    </tr>
                </s:iterator>
            </table>
        </s:form>
    </body>
</html>
like image 1
James Jithin Avatar answered Nov 04 '22 21:11

James Jithin