I have searched through for this logic pretty much everywhere but am sure I haven't done a great job and hence this question.
I have an Arraylist and it needs to be iterated and displayed in the following format
User1 User2 User3
User4 User5 User6
User7 User8 User9
I am able to do this using normal JSP scriptlets but not using JSTL. I have tried using JSTL but it skips a few entries from the list. Here is my code
<tr>
<c:forEach var="party" items="${partiesList}">
<c:set var="ctr" value="${ctr+1}" scope="page"/>
<c:choose>
<c:when test="${ctr le 3}">
<td>
<figure>
<img src="images/${party.avatarUrl}" onclick="showHide('','${party.screenName}')" class="avaimg" alt="${party.screenName}">
<figcaption><spring:message code="user.${party.screenName}" text="${party.screenName}"/></figcaption>
</figure>
</td>
</c:when>
<c:otherwise>
</tr>
<c:set var="ctr" value="0" scope="page"/>
</c:otherwise>
</c:choose>
</c:forEach>
Any help would be appreciated.
Thanks in advance
You can do this by using the varStatus attribute and the modulo operator (%).
<table>
<c:forEach var="party" items="${partiesList}" varStatus="status">
<c:if test="${status.index % 3 == 0}"><tr></c:if>
<td>${status.index}</td>
<c:if test="${status.index % 3 == 2}"></tr></c:if>
</c:forEach>
</table>
varStatus will return a LoopTagStatus object, where index is
The index of the current round of the iteration. If iteration is being performed over a subset of an underlying array, java.lang.Collection, or other type, the index returned is absolute with respect to the underlying collection. Indices are 0-based.
You can use the modulo operator to check if you need to start or close a new row.
A different approach would be just looping through the list, output it as an unnumbered list and use CSS to style it the way you want. That's how I would have solved it. An example of how your CSS could look:
ul.my-class { overflow: hidden; width: 600px; }
ul.my-class li { float: left; width: 200px; }
Related
I have a table in that each row have some information. In one of the rows, images are available and also they are clickable. I need to click one of the image which has dynamic id.
Please refer below source code
<tr id="tblRow_2">
<td height="25" colspan="8" style="border: none; text-align: right">
<input id="PPPayNow_0" type="image" src="/Client/images/paynowprepay.gif" onclick="pppayClick(0,35);"/>
<input id="PayNow_0" type="image" src="/Client/images/paynow.gif" onclick="payClick(0,35);" alt=""/>
</td>
<td></td>
<td id="paymentTotal_0" style="text-align:right; font-size:medium; font-weight:bold; color:Black; border:none"></td>
I have tried CSS selectors & x-path but no luck.
Presuming the onclick attribute values are constantly- they are js functions after all, so should be, this is how you can select the 1st input:
//td/input[starts-with(#onclick, "pppayClick")]
And this is for the 2nd:
//td/input[starts-with(#onclick, "payClick")]
You could do the same with the id attribute, if only the prefixes (the _0 part) change.
I solved this problem by using X-Path preceding siblings and x-path string functions for preceding Axes i.e. number string-length(string?) it returns the number of characters in the string . number string-length(string?) => this function I used for identifying input tag which will be enable after clicking checkbox.
solution is :
browser.useXpath().click('//*[#id="tableId"]/tbody/tr/td[3][string-length(text()) > 0]/preceding::td[2]/input[starts-with(#id, "PayNow")]');
I have a 2-dimensional array, which can be done like this (working code):
<c:forEach items="${dataArray}" var="row">
Subject id: ${row[0]}
</c:forEach>
But I want to add a condition; when I try this it does not display anything:
<c:forEach items="${dataArray}" var="row">
<c:choose>
<c:when test="${fn:containsIgnoreCase(${row[0]}, 'condtion1')}">
Subject id: ${row[0]}
</c:when>
</c:choose>
</c:forEach>
Have I got something wring in the test attribute that makes it always false?
I have 60 images and I want to place 3 images in a div each.
<c:forEach items="${images}" var="image" varStatus="imgCount">
<c:if test="${imgCount.count == 3 }">
<div class="${gridImage.displayposition}">
<img src="${imagePath}${gridImage.image}" />
</div>
</c:if>
</c:forEach>
Would this be the way to accomplish this?
The condition in your c:if will only be true once: when you're on the third item. You can use the mod or % operators in EL to handle the images in groups of three. Take care with the varStatus.count property - it's one-based rather than zero-based, so you'd access the next image in the array with ${images[imgCount.count]}.
<c:forEach items="${images}" var="image" varStatus="imgCount">
<c:if test="${(imgCount.count-1) mod 3 eq 0}">
<div class="${gridImage.displayposition}">
<img src="${imagePath}${image}/>
<img src="${imagePath}${images[imgCount.count]}/>
<img src="${imagePath}${images[imgCount.count+1]}/>
</div>
</c:if>
</c:forEach>
You could also use the step attribute of the forEach tag and eliminate the need for the if statement. Here, you only create a div every third item. The count, however, will still continue in the sequence of 1,2,3... (as opposed to 1,4,7...) so you need to multiply the index by three.
<c:forEach items="${images}" varStatus="imgCount" step="3">
<div class="${gridImage.displayposition}">
<img src="${imagePath}${images[3*(imgCount.count-1)]}"/>
<img src="${imagePath}${images[3*(imgCount.count-1) + 1]}"/>
<img src="${imagePath}${images[3*(imgCount.count-1) + 2]}"/>
</div>
</c:forEach>
I have a requirement where if status is 0 then add a css class active else add a css class active1 and for that I have done like the follow
<c:forEach items="${parentList}" var="test">
<c:choose>
<c:when test="${test[1] eq 0}">
<li><a href="#" class="active" value="${test[0].id}-${test[0].category}" id="${parent.id}" onclick="return getQuestions(this);" >
${test[0].name }</a></li>
</c:when>
<c:otherwise>
<li><a href="#" class="active1" value="${test[0].id}-${test[0].category}" id="${parent.id}" onclick="return getQuestions(this);" >
<img src="${pageContext.request.contextPath}/resources/ui_resources/img/checked.jpg" alt="" height="20" width="20"/>${test[0].name }</a></li>
</c:otherwise>
</c:choose>
</c:forEach>
Now my requirement if
${test[0].category} is client then add a button <button name="delete/>
so now 4 condtions arrise
if status is 0 and category is not client then add class active
if status is 0 and category is client then add class ="active" and
add button.
if status is not 0 category is client then add class="active1" and
add button
if status is not 0 and category is not client then only add
class="active".
So can any body please tell me how to use if loop inside if loop using jstl
Instead of a multitude of <c:choose /> use <c:if /> together with a <c:var /> to determine the class to use. You can also use a <:if /> for the button, this will require you to move the rendering of the image to the css.
The JSP would look something like this (from the top of my head).
<c:forEach items="${parentList}" var="test">
<c:set var="clazz" value="active" />
<c:if test="${test[1] ne 0 and test[0].category ne 'client'}">
<c:set var="clazz" value="active1" />
</c:if>
<li>
<a href="#" class="${clazz}" value="${test[0].id}-${test[0].category}" id="${parent.id}" onclick="return getQuestions(this);" > ${test[0].name }</a>
<c:if test="${test[0].category eq 'client'}"><button name="delete" /></c:if>
</li>
</c:forEach>
You would need something like the following to your css class active1
a.active1 {
background-image: url('/resources/ui_resources/img/checked.jpg');
background-repeat: no-repeat;
padding-left: 25px; /* width of the image plus a little extra padding */
display: block;
}
Based on your code block, how just add c:if tag after <c:choose> block?
<c:forEach ...>
<c:choose ...>
</c:choose>
<%-- here to check buuton add or not --%>
<c:if test="${test[0].category == 'client'}"><button name="delete" /></c:if>
</c:forEach
My HTML Code looks like this:
<html>
<body>
<div>
</div>
<div>
<table>
<tbody id=a>
<tr>
<td>
<div>
<span>
some Text
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text2
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text3
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
I'm trying to select each of the span elements by their text. I'm able to select the tbody by id. I Tried this:
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first <span> element in my table.
I also tried:
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single <span> element in my table, and I don't know why.
I also don't understand why
tbody.FindElement(By.XPath(String.Format(".//span[text() = {0})]", &var)));
throws an Element not found Exception, when the contain method returns a <span> element with just the same text.
I tried by using xpath as:
.//span[contains(text(),'some Text')]
it is selecting all the 3 span.
so to this i have refer to parent element.
for 1st span: .//tbody[#id='a']//tr[1]//span[contains(text(),'some Text')]
for 2nd: .//tbody[#id='a']//tr[2]//span[contains(text(),'some Text')]
for 3rd: .//tbody[#id='a']//tr[3]//span[contains(text(),'some Text')]
through this I can select every span element individually.
You could use the jQuery to get all the span elements within "Table".
Example:
var items = $('table div span');
items.each(function (x) {
alert(items[x].innerHTML);
});
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first Element in my table.
This is an expected behavior in Selenium. As i can see, there are 3 elements with the same xpath as mentioned in your code, in this case Selenium returns the first element.
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single Element in my table, and i dont know why.
This is also an expected behavior in Selenium. FindElements will return all the elements with the same xpath.
So change the value of var to some Text2 or some Text3 to locate the other two elements.
The following xpath will work for some Text2 :
.//span[contains(text(), 'some Text2'))]
Try with this Xpath $x("//tr//span[contains(.,'some Text')]")
For what I can see, you are having a trouble with the contains. All 3 spans are containing this 'some Text' portion.
If you want to check the entire string, you could use .//span[text()='some Text'].
Hope this helps, and have fun with web parsing!