Link to home
Start Free TrialLog in
Avatar of JianJunShen
JianJunShen

asked on

Very difficult question, collection or list manipulation in struts 2.

I have two collections, one is all possible choices(checkbox). The other is user's choices. Of course, user's choice is subset of all possbile choices. In push JSP scriptlet world, I could use
<foreach possbile choice>
   <if choice is among user's choice>
       <option value="xx"  selected or checked>
   <else>
       <option value="xx" selected="false">
<end of foreach>

How to do it in struts 2.0? Are there examples or documents?  
Avatar of valipotor
valipotor

<s:iterator value="possibleChoices">
<s:if test="#rowstatus.odd == true">
  <p>day is: <s:property/></p>
    </s:if>
    <s:else>
  <p>day is: <s:property/></p>
    </s:else>
</s:iterator>

ASKER CERTIFIED SOLUTION
Avatar of valipotor
valipotor

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of JianJunShen

ASKER

Hi, valipotor:
Please be a little bit patient. I am working on my small applications to verfiy it.

Ok, I think I have OGNL problem now. I followed your instuctions: And In my jsp page, I have:

<select name="cid" multiple="true">
    <s:iterator value="categories" status="category">           
        <s:if test = " 'category.id' in 'selectedCategories' ">
            <option value="<s:property value='#category.id'/>" selected>
                                                                         <s:property value="#category.name" /></option>
       </s:if>
       <s:else>
           <option value="<s:property value='#category.id'/>" > 
                                                                          <s:property value="#category.name" /></option>
      </s:else>
   </s:iterator>
</select>      

In my Action:
I have:

public class UpdateItemAction extends ActionSupport implements SessionAware{
     ...
                     List<Category> categories;
      List<String> cid;
      List<Category> selectedCategories;
    ...
                    public String input(){
            Long itemid = (Long) session.get("itemid");
            Item item = registrationService.getItem(itemid);
            setCategories(registrationService.listAllCategories());
            setSelectedCategories(item.getCategories());
            return INPUT;
      }
But the final html is as follows:
            <select name="cid" multiple="true">            
                  <option value="" > </option>
                 <option value="" > </option>
           </select>
I do have two categories. The loop count is correct. How to write JSP in my case?            

First of all, use the s:property in this way:

<s:property value='id'/>
Second,
The loop should look like:

<select name="cid" multiple="true">
    <s:iterator value="categories" var="current">  
         <s:if test = " #current in selectedCategories ">
            <option value="<s:property value='id'/>" selected>
                                                                       <s:property value="name" /></option>
       </s:if>
       <s:else>
           <option value="<s:property value='id'/>" >
                                                                          <s:property value="name" /></option>
      </s:else>
   </s:iterator>
</select>      

Your are right. Now it becomes
<select name="cid" multiple="true">
              <option value="1" > afd</option>
      <option value="2" > shoes</option>
</select>
It is much better. But it should select shoes. I am afraid
<s:if test = " 'category.id' in 'selectedCategories' "> is incorrect. I change it to
<s:if test = " 'category' in 'selectedCategories' ">, it does not work either.

selectedCategories is a member variable of Action. category is the instance from iterator.
What's correct way to check category is among selectedCategories?
As i posted above, change it to:

  <s:iterator value="categories" var="current">  
....
 <s:if test = " #current in selectedCategories ">
I followed your instructions,

<select name="cid" multiple="true">
   <s:iterator value="categories" var="category">           
       <s:if test = " #category in selectedCategories ">
             <option value="<s:property value='cid'/>" selected><s:property value="name" /></option>
       </s:if>
      <s:else>
           <option value="<s:property value='cid'/>" > <s:property value="name" /></option>
      </s:else>
   </s:iterator>
</select>      

It does not work either.
The html looks like as follows:

<select name="cid" multiple="true">      
     <option value="1" > afd</option>
    <option value="2" > shoes</option>
</select>

so s:if still wrong.
What does it show?
Sorry, I have a mistake there
<s:if test = " #category in selectedCategories ">, some extra spaces after ", should be <s:if test = "#category in selectedCategories">.
Very important, you should implement equals() and hashcode() methods for the Category object, otherwise the condition will return false all the time.
If you would like a demo implementation of the equals() and hashCode() methods, post the Category fields list (or the whole class)  and i should provide one for you.

Hi, first 'var' tag in iterator is not correct. I used status. It compiles at least. I removed empty space after quotation mark, but it still does not work.

Are hash and equals implemented?
valipotor:

Hash and equals are proper. I verified in following codes:
Output is

category name is shoes
catetory shoes is in selectedCategories

==================
public String input(){
  ....
  List<Category> temp = getSelectedCategories();
  List<Category> allCat = getCategories();
  for(int i=0;i<temp.size();i++){
    System.out.println("category name is "+temp.get(i).getName());
    if(temp.get(i).getParentCategory()!=null){
        System.out.println("category parent name is"+temp.get(i).getParentCategory().getName());
       }
  }
  for(int j=0;j<allCat.size();j++){
     Category cat = allCat.get(j);
     if(temp.contains(cat)){                     ----------------->contains, does it same as s:if's test?
        System.out.println("catetory "+cat.getName()+" is in selectedCategories");
    }
  }
  return INPUT;
}
I verified the codes that selectedCategories does contain category shoes. See above code for detail.:
   if(temp.contains(cat)){                    
        System.out.println("catetory "+cat.getName()+" is in selectedCategories");
   }
I tried the other way, I put <s:if test  against a session variable method.


The method is as follows:
public boolean isSelectedCategory(){
     return true;
}
In JSP: <s:if test ="%{#session.test.isSelectedCategory()}">
Then the result is expected.

But if I add an argument in the method:
public boolean isSelectedCategory(Category cat){
     return true;
}
In JSP: Whatever I try <s:if test ="%{#session.test.isSelectedCategory(#category)}">
or                               <s:if test ="%{#session.test.isSelectedCategory('#category')}">
The result is not expected.

Based on these tests, I am afraid the way to access category(See below extracted codes) is not correct. Am I right?
<select name="cid" multiple="true">
      <s:iterator value="categories" status="category"> --->How to refer category later on, #category des not work
          <s:if test ="%{#session.test.isSelectedCategory(#category)}">
              <option value="<s:property value='cid'/>" selected><s:property value="name" /></option>
          </s:if>
         <s:else>
            <option value="<s:property value='cid'/>" > <s:property value="name" /></option>
         </s:else>
    </s:iterator>
</select>       



As one could see my above comments, only after I add an argument, the result is not expected. There is obviously no problem in the java codes. But it is in JSP codes.
valipotor:

status attribute  in s:interator should be id. Otherwise, your answer is correct. Please modify it and post it again. 1) I could give you points since your answer is almost correct. 2) I could add this question to my knowledgebase. So please spend a little bit time to do it. Thanks.