DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17473>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17473 Problem to include a jsp into an iterate tag Summary: Problem to include a jsp into an iterate tag Product: Struts Version: 1.1 Beta 3 Platform: All OS/Version: All Status: NEW Severity: Major Priority: Other Component: Custom Tags AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] 2 problems have been identified for this type of inclusion : Let's start with a sample code : Here is a sample main jsp (main.jsp) : <[EMAIL PROTECTED] uri="/WEB-INF/struts-html.tld" prefix="html" %> <[EMAIL PROTECTED] uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:form method="post" action="/submit"> <html:iterate name="myForm" property="tab" id="tab" indexId ="index" scope="request"> <jsp:include page="/included.jsp" flush="true" /> </html:iterate> </html:form> Here is a sample included jsp (included.jsp) : <[EMAIL PROTECTED] uri="/WEB-INF/struts-html.tld" prefix="html" %> <[EMAIL PROTECTED] uri="/WEB-INF/struts-bean.tld" prefix="bean" %> Personne <bean:write name="index"><br> Nom <html:text name="tab" property="firstName" indexed="true" /><br> Prenom <html:text name="tab" property="lastName" indexed="true" /><br> The first problem is that in the included jsp, it is impossible to access to the differents properties given by each iteration : The error message is "cannot find bean index in any scope" One proposed solution is to use <bean:define> into the <logic:iterate> tag and to add the index bean and the tab bean in scope session instead of scope page. This solution doesn't seams to work : the error message is the same. Another solution could be to modify the doStartTag() and doAfterBody() method of the o.a.s.taglib.logic.IterateTag class to store the two bean in request instead of page context. My tested solution is to redefine the <logic:iterate> tag. I have created a <perso:iterate> tag with the class PersoIterateTag wich extends IterateTag, redefining his doStartTag() and doAfterBody() method : public doStartTag() throws JspException { int result = super.doStartTag(); if (result == EVAL_BODY_TAG) { Object o = pageContext.getAttribute(id); if (o == null) { pageContext.getRequest().removeAttribute(id); } else { pageContext.getRequest().setAttribute(id,o); } o = pageContext.getAttribute(indexId); if (o != null) { pageContext.getRequest().setAttribute(indexId,o); } } return result; } public doAfterBody() throws JspException { int result = super.doAfterBody(); if (result == EVAL_BODY_TAG) { Object o = pageContext.getAttribute(id); if (o == null) { pageContext.getRequest().removeAttribute(id); } else { pageContext.getRequest().setAttribute(id,o); } o = pageContext.getAttribute(indexId); if (o != null) { pageContext.getRequest().setAttribute(indexId,o); } } return result; } Modifying the first jsp (main.jsp) to use this tag, there is no problem for finding the bean anymore. But, here comes the second problem : the indexed property of tag <html:text> provides a way to generate a <html input="text"> type tag with a name property like "tab[0].firstName". To do this, when the indexed property is true into the <html:text> tag, the method prepareIndex() from o.a.s.taglib.html.BaseHanderTag class is called. But into this method the first operation consists in calling the findAncestorWithClass() method to get the instance of the IterateTag wich correspond to the <logic:iterate>. In this case the <logic:iterate> tag isn't in the same page than the <html:text> tag, and so an error message comes: "indexed="true" is only valid within an enclosing iterate tag" This problem seems to be a scope problem : the corresponding instance for <logic:iterate> is into the page scope, that's why the included jsp cannot recover his instance. One solution to fixe this problem can be to add two property to the <html:text> (and to similar tag) : * indexName : The name of the bean containing the current value of the index (in this exemple "index") * indexScope : The scope where this bean can be found. This properties could be added to the o.a.s.taglib.html.BaseHandlerTag class with the corresponding getter and setter method. On begining of the prepareIndex() method of this class, the following code could be added : protected void prepareIndex(StringBuffer handlers, String name) throws JspException { if (indexName != null) { Integer index = (Integer)RequestUtils.lookup (pageContext,indexName,indexScope); if (index == null) { JspException e = new JspException(messages.getMessage ("lookup.bean", indexName, indexScope)); RequestUtils.saveException(pageContext, e); throw e; } if (name != null) handlers.append(name); handlers.append("["); handlers.append(index); handlers.append("]"); if (name != null) handlers.append("."); return; } ... } On the end of the release() method of this class, the following code could be added : indexName = null; indexScope = null; Finally, the struts-html.tld file has to be modified, addding the following line to each tag wich can use it : <attribute> <name>indexName</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>indexScope</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> With this modification the folowing jsp code will now work : Here is the new main jsp (main.jsp) : <[EMAIL PROTECTED] uri="/WEB-INF/struts-html.tld" prefix="html" %> <[EMAIL PROTECTED] uri="/WEB-INF/struts-perso.tld" prefix="logic" %> <html:form method="post" action="/submit"> <logic:iterate name="myForm" property="tab" id="tab" indexId ="index" scope="request"> <jsp:include page="/included.jsp" flush="true" /> </logic:iterate> </html:form> Here is the new included jsp (included.jsp) : <[EMAIL PROTECTED] uri="/WEB-INF/struts-html.tld" prefix="html" %> <[EMAIL PROTECTED] uri="/WEB-INF/struts-bean.tld" prefix="bean" %> Personne <bean:write name="index"><br> Nom <html:text name="tab" property="firstName" indexName="index" indexScope="request" indexed="true" /><br> Prenom <html:text name="tab" property="lastName" indexName="index" indexScope="request" indexed="true" /><br> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]