You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Stephan Koops (JIRA)" <ji...@apache.org> on 2006/09/13 12:17:31 UTC

[jira] Commented: (STR-1249) [taglib] Problem to include a jsp into an iterate tag

    [ http://issues.apache.org/struts/browse/STR-1249?page=comments#action_38204 ] 
            
Stephan Koops commented on STR-1249:
------------------------------------

I've had the problem, that with <jsp:include page="/included.jsp" flush="true" /> nohing of the included jsp was validated (no <bean:write ... />, no <html:text /> and like this).
I used <%@ include file="/included.jsp" %> and it worked fine

> [taglib] Problem to include a jsp into an iterate tag
> -----------------------------------------------------
>
>                 Key: STR-1249
>                 URL: http://issues.apache.org/struts/browse/STR-1249
>             Project: Struts 1
>          Issue Type: Improvement
>          Components: Taglibs
>    Affects Versions: Future
>         Environment: Operating System: All
> Platform: All
>            Reporter: Freddy Lecerf
>         Assigned To: Struts Developers
>            Priority: Minor
>             Fix For: Future
>
>
> 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) :
> <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
> <%@taglib 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) :
> <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
> <%@taglib 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) :
> <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
> <%@taglib 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) :
> <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
> <%@taglib 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>

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira