?
Solved

using forEach tags with <%=

Posted on 2005-02-27
33
Medium Priority
?
412 Views
Last Modified: 2013-11-24
I have the following code in my jsp:

                  <c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'>
                        <td align="center" valign="middle" class="row_normal">
                        <div><input name="<c:out value='${doctype.doctypeId}' />"
                              type="checkbox" value="checkbox"
                              checked="<%= modifyUserFormBean.getCheckedDoctypes().contains(doctype.getDoctypeId())%>" />
                        <c:out value='${doctype.doctypeName}' /></div>
                        </td>
                  </c:forEach>


In line that says modifyUserFormBean.getCheckedDoctypes().contains(doctype.getDoctypeId())%>"  I get a compilation exception on doctype: doctype cannot be resolved

I've tried different combinations of c: and c_rt: but to no avail.

Please help.
0
Comment
Question by:aturetsky
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 12
  • 7
  • +1
33 Comments
 
LVL 29

Expert Comment

by:bloodredsun
ID: 13418682
This is to do with scopes rather than the forEach tag. The scriptlet does not have access to the expression lanaguage variable "doctype"
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13418982
Does:

               <c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'>
                    <jsp:useBean id="doctype" class="CLASSOFDOCTYPEOBJECT"/>
                    <td align="center" valign="middle" class="row_normal">
                    <div><input name="<c:out value='${doctype.doctypeId}' />"
                         type="checkbox" value="checkbox"
                         checked="<%= modifyUserFormBean.getCheckedDoctypes().contains(doctype.getDoctypeId())%>" />
                    <c:out value='${doctype.doctypeName}' /></div>
                    </td>
               </c:forEach>

help?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13418989
(replace CLASSOFDOCTYPEOBJECT with the full classname that the "doctype" obejct represents :-)
0
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
LVL 1

Author Comment

by:aturetsky
ID: 13489446
Tim, I am sorry for the delayed response.  I ended up doing it differently before I received your message, so I kept putting off my response until I would get to try out your code.

Here's what i don't understand in your code.  Wouldn't <jsp:useBean id="doctype" class="somepackage.Doctype"/>
result in putting a blank bean of Doctype type into the session.  How, in your code, would it get populated with the contents of ${doctype}?  Would you not need a c:set?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13494267
>> How, in your code, would it get populated with the contents of ${doctype}?  Would you not need a c:set?

  <c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'>

defines a doctype object and stores it in the var called "doctype"

  <jsp:useBean id="doctype" class="CLASSOFDOCTYPEOBJECT"/>

gets this object, and defines it so that it can be used in your JSP scriptlet...

As far as I know anyway...  did you try the code?

Tim
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13497185
Tim,

Well, I tried running it, but it doesn't seem to work for a different reason - the doctype is of class Doctype, which for some reason is not being treated by the jsp compiler as a bean, so I get a "The value for the useBean class attribute com.talisen.workflow.model.Doctype is invalid" error , even though I made sure that the declaration and everything else is correct.  I'll included the code for that class on the very bottom, in case you can tell me offhand why this class is not being treated as a bean.

But in any case here's what I don't understand in your code:

You suggest that the line <jsp:useBean id="doctype" class="CLASSOFDOCTYPEOBJECT"/>  "gets this object."  Well, I didn't think that was true, and that it would instantiate a brand new bean of  that type, but just to be sure I did some research, and I think I am correct here:
According to http://java.sun.com/products/jsp/syntax/1.2/syntaxref1217.html,

"The <jsp:useBean> element locates or instantiates a JavaBeans component. <jsp:useBean> first attempts to locate an instance of the bean. If the bean does not exist, <jsp:useBean> instantiates it from a class or serialized template.

To locate or instantiate the bean, <jsp:useBean> takes the following steps, in this order:

   1. Attempts to locate a bean with the scope and name you specify.
   2. Defines an object reference variable with the name you specify.
   3. If it finds the bean, stores a reference to it in the variable. If you specified type, gives the bean that type.
   4. If it does not find the bean, instantiates it from the class you specify, storing a reference to it in the new variable. If the class name represents a serialized template, the bean is instantiated by java.beans.Beans.instantiate.
   5. If <jsp:useBean> has instantiated (rather than located) the bean, and if it has body tags or elements (between <jsp:useBean> and </jsp:useBean>), executes the body tags"

Now, l'll go through it in order.  Step 1 attempt would result in nothing, because the var doctype in <c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'> is invisible since it only has nested visibility (see bellsouthpwp.net/b/i/billsigg/jstl-quick-reference.pdf).  Therefore, after defining the object reference variable in Step 2, it would not go into Step 3, since such bean does not exist.   Rather, it would go into step 4 and instantiate a new one.  That means the value of the var from the loop will never get into that bean.

Am I wrong?

As promised here' s the code for the Doctype class - and I am increasing the point value.

package com.talisen.workflow.model;

import java.io.Serializable;

public class Doctype implements Serializable, Comparable {

      private Integer doctypeId = null;
      private String doctypeName;
      private String doctypeDesc;
      private String doctypeAbbr;
      private Status status;
    private int hashValue = 0;

    /**
     * @return Returns the doctypeDesc.
     */
    public String getDoctypeDesc()
    {
        return this.doctypeDesc;
    }
    /**
     * @param doctypeDesc The doctypeDesc to set.
     */
    public void setDoctypeDesc(String doctypeDesc)
    {
        this.doctypeDesc = doctypeDesc;
    }
    /**
     * @param doctypeId The doctypeId to set.
     */
    public void setDoctypeId(Integer doctypeId)
    {
        this.doctypeId = doctypeId;
    }
    /**
     * @param doctypeUsers The doctypeUsers to set.
     */

    /**
     * @return Returns the doctypeName.
     */
    public String getDoctypeName()
    {
        return this.doctypeName;
    }

      /**
       * No-arg constructor for JavaBean tools.
       */
      Doctype() {}

      /**
       * Simple constructor.
       */
      public Doctype(String name) {
            this.doctypeName = name;
      }
      public Doctype(Integer doctypeId) {
            this.doctypeId = doctypeId;
      }

      // ********************** Accessor Methods ********************** //

      public Integer getDoctypeId() { return doctypeId; }

      public void setDoctypeName(String name) { this.doctypeName = name; }


      // ********************** Common Methods ********************** //

      public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Doctype)) return false;

            final Doctype doctype = (Doctype) o;

            if (doctypeName != null ? !doctypeName.equals(doctype.doctypeName) : doctype.doctypeName != null) return false;

            return true;
      }

    public int hashCode()
    {
        if (this.hashValue == 0)
        {
            int result = 17;
            int userIdValue = this.getDoctypeId() == null ? 0 : this.getDoctypeId().hashCode();
            result = result * 37 + userIdValue;
            this.hashValue = result;
        }
        return this.hashValue;
    }

      public String toString() {
            return  "Doctype_Id ('" + getDoctypeId() + "'), " +
                        "Doctype_Name: '" + getDoctypeName() + "'";
      }

      public int compareTo(Object o) {
            if (o instanceof Doctype) {
                  return this.getDoctypeName().compareTo( ((Doctype)o).getDoctypeName() );
            }
            return 0;
      }

      // ********************** Business Methods ********************** //

      /**
       * @return Returns the doctypeAbbr.
       */
      public String getDoctypeAbbr() {
            return doctypeAbbr;
      }
      /**
       * @param doctypeAbbr The doctypeAbbr to set.
       */
      public void setDoctypeAbbr(String doctypeAbbr) {
            this.doctypeAbbr = doctypeAbbr;
      }
      /**
       * @return Returns the status.
       */
      public Status getStatus() {
            return status;
      }
      /**
       * @param status The status to set.
       */
      public void setStatus(Status status) {
            this.status = status;
      }
}
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13550023
Tim, I realize my previous posting might be too long to read, but could you at least please respond to this part of it, so I can go ahead and give you points.
-------------------
But in any case here's what I don't understand in your code:

You suggest that the line <jsp:useBean id="doctype" class="CLASSOFDOCTYPEOBJECT"/>  "gets this object."  Well, I didn't think that was true, and that it would instantiate a brand new bean of  that type, but just to be sure I did some research, and I think I am correct here:
According to http://java.sun.com/products/jsp/syntax/1.2/syntaxref1217.html,

"The <jsp:useBean> element locates or instantiates a JavaBeans component. <jsp:useBean> first attempts to locate an instance of the bean. If the bean does not exist, <jsp:useBean> instantiates it from a class or serialized template.

To locate or instantiate the bean, <jsp:useBean> takes the following steps, in this order:

   1. Attempts to locate a bean with the scope and name you specify.
   2. Defines an object reference variable with the name you specify.
   3. If it finds the bean, stores a reference to it in the variable. If you specified type, gives the bean that type.
   4. If it does not find the bean, instantiates it from the class you specify, storing a reference to it in the new variable. If the class name represents a serialized template, the bean is instantiated by java.beans.Beans.instantiate.
   5. If <jsp:useBean> has instantiated (rather than located) the bean, and if it has body tags or elements (between <jsp:useBean> and </jsp:useBean>), executes the body tags"

Now, l'll go through it in order.  Step 1 attempt would result in nothing, because the var doctype in <c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'> is invisible since it only has nested visibility (see bellsouthpwp.net/b/i/billsigg/jstl-quick-reference.pdf).  Therefore, after defining the object reference variable in Step 2, it would not go into Step 3, since such bean does not exist.   Rather, it would go into step 4 and instantiate a new one.  That means the value of the var from the loop will never get into that bean.

Am I wrong?
0
 
LVL 28

Expert Comment

by:rrz
ID: 13550202
>${modifyUserFormBean.doctypes}    
What type of collection is returned ?          rrz
0
 
LVL 28

Accepted Solution

by:
rrz earned 1400 total points
ID: 13550856
Try something like the following.       rrz

<c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'>
         <td align="center" valign="middle" class="row_normal">
         <div><input name="<c:out value='${doctype.doctypeId}' />"
                     type="checkbox" value="checkbox"
  <%
     com.talisen.workflow.model.Doctype  currentType  =  
                 (com.talisen.workflow.model.Doctype)pageContext.getAttribute("doctype");
     String checkValue =
            modifyUserFormBean.getCheckedDoctypes().contains(currentType.getDoctypeId());
  %>
                     checked="<%=checkValue%>" />
                    <c:out value='${doctype.doctypeName}' /></div>
                    </td>
               </c:forEach>
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13557696
thanks, rrz - well, I mean I ended up doing earlier in a similar way, except I had to put the attribute "doctype" into the request context.

How would your way work, however - that is, how can you, in the following line, expect the doctype to be an attribute in pageContext if you never put it there?

com.talisen.workflow.model.Doctype  currentType  =  
                 (com.talisen.workflow.model.Doctype)pageContext.getAttribute("doctype");
0
 
LVL 28

Expert Comment

by:rrz
ID: 13557808
>how can you, in the following line, expect the doctype to be an attribute in pageContext if you never put it there?            
you put it there with  
><c:forEach var='doctype'        
Please try the following page.     rrz  

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
<c:forEach items="1,2,3,4,5,6" var="current">
<%
  String current = (String)pageContext.getAttribute("current");
%>
<%=current%>
</c:forEach>
0
 
LVL 28

Expert Comment

by:rrz
ID: 13557834
I guess when it comes down to it having a scriptlet in a JSTL tag is an ugly solution.
Are you using JSP 2.0 ? If so then we can clean it up some.      rrz
0
 
LVL 28

Expert Comment

by:rrz
ID: 13557902
My solution is a variation of Tim's solution.
Right  ?  
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13558227
Cool.  Thanks.  You the man.
Before I reward points, I want to make sure that my problem with Tim's answer was justified.  That is, that using  <jsp:useBean id="doctype" class="CLASSOFDOCTYPEOBJECT"/> would not help since doctype was never instantiated as a bean, only as an attribute of the page context.  Is that accurate?
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13558316
Also, I just saw your response above.  Yes.  I am using 2.0.   I'd love to know how can we clean it up and not use scriplets.
0
 
LVL 28

Expert Comment

by:rrz
ID: 13559391
> I'd love to know how can we clean it up and not use scriplets.  
No, I didn't say that. I meant to say that we could get rid of  the display tags.
><c:out value='${doctype.doctypeName}' /></  
could be just  EL  
${doctype.doctypeName}  

>Is that accurate?  
I don't think so. But let's get Tim's response.    
I would try Tim's idea like below.      rrz    

<jsp:useBean id="doctype" class="com.talisen.workflow.model.Doctype"/>
<c:forEach var='doctype' items='${modifyUserFormBean.doctypes}'>
   <td align="center" valign="middle" class="row_normal">
   type="checkbox" value="checkbox"
   checked="<%= modifyUserFormBean.getCheckedDoctypes().contains(doctype.getDoctypeId())%>" />
   ${doctype.doctypeName}</div>
   </td>
</c:forEach>
0
 
LVL 28

Expert Comment

by:rrz
ID: 13559481
No, that won't work ( Tim please help ).
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13559726
Thanks for all this.  If I don't get the response from Tim today, I'll go ahead and reward the points, since I posted my question to him a while ago.  Speaking of EL ... I am posting a following question, that I am sure you can answer.  The link is below.

1) my development server supports 2.0, so to use EL syntax such as ${doctype.doctypeName} without the c:out, what should the taglib declaration look like, or do I not need a declaration
2) my production server (Sun Web Server 6.1) only supports 1.2, so I am just curious if I can EL-enable it by dropping in a jar or what not, or is that impossible?

The link for the question is http://www.experts-exchange.com/Web/Web_Languages/JSP/Q_21353601.html.
0
 
LVL 28

Expert Comment

by:rrz
ID: 13560151
1) El is part of JSP 2.0   nothing special is needed.  
2)No  
Wait for Tim's response before taking action here.           rrz    
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13560418
will do
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13563246
Hiya!  Sorry, I was at home, asleep ;-)

Whats the problem?  Didn't rrz's solution fix it?
0
 
LVL 28

Expert Comment

by:rrz
ID: 13566590
>Whats the problem?  
Just wondering if your use of useBean tag should work.         rrz
0
 
LVL 35

Assisted Solution

by:TimYates
TimYates earned 600 total points
ID: 13566701
I'm not sure if it will work inside a <c:forEach tag...

I know it works inside a <logic:iterate tag for Struts...

But I guess they are completely different :-(

Tim
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13567518
but even with logic:iterate it would only work for an iteration over a collection of bean objects, correct?  So if my doctype object is, for whatever reason, not classified as a bean (not sure why not in my case, but that's beside the point) it wouldn't work, right?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13567585
does it have an empty constructor?

if so, it should work as a bean...  (as long as it has getXXX methods for the parameters you want to read...
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13568429
Thanks.  Could be my problem is the fact that my empty constructor is not declared as public (as you can see in the code above).  I can't get to changing that code right just now to try it out, but what do you think?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 13568527
Sounds like it...  Beans need a public constructor with no args...

good luck with it!!

Tim
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13568595
Thanks, Tim.  I awarded most of the points to rrz since he gave a complete working solution.  However, I do appreciate the time you put in to answer my questions and for sharing your very helpful expertise.
0
 
LVL 28

Expert Comment

by:rrz
ID: 13568711
I spent some time trying Tim's idea.  This works  
-------------------------------------------------------------------
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
  ArrayList list = new ArrayList();
  list.add("joe");
  list.add("sue");
%>
<c:set var="list" value="<%=list%>"/>
<c:forEach items="${list}" var="person">
     <jsp:useBean id="person" class="java.lang.String"/>
     <%=person%>
</c:forEach>
-------------------------------------------------------------------
but you never answered my question  
>>${modifyUserFormBean.doctypes}    What type of collection is returned ?
If, you are returning a Map, then the current element is exposed as a java.util.Map.Entry  .  In that case we are "out of luck" because Entry is just an inerface.      
What do you think Tim ?
0
 
LVL 28

Expert Comment

by:rrz
ID: 13568742
<%@ page import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
  ArrayList list = new ArrayList();
  list.add("joe");
  list.add("sue");
%>
<c:set var="list" value="<%=list%>"/>
<c:forEach items="${list}" var="person">
     <jsp:useBean id="person" class="java.lang.String"/>
     <%=person%>
</c:forEach>
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13568859
I have modifyUserFormBean.doctypes as a Set<Doctype>  - I am using Java 1.5 in my development env, so it does typed collections.
So each element should be exposed as a Doctype, which I guess would be a bean once I append "public" modifier to the default constructor - (I didn't get to try that out yet.)

Thanks for all your time, rrz
0
 
LVL 1

Author Comment

by:aturetsky
ID: 13568937
So let me ask you, then.  If this (your code below) works and bean is anything with a public default constructor, then why would you need <c:set var="list" value="<%=list%>"/>.   If you can access it as an attribute of the pageContext, then why can you not do the same with useBean which would check all contexts for anything that has a public no-arg constructor.  (This is the opposite of what I was asking Tim before - I mean now I would almost think Tim's way should work)

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
<c:forEach items="1,2,3,4,5,6" var="current">
<%
  String current = (String)pageContext.getAttribute("current");
%>
<%=current%>
</c:forEach>
0
 
LVL 28

Expert Comment

by:rrz
ID: 13570518
>Tim's way should work)
I think so.    

>why would you need <c:set var="list" value="<%=list%>"/>.      
Please try the following page and ask question aferwards.  
As Tim has pointed out
the useBean tag is the bridge between the two. It creates both.         rrz        


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
  String scriptVar = "scripting variable";
%>
<c:set var="tag" value="set by tag"/>
Scoped variable can be ${tag}.<br/>
Unscoped variable is <%=scriptVar%>.<br/>
?${scriptVar} No, I can't see that.<br/>
<c:set var="scoped" value="<%=scriptVar%>"/>
Now, I can see the scoped ${scoped}.<br/>
0

Featured Post

Interactive Way of Training for the AWS CSA Exam

An interactive way of learning that will help you visualize core concepts so that you can be more effective when taking your AWS certification exam.  Built for students by a student to help them understand the concepts that they are being taught.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question