Stephane, it seems we're both working on the same problem. I just today posted a similar question. And like yours, it seems my question was far too vague, as I received not one reply yet... Let's see if we can help each other.
As I stated in my question, I've found this (http://www.developer.com/java/ejb/article.php/2233591) article that describes a solution to our problem. I however could not get it to work using arrays either. Once I replaced in the form definition, in the action and in the jsp the array by java.util.List it does work. I don't see any reason to favor arrays over Lists, so this should probably help you too. I however want to take it up one level higher, I want the dynamic form to go into a tile. i.e. I don't want my data stored in session any more. But first let me see if I can help you by giving you my code. my form definition (from struts-config.xml): <form-beans> <form-bean name="searchForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="table" type="java.lang.String" /> <form-property name="criteria" type="java.util.List" /> <form-property name="columns" type="java.util.List" /> <form-property name="results" type="java.util.List" /> </form-bean> .... I'm creating a generic search form that I can use for all my apps entities; table receives the name of the set of search criteria and criteria receives the criteria themselves. Like in your case, this list contains the entities with the properties repeated in the form. My bean (i'll leave out the getters and setters as these do not add anything to the story): /* * Created on 6-apr-2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package nl.krew.va.search; import java.io.Serializable; /** * CriteriumLine bean for holding exactly one criterium in the search form. * * @author Richard * */ public class CriteriumLine implements Serializable { /** * The key for the label to show in front of this criterium. */ private String label = null; /** * The name of the property that this criterium checks against. */ private String property = null; /** * A code for the operator to use in the check. i.e. something like * EQ for equal, GT for greater than etc. */ private String operator = null; /** * Place holder for the values to check the property against as * entered by the end user. */ private Object[] values = null; ..... (left off the rest) And now the trick part, as I've taken it of James' article: In the action mappings I defined 2 actions. The first that calls my first action SearchAction and then forwards into a view (in my case a tile definition, search.page, but this eventually evaluates to searchTile.jsp), the second that calls the second action ListAction which tries to actually retrieve the results and pass them, together with the criteria to the search.page again. As you can see I'm trying to be clever with the wildcard mapping, but that doesn't work as I want it to do yet either :(. <action-mappings> <!-- Entry point for the search pages. Instantiates the DynaActionForm searchForm, fills the table property (from the first part of the url used) and expands and initializes the criteria array according to what is needed for that table. --> <action path="/*Search" type="nl.krew.va.actions.SearchAction" parameter="{1}" name="searchForm"> <forward name="success" path="search.page" /> </action> <!-- Post target for search.page. Lists, if possible, the results of the search. Redirects back into the search form otherwise --> <action path="/Search" type="nl.krew.va.actions.ListAction" name="searchForm" input="search.page"> <forward name="success" path="results.page" /> </action> .... Now, For the first action, SearchAction. What this does is to store the table name in the searchForm, then find the search criteria for that table (using business layer calls) and re-dimension the searchForm's criteria List by adding CriteriumLine entries. /* * Created on 6-apr-2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package nl.krew.va.actions; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import nl.krew.va.Constants; import nl.krew.va.search.CriteriumLine; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; /** * Retrieves the search conditions defined for the table specified in 'parameter'. Then passes the * found screen definition to the search view. * * @author Richard */ public class SearchAction extends Action { private static Log log = LogFactory.getLog(SearchAction.class); /* (non-Javadoc) * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMappi ng, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { if (log.isTraceEnabled()) log.trace("Entering SearchAction.execute."); DynaActionForm searchForm = (DynaActionForm) form; String table = mapping.getParameter(); searchForm.set( Constants.SEARCH_TABLE, table); // TODO: make BF call to retrieve CriteriumLines for the table. List criteria = new ArrayList(); criteria.add( new CriteriumLine("IncidentID")); criteria.add( new CriteriumLine("bla bla bla")); searchForm.set( Constants.SEARCH_CRITERIA, criteria); if (log.isInfoEnabled()) log.info( "Search on [" + table + "] has " + criteria.size() + " criteria."); if (log.isTraceEnabled()) log.trace("Leaving SearchAction.execute."); return mapping.findForward(Constants.FWD_SUCCESS); } } And the second action, ListAction. This takes the table plus the entered search criteria and performs the search. The results are then stored, together with a definition of the columns that should be shown to the end user, in the listForm. /** * Retrieves the search criteria from the searchForm and tries to get a list * of entities for the search results. * * @author Richard */ public class ListAction extends Action { private static Log log = LogFactory.getLog(ListAction.class); /* (non-Javadoc) * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMappi ng, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { log.trace("Entering ListAction.execute."); DynaActionForm listForm = (DynaActionForm) form; String table = listForm.getString( Constants.SEARCH_TABLE); List criteria = (List)listForm.get( Constants.SEARCH_CRITERIA); log.debug( "Creating result list for table [" + table + "]."); ListBF bf = new ListBF(); listForm.set( Constants.SEARCH_COLUMNS, bf.getListColumns( table)); listForm.set( Constants.SEARCH_RESULTS, bf.getList(table /* TODO: Add selection criteria.*/ )); log.trace( "Leaving SearchAction.execute."); return mapping.findForward( Constants.FWD_SUCCESS); } } Then, the view, as implemented in searchTile.jsp. This is far from finished, but the idea should be visible already. As an improvement over your version, this does not need the nb field, it just iterates over the number over entries in the list. <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%-- Search Tile This tile renders a form in which the user can enter selection criteria for the specified table. It takes as parameter the table and a list of criteria. Each item is a bean with following properties : label - key for the message to show in front of the criterium. property - name of the property to select on. operator - code for the comparison to perform. values - array of the values entered by the end user (dimension may vary upon the operator entered). @param table the table to render a search form for. @param criteria List of CriteriumLine beans. @param columns ignored. @param results ignored. --%> <%-- Push tiles attributes into page context --%> <tiles:importAttribute /> <logic:present name="title"> <em><tiles:getAsString name="title"/></em> </logic:present> <html:form action="/Search.do" > <html:hidden property="table"/> <table> <logic:iterate id="criterium" name="searchForm" property="criteria" type="nl.krew.va.search.CriteriumLine" indexId="indexId" > <tr> <td> <html:hidden name="criterium" property="property" indexed="true"/> <bean:write name="criterium" property="label"/> </td> <td> <html:text name="criterium" property="operator" indexed="true"/> </td> <td> <html:text name="criterium" property="values" indexed="true" /> </td> </tr> </logic:iterate> </table> <html:submit /> </html:form> The ListTile.jsp is not yet there yet. But it is just going to be more of what happened in searchTile.jsp. The problem I am now facing is that for this instance of the searchForm to still exist later on in the both .jsp's and the ListAction, the form needs to be stored into session scope. If I don't store it there, a new instance will be created upon every call and I will be given an empty List for criteria every time. However, since I want to make the pages into a tile I don't want the searchForm to go into session scope. I hope this does help you, Stephane. And of course, any suggestions are welcome (from anyone). Richard -----Oorspronkelijk bericht----- Van: Stéphane Zuckerman [mailto:[EMAIL PROTECTED] Verzonden: donderdag 7 april 2005 18:35 Aan: Struts Users Mailing List Onderwerp: Re: LazyLists and dynamic forms Niall Pemberton a écrit : > Its hard to help when all you say is "failed to make their examples work". > Posting snippets of relevant bits of your struts-config.xml, jsp etc would > help along with what actually happened. Sorry for the lack of details, I know I was really too vague. I am using Struts 1.2.4 . So, here is what I want to do : I have a list of text fields which number is unknown when the user gets to the JSP. Fields are added dynamically through JavaScript. Now, I know there is Struts 1.2.6 on its way, but I can't wait for it to get a "stable" label. So here is the example I was trying to follow (extracted from http://wiki.apache.org/struts/StrutsCatalogLazyList) : [quote] In fact using Arrays (rather than Lists) a LazyDynaBean can be used directly, in the following way: <form-beans> <form-bean name="skillForm" type="org.apache.commons.beanutils.LazyDynaBean"> <form-property name="skills" type="myPackage.SkillBean[]"/> </form-bean> </form-beans> [/quote] Supposedly, the LazyDynaBean object should be wrapped within a BeanValidatorForm one. Here is what I am using in my struts-config.xml file : <form-bean name="dynaLazyForm" type="org.apache.commons.beanutils.LazyDynaBean"> <form-property name="nb" type="java.lang.String" /> <form-property name="persons" type="net.beuarh.lasher.Person[]"/> </form-bean> The class Person is really just a bean, with deux properties : name and fname. Here is the JavaScript code I use to generate new text fields : function foo() { var nb = document.getElementById('nb').value; var f = document.getElementById('f'); f.innerHTML = null; f.innerHTML = "nb: "+ "<input type='text' id='nb' value='"+nb+"' /><br />"; for (var i = 0; i < nb; i++) { f.innerHTML += "name: <input type='text' " + "name='persons["+i+"].name' id='name' /><br />"; f.innerHTML += "first name:<input type='text' " + "name='persons["+i+"].fname' id='fname' /><br />"; } f.innerHTML += "<input type='submit' value='submit' />"; } The JSP is really basic (since this is a test) : <html> <head> <html:base/> <title>JSP for lazyForm form</title> <script src="js.js" language="javascript" type="text/javascript"></script> </head> <body> <html:errors/> <html:form action="/dynaLazy" styleId="f"> nb : <html:text property="nb" onblur="foo()" styleId="nb"/> <br /> <html:submit/> </html:form> </body> </html> ... And my Action class is as simple as the JSP : public final class DynaLazyAction extends Action { public ActionForward execute(...) { DynaValidatorForm dynaForm = (DynaValidatorForm) form; // here is the line that makes it all crumble... Person[] persons = (Person[]) dynaForm.get("persons"); request.setAttribute("persons",persons); return mapping.findForward("ok"); } } As I said before, when it is about "manual" forms, everything's fine, I use LazyLists, and it works (thank you so much, Rick; you made my morning wonderful :-) ). I hope I wasn't too messy in my explanations ... Thanks for any clue you might give me :-) -- Stéphane Zuckerman --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]