Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have <s:if> with two conditions in Struts 2

Tags:

jsp

struts2

ognl

I iterate through a list of items, and need to show a specific dropdown list if the state of element is equal to student or teacher. The following code shows all fields but does not show the dropdown for any of the elements!

 <s:iterator value="listOfPeople" status="element">
   .....
  <s:if test='%{elements[#element.index].Status.equalsIgnoreCase("Student") ||
          elements[#element.index].Status.equalsIgnoreCase("Teacher")}'>

            <s:select name="elements[%{#element.index}].Status"
                               id="elements[%{#element.index}].Status"
                               label="Status"
                               list="#{'Student':'Student','Teacher':'Teacher'}"
                               headerKey = "-1"
                               headerValue=" "
                               value="%{Status}"
             />

    </s:if>

In Controller:

    PeopleModel peopleModel = new PeopleModel();
    listOfPeople = peopleModel.findPeople();
    System.out.println("size is:" + listOfPeople.size());  //returns 8
    return "listPeople";

My Model:

    List<People> people = new ArrayList();
    final Session session = HibernateUtil.getSession();
    try {
        final Transaction tx = session.beginTransaction();
        try {

            Criteria criteria = session.createCriteria(People.class, "People")
            people.addAll((List<People>) criteria.list());
            if (!tx.wasCommitted()) {
                tx.commit();
            }
            if (session.isOpen()) {
                session.close();
            }
            System.out.println("size is ::: " + people.size());   //returns 8
            return people;

        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        }
    } finally {
        HibernateUtil.closeSession();
    }
    return null;
}

Result of the following code

   Status: ${Status}
   <br/>value : [<s:property value="elements[%{#element.index}].Status" />]
                       

is

Status : Principle
value : [] Status : Student
value : [] Status : Teacher
value : [] Status : Teacher
value : [] Status : Teacher
value : [] Status : Teacher
value : [] Status : Teacher
value : [] Status : Teacher
value : [] 

The above result is showing the first person's status separate to the other ones thats why the last value : [] is not showing any status.

If I take out Status: ${Status} the result would be

value : []
value : []
value : []
value : []
value : []
value : []
value : []
value : []
               
like image 224
AlexCartio1 Avatar asked Mar 11 '14 03:03

AlexCartio1


2 Answers

You don't need to have those conditions and if tag at all if you need to have the select tag being preselected on the Status you should provide valid keys. The headerKey = "-1" is invalid because it's not a String. Try headerKey = " ", the keys should not be empty. if the preselected value doesn't match the key the headerValue will be shown. For example

<s:iterator value="listOfPeople" status="element">    
  <s:select name="elements[%{#element.index}].Status"
           id="elements[%{#element.index}].Status"
           label="Status"
           list="#{'Student':'Student','Teacher':'Teacher'}"
           headerKey=" "
           headerValue=" "
           value="%{Status}"/>    
</s:iterator>
like image 24
Roman C Avatar answered Nov 11 '22 06:11

Roman C


Put %{} around the whole expression, not in the middle as in other attributes of other tags:

Also use a more appropriate equality function for Strings, like described here

<s:if test='%{elements[#element.index].status.equalsIgnoreCase("Student") ||
              elements[#element.index].status.equalsIgnoreCase("Teacher")}'>

EDIT: dude, you are doing a lot of odd things;

  1. ${Status} is JSP EL, you have no need of using it;
  2. You are iterating a source, and checking another source: printing <s:property value="elements[%{#element.index}].Status" /> gives you an empty result, and I can't see that elements thing anywhere in your code;
  3. the capital letter as first in an attribute is WRONG, because if the variable is named foo and the getter is getFoo(), in page you will have .foo, not .Foo. If your variable is named Foo, it is against the specs / best practices, let's start variables names with a lowercase letter.

Then If you have private Object Status, change it to private Object status;, along with the getter and the setter, and in page use:

<s:iterator value="listOfPeople" status="element">
    <s:if test='%{listOfPeople[#element.index].status.equalsIgnoreCase("Student") ||
                  listOfPeople[#element.index].status.equalsIgnoreCase("Teacher")}'>

or with a var

<s:iterator value="listOfPeople" status="element" var="row">
    <s:if test='%{row.status.equalsIgnoreCase("Student") ||
                  row.status.equalsIgnoreCase("Teacher")}'>

or simply

<s:iterator value="listOfPeople" status="element">
    <s:if test='%{status.equalsIgnoreCase("Student") ||
                  status.equalsIgnoreCase("Teacher")}'>

Strange code leads to weird results... then use it straight :)

like image 108
Andrea Ligios Avatar answered Nov 11 '22 05:11

Andrea Ligios