views:

61

answers:

2

Hi all I have (just like the rest) inherited some struts 1 code. I have had need to add a few more pages to this project.

What I cannot figure out is how to map several distinct but similarly natured input elements to my ActionForm.

Let me elaborate. I create a new <Input> element dynamically as the user inputs more and more items (I use the YUI autocomplete form element and for each entered input I add it as an input element to my form and draw a new YUI autocomplete - complex sounding, I know)

So... My form looks a bit like (... after some prettifying and some such...):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>My Cool App - Test Case Builder</title>  

        <link rel="stylesheet" type="text/css" href="../script/yui/fonts/fonts-min.css" />
        <link rel="stylesheet" type="text/css" href="../skins/myCoolApp/button/button.css" />
        <link rel="stylesheet" type="text/css" href="../script/yui/autocomplete/assets/skins/sam/autocomplete.css" />
        <link rel="stylesheet" type="text/css" media="screen" href="../skins/myCoolApp/testcase.css" />


        <!-- YUI JAVA SCRIPTS -->
        <script type="text/javascript" src="../script/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
        <script type="text/javascript" src="../script/yui/element/element-min.js"></script>
        <script type="text/javascript" src="../script/yui/button/button-min.js"></script>
        <script type="text/javascript" src="../script/yui/datasource/datasource-min.js"></script>
        <script type="text/javascript" src="../script/yui/autocomplete/autocomplete-min.js"></script>


        <!-- APP JAVA SCRIPTS -->
        <script type="text/javascript" src="../script/myCoolApp/myCoolApp.js" ></script>
        <script type="text/javascript" src="../script/myCoolApp/stack.js" ></script>
        <script type="text/javascript" src="../script/myCoolApp/testcase/testcase.js"></script>
        <script type="text/javascript" src="../script/myCoolApp/testcase/default-data.js" ></script>
        <script type="text/javascript" src="../script/myCoolApp/testcase/data-structs.js" ></script>
        <script type="text/javascript" src="../script/myCoolApp/testcase/ui-elements.js" ></script>


    </head>
    <body class="cf010">
        <div id="wrap">
            <div id="header">
                <div id="main-header">
                    COOL APP
                </div>                
            </div>
            <div id="main-body">
                <div id="content">
                    <div class="col main">
                        <div id="main">
                            <form method="post" id="testcaseForm" class="typea" action="">
                                <fieldset>
                                    <legend>Test Case Builder</legend>
                                    <div id="tk1" class="tabcontrol">
                                        <ul class="tabs">
                                            <li class="first active">
                                                <a href="#">
                                                    <span>General</span>
                                                </a>
                                            </li>
                                            <li class="last">
                                                <a href="#">
                                                    <span>Parameters</span>
                                                </a>
                                            </li>
                                        </ul>
                                        <div id="tab0" class="tc-panel">
                                            <dl class="cls9">
                                                <dt>
                                                    <label for="scenario">Choose Scenario:</label>
                                                </dt>
                                                <dd>
                                                    <input type="text" id="scenario" name="scenario" class="text" />
                                                    <span id="scenarioToggle"></span>
                                                    <div class="auto-complete" id="scenarioContainer"></div>
                                                </dd>
                                                <dt>
                                                    <label for="ruleID">Choose Rule ID:</label>
                                                </dt>
                                                <dd>
                                                    <input type="text" id="ruleID" name="ruleID" class="text" />
                                                    <span id="ruleIDToggle"></span>
                                                    <div class="auto-complete" id="ruleIDContainer"></div>
                                                </dd>
                                                <dt>
                                                    <label for="Test Case Name" accesskey="t"><span class="accesskey">T</span>est Case Name:</label>
                                                </dt>
                                                <dd>
                                                    <input type="text" id="testCaseName" name="testCaseName" class="text" />
                                                </dd>
                                            </dl>
                                        </div>
                                        <div id="tab1" class="tc-panel hidden">
                                            <div class="toolbar" id="action-bar">
                                                <ul>
                                                    <li class="first">
                                                       <a title="select all" href="#" id="btmSelectAll" class="button">
                                                           <span>select all</span>
                                                       </a>
                                                    </li>
                                                    <li>
                                                       <a title="remove row" href="#" id="btmRemove" class="button">
                                                           <span>remove row</span>
                                                       </a>
                                                    </li>
                                                    <li>
                                                       <a title="undo last" href="#" id="btmRollBack" class="button disabled">
                                                           <span>undo last</span>
                                                       </a>
                                                    </li>
                                                    <li class="last">
                                                       <a title="accept row" href="#" id="btmAccept" class="button disabled">
                                                           <span>accept row</span>
                                                       </a>
                                                    </li>
                                                </ul>
                                            </div>
                                            <div id="param.list" class="gridclip">
                                                <table id='param.list.tbl' class='grid modela' >
                                                    <caption>Test Case Summary</caption>
                                                    <col/><col/><col/>          
                                                    <thead>
                                                        <tr>
                                                            <th class='hl center first'>
                                                                <input class='grid-select-all' type='checkbox' />
                                                            <th>
                                                            <th scope='col'>Row</th>
                                                            <th scope='col'>Parameter</th>
                                                            <th scope='col' class='last'>Value</th>
                                                        </tr>
                                                    </thead>
                                                    <tfoot>
                                                        <tr>
                                                            <th scope='row'>Total</th>
                                                            <td colspan='3'>2 parameters as Test Case input</td>
                                                        </tr>
                                                    </tfoot>
                                                    <tbody id='param.list.tbl.body'>               
                                                        <tr class='odd'>
                                                            <td class='rowcheck center first'>
                                                                <input value='param1###value1' id='cb1' name='SelectedRows' class='grid-select-row' type='checkbox'/>
                                                            </td>
                                                            <td class='id'>1</td>
                                                            <td>param1</td>
                                                            <td class='last'>value1</td>
                                                        </tr>
                                                        <tr class='even'>
                                                            <td class='rowcheck center first'>
                                                                <input value='param2###value2' id='cb2' name='SelectedRows' class='grid-select-row' type='checkbox'/>
                                                            </td>
                                                            <td class='id'>2</td>
                                                            <td>param2</td>
                                                            <td class='last'>value2</td>
                                                        </tr>
                                                        <tr class='odd'>               
                                                            <td class='rowcheck center first' />
                                                            <td class='id'><em>new</em></td>
                                                            <td>
                                                                <dl class='clsTable'>
                                                                    <dt>
                                                                        <input type='text' id='param' name='param' class='text paramInput' />
                                                                    </dt>
                                                                    <dd>
                                                                        <span id='paramToggle' />
                                                                    </dd>
                                                                    <div class='auto-complete' id='paramContainer' />
                                                                </dl>
                                                            </td>
                                                            <td class='last'>
                                                                <dl class='clsTable'>
                                                                    <dt>
                                                                        <input type='text' id='value' name='value' class='text valueInput' />
                                                                    </dt>
                                                                </dl>
                                                            </td>
                                                        </tr>
                                                    </tbody>
                                                </table>
                                            </div>
                                         </div>
                                    </div> <!-- tabcontrol -->
                                </fieldset>
                                <div class="submit-box">
                                    <input type="submit" name="formRun" id="formRun" class="form-save"
                                        value="Execute" accesskey="x" title="Run: Press Alt + [Shift] + x" />
                                    <input type="submit" name="formSave" id="formSave"
                                        value="Save" accesskey="s" title="Save: Press Alt + [Shift] + s" />
                                    <input type="submit" name="formLoad" id="formLoad"
                                        value="Load" accesskey="l" title="Load: Press Alt + [Shift] + l" />
                                    <input type="submit" name="formCancel" id="formCancel" class="form-cancel"
                                        value="Cancel" accesskey="c"  title="Cancel: Press Alt + [Shift] + c" />
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

As you can see the following is pretty much a duplicate:

<tr class='odd'>
    <td class='rowcheck center first'>
        <input value='param1###value1' id='cb1' name='SelectedRows' class='grid-select-row' type='checkbox'/>
    </td>
    <td class='id'>1</td>
    <td>param1</td>
    <td class='last'>value1</td>
</tr>
<tr class='even'>
    <td class='rowcheck center first'>
        <input value='param2###value2' id='cb2' name='SelectedRows' class='grid-select-row' type='checkbox'/>
    </td>
    <td class='id'>2</td>
    <td>param2</td>
    <td class='last'>value2</td>
</tr>

The relevant part of my stuts-config.xml file is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"&gt;
<struts-config>
    <data-sources />
    <form-beans>
        <form-bean name="TestCaseForm"  type="com.blahblah.mycoolapp.forms.TestCaseForm" />
    </form-beans>
    <action-mappings>
        <action path="/pages/SaveTestCase" name="TestCaseForm"
            type="org.springframework.web.struts.DelegatingActionProxy" scope="request">
        </action>
    </action-mappings>
    <message-resources parameter="MessageResources" />
</struts-config>

I also use spring 2.56 (The relevant part being):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;

    <bean name="/pages/SaveTestCase" class="com.blahblah.mycoolapp.actions.TestCaseBuilderSaveAction" />

</beans>

My Java ActionForm class (from what I had learned off the net) is:

package com.blahblah.mycoolapp.forms;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts.action.ActionForm;

public class TestCaseForm extends ActionForm {

    private static final long serialVersionUID = 2352146257739099766L;

    private String scenario;
    private String ruleID;
    private String testCaseName;
    private List<String> SelectedRows = new ArrayList<String>() ;

    public String getScenario() {
        return scenario;
    }

    public void setScenario(String scenario) {
        this.scenario = scenario;
    }

    public String getRuleID() {
        return ruleID;
    }

    public void setRuleID(String ruleID) {
        this.ruleID = ruleID;
    }

    public String getTestCaseName() {
        return testCaseName;
    }

    public void setTestCaseName(String testCaseName) {
        this.testCaseName = testCaseName;
    }

    public List<String> getSelectedRows() {
        return SelectedRows;
    }

    public void setSelectedRows(int index, String value) {
        this.SelectedRows.add(value);
    }
}

The question is why do I get an empty SelectedRows in my TestCaseBuilderSave Action?

Thanks all who have the patience to read such a long question...

and (hopefully) thanks to all you potential saviors :)

EDIT 1:

Due to @ahiru's request I post my action class which - for the time being is just a stripped down. almost do nothing, class:

public class TestCaseBuilderSaveAction extends Action {


    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition","attachment;filename=superfish.xml");

        try
        {
           ServletOutputStream out = response.getOutputStream();

           String contentStr = "<Yaneeve>Has been here...</Yaneeve>";
           byte[] bytes = contentStr.getBytes();
           out.write(bytes, 0, bytes.length);
           out.flush();
           out.close();

        }catch(Exception e){
           e.printStackTrace();
      }

      return null;
    }
}
+1  A: 

I'm not a struts master or anything but can struts handle building a List out of the inputs? Would it rather be better to use an array of strings? Also have you tried adding a method in your form?

public void setSelectedRows(List<String> list) { SelectedRows = list;}

I think there is a way to define a indexed input in the struts config.

--update

Could you possibly post your action class where you are trying to get these values?

I know you said that the method above does not work but here is what works for me in a similar situation (I think). Sorry I can't find the exact code but here is what I remember:

-ActionForm

private String[] strings;

public void setStrings(String[] strings) { this.strings = strings;}
public String[] getStrings() { return strings; }

jsp/html/whatever

<input type="text" value="x" name="strings[]">
<input type="text" value="y" name="strings[]">
<input type="text" value="z" name="strings[]">

I'm also curious if spring and struts play together nicely (i've done no research on this)

Thanks, I have tried both things... neither the methods you suggest nor the array worked. As far as I am concerned it could be a List, an Array, a Map, a graph, whatever... as long as I get the data to the server using the ActionForm
Yaneeve
will give your array example another try...
Yaneeve
@ahiru: as for "I'm also curious if spring and struts play together nicely (i've done no research on this)" I have only integreated struts 1 with spring, not struts 2 but from my brief experience, the initial setup is a bit tricky but from then on it is (mostly) smooth sailing
Yaneeve
+1  A: 

It seems as if the problem had been that the checkboxes had not been 'checked'.

Only 'checked' checkboxes get their value transferred to the server...

One thing I wish to emphasize is that I had converted my code to be like what @ahiru suggested:

private String[] strings;

public void setStrings(String[] strings) { this.strings = strings;}
public String[] getStrings() { return strings; }
Yaneeve