add a serial number while performing iteration in thymeleaf - java

I have a senario in which i must perform iteration on a list and display result as a grid.Also include serial number in it. Now what I did for serial number is given below
<div th:with="i=0">
<tr th:each="mydate:${data.Listdata}" >
<div th:with="i=${i+1}">
<td th:text="${i}">
</div>
//other codes
</tr>
</div>
but only 1 appears in all serial number.Can anyone help me with this?

You can use the index of the iteration status:
<tr th:each="item,iterator : ${items}">
<td th:text="${iterator.index}"></td>
</tr>

You can use the iterationStatus to begin with 1 instead of 0.
<tr th:each="item,iterationStatus : ${items}">
<td th:text=${iterationStatus.count}></td>
</tr>
This gives the table Sno. Starting with 1.

To get the index:
<tr th:each="item: ${items}">
<td th:text="${iterator.indexOf(item)}"></td>
</tr>
To get a numbering increment index by one.
<tr th:each="item: ${items}">
<td th:text="${iterator.indexOf(item) + 1}"></td>
</tr>

Related

Thymeleaf: th:each for two table rows?

How can I, inside a th:each loop create a group of two rows instead of just one?
I know I can do:
<tr th:each="obj: ${listOfObjects}">
<td>a column with data: ${obj.id}</td>
</tr>
However, I want two <tr> elements to be created, as I would do with JSTL:
<c:forEach items="${listOfObjects}" var="obj">
<tr>
<td>${obj.id}</td>
</tr>
<tr>
<td>${obj.name}</td>
</tr>
</c:forEach>
Is there a way to achieve that with Thymeleaf?
You could use a th:block element for grouping the rows together and repeat them:
<th:block th:each="obj: ${listOfObjects}">
<tr>
<td th:text="${obj.id}"></td>
</tr>
<tr>
<td th:text="${obj.name}"></td>
</tr>
</th:block>
You can read more about th:block here

Selenium Webdriver Xpath: Find and compare the text of an element then click the link that's 4 rows after

I want to find and compare the heading in the table. Then click on the delete button that in the next 3 rows of the heading.
Example: Lets say a given input is Heading 2. I want to search Heading 2 and see if it exists then click on the delete button that is associated with 'Heading 2' (like 3-4 rows after).
So far this is the code that i came close to. The only problem is that it always click the first selection instead of where i want it to go.
String HeadingName = "Heading 2"
driver.findElement(By.xpath("//tr[contains(.,'" + HeadingName + "')]/tr[position()=4]/td[2]/div/a[2]")).click();
This is what the table and it's code looks like.
Heading 1
Name: Joe
Gender: Male
Options: Update | Delete
Heading 2
Name: Jenny
Gender: Female
Options: Update | Delete
<table>
<tbody>
<tr>
<th class="st-head-row" colspan="2">Heading 1</th>
</tr>
<tr class="even">
<td class="st-key">Name:</td>
<td class="st-val">Joe</td>
</tr>
<tr class="even">
<td class="st-key">Gender:</td>
<td class="st-val">Male</td>
</tr>
<tr class="even last-row">
<td class="st-key">Options:</td>
<td class="st-val">
<div style="white-space:nowrap;">
<a id="save" href="linkaddress">save</a>
|
<a id="delete" href="linkaddress">delete</a>
</div>
</td>
</tr>
<tr>
<th class="st-head-row" colspan="2">Heading 2</th>
</tr>
<tr class="even">
<td class="st-key">Name:</td>
<td class="st-val">Jenny</td>
</tr>
<tr class="even">
<td class="st-key">Gender:</td>
<td class="st-val">female</td>
</tr>
<tr class="even last-row">
<td class="st-key">Options:</td>
<td class="st-val">
<div style="white-space:nowrap;">
<a id="save" href="linkaddress">save</a>
|
<a id="delete" href="linkaddress">delete</a>
</div>
</td>
</tr>
</tbody>
</table>
Try this code , hope it will help you.
driver.findElement(By.xpath("//tr/th[contains(text(),'" + HeadingName + "')]//following::tr[3]/td[2]/div/a[2]")).click();
Thanks
Try next code with xpath
String headingName = "Heading 2";
driver.findElement(By.xpath("//th[text()='"+ headingName +"']/parent::tr/following-sibling::tr[#class='even last-row']/td[#class='st-val']/div/a[#id='delete']")).click();
If it works, for detailedinfo how this xpath is created look here - http://www.w3schools.com/xpath/xpath_axes.asp
I'd try and keep the XPath a bit more "semantic", e.g.
//tr[th = 'Heading 2']/following-sibling::tr[starts-with(td[1], 'Options')][1]//a[. = 'delete']
Here I'm looking specifically for the "delete" link in the next "Options" row, rather than something more fragile like "the second link in the next-but-two row".
I actually made an answer that surprisingly worked for me.
dUtil.findElement(By.xpath("//tr/th[contains(text(),'" + headingName + "')]/../following::tr[3]/td[2]/div/a[2]")).click();
I got every condition I wanted.
Searches for the heading that is similar to the given input heading
Clicks the link 'Delete' that is 3 rows bellow the searched element
Should work even if there are more than one batch of rows (batch meaning from heading to delete)
The batch doesn't have to be in order.

How to click a button from a table where all classes have the same name

<tbody>
<tr class="b">
<td class="t_l">betmatrix</td>
<td class="t_l">
<td class="t_r">dsdfsf</td>
<td class="t_r">NONE</td>
<td class="t_r">ALL</td>
<td class="t_r">NONE</td>
<td class="t_r">ALL</td>
<td class="t_r">ALL</td>
<td class="t_r">NONE</td>
<td class="t_r">ALL</td>
<td class="t_r">Not required</td>
<td class="t_r">1.11</td>
<td class="t_r">All User</td>
<td class="t_r">0.00</td>
<td class="t_r">2014-09-05</td>
<td class="t_r">2014-09-15</td>
<td class="t_r">2014-09-05</td>
<td class="t_r">1-admin</td>
<td class="t_r">
<td class="t_r">0.00</td>
<td class="t_r">0.00</td>
<td class="t_r">
<td class="t_r">
<a onclick="showBonusModificationLogs(53599)" href="#">History</a>
</td>
</tr>
<tr class="a">
<tr class="b">
<tr class="a">
</tbody>
This is the table structure that I have, and there is no way I can search only for specific items in the table.
How can I find an element in a row and then click on the button at the end of the row if it is found?
In this example I would need to search for the word: dsdfsf
It was easier for other tables because the classnames were different. But the same method will not work here.
As #alecxe pointed out, you can use XPath. There are probably hundred different ways of doing this. But to match your requirements I would use: //tr[td[text()='dsdfsf']]/td/a. This says: any row that has a column with the text 'dsdfsf', locate a column with an anchor tag.
You can find element By.xpath:
WebElement element = driver.findElement(By.xpath('//table//tr[td[#class="t_r"] and text() = "dsdfsf"]/td[last()]'));
element.click();
The xpath would search in every tr inside the table for the td with class t_r and text dsdfsf, then would get the last td inside the row.

Selenium Webdriver - Unticking all the chekboxes in a complicated table

I am having some problems currently trying to untick checkboxes in an iframe. The situation is it is currently possible to set some checkboxes to default ticked and some not. I need 1 specific checkbox ticked, so the sensible thing to do is run a loop that iterates through all the checkboxes and unchecks them all.
Here is where I am running into issues. I will post a sample of the HTML that the checkboxes are contained in. (This isn't mine so I can't edit the HTML unfortunately).
This is how the example looks in a situation where there are 3 different types of checkbox in the iframe.
<fieldset id="testing">
<legend>testing</legend>
<table>
<tbody>
<tr>
<td class="EXAMPLE">
<table id="CHECKBOXTYPE1">
<tbody>
<tr>
<td style="vertical-align:top;white-space:nowrap;" title="">
<input id="CHECKBOXTYPE1-01" type="checkbox" value="on" onclick="DOES STUFF;"/>
</td>
<td style="vertical-align:top;white-space:nowrap;" title="">TITLE1</td>
</tr>
<tr>
<td/>
<td id="CHECKBOXTYPE2-01" style="display:none;white-space:nowrap;vertical-align:top;padding:0px;">
<table>
<tbody>
<tr>
<td style="vertical-align:top;" colspan="3">
<select id="field" style="width:100%;">
<option value="1">STUFF1 </option>
<option value="2">STUFF2 </option>
<option value="3">STUFF3 </option>
<option value="4">STUFF4 </option>
</select>
</td>
<td style="vertical-align:bottom;padding-left:6px;" rowspan="2">
<textarea id="CHECKBOXTYPE2-01-COMMENTS" cols="50" rows="2" style="margin:0px;height:50px;" type="text" onclick="DOES STUFF">Please Insert Notes...</textarea>
</td>
</tr>
<tr>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" value="<" style="height:100%;width:32px;"/>
</td>
<td style="vertical-align:bottom;">
<input id="CHECKBOXTYPE2-01-INPUT" type="input" readonly="" style="width:112px;"/>
</td>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" style="width:32px;height:100%;" value=">"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="field_label">
<table id="CHECKBOXTYPE3">
<tbody>
<tr>
<td style="vertical-align:top;">
<input id="CHECKBOXTYPE3-01" type="checkbox" title="" onclick="DOES STUFF"/>
</td>
<td style="vertical-align:top;" title="">CHECKBOX NAME</td>
<td style="vertical-align:top;">
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
The code I have attempted to iterate is
try{
for(int i=0; i < 30; i++){
WebElement relCheckBoxes = driver.findElement(By.xpath("html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"));
if(relCheckBoxes.isSelected()){
relCheckBoxes.click();
}
}
}
catch(Exception e){
System.out.printf("didn't work");
}
Obviously this is not the most optimised piece of code, but right now I'm just struggling to find something that works :\ I just want to run through the checkboxes, turn off all of them, then turn on the one that I need after.
Thank you.
If you want to uncheck all the checkboxes use the following code. It is much efficient!
//Get the complex table
WebElement mainTable = driver.findElement(By.xpath("html/body/div[3]/fieldset/table"));
//Find all the input tags inside the mainTable and save it to a list
List<WebElement> checkBoxes = mainTable.findElements(By.tagName("input"));
//iterate through the list of checkboxes and if checked, uncheck them
for (WebElement checkbox : checkBoxes) {
if (checkbox.isSelected()) {
checkbox.click();
}
}
I dont see any frame inside your code. If there is a frame use the below code 1st
//switch to the frame
driver.switchTo().frame("framename/index");
Hope this helps you :)
There are a couple of problems here:
1) Your XPath is incorrect. You have:
"html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"
Instead, it should be:
"html/body/div[3]/fieldset/table/tbody/tr[" + i + "]/td/table/tbody/tr/td[1]"
Otherwise, you're just looking for a table row with a non-numerical index 30 times!
2) XPath indices are 1-based rather than 0-based (crazy, I know). Since your loop starts with i=0, it starts off by trying to find the non-existent zeroth element. findElement throws an exception when it cannot locate an element that matches the search criterion, so the loop ends immediately. Try starting the loop with i=1 instead.

Alternative of element.children in jsoup

Alright I am having trouble with finding an equivalent of Element.children() because I have an Elements object...
What I am trying to do is download an html file (well I have done that...) and identify a single table row (, I've done that by using doc.getElementsByClass("emphasizedRowColor"); because the row I want has that emphasizedRowColor class and no other elements do). I just don't understand how to isolate the one Element in my Elements object RWTableRow.
Html:
<tr class="rwOdd emphasizedRowColor">
<td class="jewel" style="">
<div class="teamJewel" style="background-position: 0px -336px;margin: 0 0 2px 2px;"></div>
</td>
<td class="left" style=""> Detroit</td>
<td style="">18</td>
<td style="">9</td>
<td style="">5</td>
<td style="">4</td>
<td class="narrowStatsColumn cSrt" style="">22</td>
<td class="narrowStatsColumn" style="">9</td>
<td style="">45</td>
<td style="">48</td>
<td style="">3-2-4</td>
<td style="">6-3-0</td>
<td style="">3-3-4</td>
</tr>
I can figure out what to do once I actually get the table as an Element but oh boy I think I just need a fresh set of eyes to figure out what I'm doing...
Java:
Document doc = Jsoup.connect(url).userAgent("Mozilla").get();
Elements RWTableRow = doc.getElementsByClass("emphasizedRowColor");
As you can see, I'm in quite the pickle...
Elements is a standard java.util.List, you can simply call
Element e = RWTableRow.get(0);
And there you have it.

Categories