How can I select multiple TR elements in a table? - html-table

<table>
<tr>
<td/>
<td/>
<td/>
</tr>
<tr>
<td/>
<td/>
<td/>
</tr>
.....
</table>
This the table structure I have and I want to provide multi select feature on this table. User should be able to select multiple TR elements - very similar to tag.
But I cannot use because I want to add multiple span elements in each td in the above structure.
I thought of having an event capture on TR. But I am totally at loss as to how to proceed. Any suggestions?
Some of the other things I tried include adding a DIV directly inside TR - but that is incorrect. And adding a div inside the TD is of no use to me in this case.

Try SlickGrid. It pretty much gives you that out of the box. It uses div instead of table, though.
https://github.com/mleibman/SlickGrid

Related

htmx: How to swap table row with hx-swap-oob?

I want to use hx-swap-oob to replace a table row of the existing page "out of band".
in browser:
<table>
<tr id="offer_1">....</tr>
<tr id="offer_2">....</tr> (old)
<tr id="offer_3">....</tr>
</table>
From Server to client:
<table hx-swap-oob="outerHTML:#offer_2" hx-select="#offer_2">
<tr id="offer_2"> .... </tr> (new)
</table>
But up to now this is the result:
<table>
<tr id="offer_1">....</tr>
<table hx-swap-oob="outerHTML:#offer_2" hx-select="#offer_2">
<tr id="offer_2"> .... </tr> (new)
</table>
<tr id="offer_3">....</tr>
</table>
I guess hx-select does not get evaluated when htmx get this snippet from the server.
How can I swap a row out-of-band?
Take a look at the new extension multi-swap.
https://htmx.org/extensions/multi-swap/
It allows swapping multiple elements marked with the id attribute.
For each element it is possible to choose which swap method should be used.
This does work:
<tr hx-swap-oob="true" id="offer_2"> .... </tr> (new)
But it has a drawback:
You need to modify the method which creates this row. Depending on your context, you might already have a method for this. Why modify this method, just because the result of this method should get used out-of-band?
If you use Django, this snippet could get used to add the hx-swap-oob attribute after the HTML got created:
def add_oob_attribute(html):
"""
I would like to avoid this ugly hack
https://github.com/bigskysoftware/htmx/issues/423
"""
assert isinstance(html, SafeString)
new, count = re.subn(r'(<\S+)', r'\1 hx-swap-oob="true"', html, count=1)
if not count == 1:
raise ValueError(f'Could not add hx-swap-oob: {html}')
return mark_safe(new)
I created an issue to find a better solution in the future:
https://github.com/bigskysoftware/htmx/issues/423

Selenium XPath - Ignore element amongst table

I have an issue with selecting a table to be read in Selenium.
I have a table in which there is two 'tr' elements inside the 'thead', and I need to find a way to ignore the first of these.
Here is the code:
<table class="noselect">
<thead>
<tr>
<th> </th>
<th class="number IOL">Interest Rates</th>
<th class="number IO">
</tr>
<tr>
<th>Description</th>
<th class="number">Value</th>
<th class="number">Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<tr class="">
<tr class="">
<tr class="">
<tr>
<tr>
</tbody>
</table>
Using Selenium I will ask it to record the value of a certain row and column . This will then look at the Table element I will give it (hopefully using an XPath I can get working in this case), look at the thead and record the headers of each column. In this case that I am struggling with, the fact there is an extra 'tr' at the top of this table gets in the way of this process.
This is how the element is currently used:
[TableAlias("Detailed table")]
protected virtual IWebElement DetailedTable()
{
return Driver.FindElement(By.XPath("//table[#class='noselect']"));
}
I have tried many different ways which I can't get to work, but the gist of what I've been going for is:
//table[#class='noselect movements']/thead/tr/th[not(text()='Interest Rates')]/../../..
Here I'm stuck on going to the 'tr' element, telling it not to use it then backing out, but that selects it back again - and even that doesn't unselect the whole 'tr' element. It doesn't seem to help (to me) that the 'tr' element I'm trying to remove is blank with no class or defining features.
Is there a way of selecting the entire table except for the first 'tr' element in 'thead' as one element?
combine two xpathes. The 1st xpath take thead without the 1st tr and the 2nd tbody
//table/thead/tr[not(position()=1)] | //table/tbody
In your function that processes the THEAD tag, get the collection of TRs and start with [1] (skipping [0]) and process the rest.

Clicking other cell's child element in Selenium WebDriver Java

What is the code to be used to click the "a" element by looking first for the "td" that contains certain texts?
<table>
<tbody>
<tr>
<td><a class="link">link</a></td>
<td>1st</td>
</tr>
<tr>
<td><a class="link">link</a></td>
<td>2nd</td>
</tr>
</tbody>
</table>
I used this code but it doesn't work.
driver.findElement(By.xpath("//td[contains(text(), '1st')]/following-sibling::a[#class='link']")).click();
Try this xPath //td[contains(text(), '1st')]/../td/a[#class='link'].
Your mistake comes from the axis "following-sibling". The tag a is not a sibling of the td tag. I use .. to go up, then select td again and then a.
I tested the xPath using http://www.xpathtester.com/xpath. It works. Beware that every browser comes with their own xPath implementation, therefore it could behave a bit differently.
However, as there is nothing exotic in the xPath expression, I don't expect any problem.

Updating HTML table through JSTL and SQL

I have a HTML table which initially displays all records in the DB. I have just added a JQuery Datepicker component, and now I want to be able to retrieve records based on date. I have no problem extracting the date from the Datepicker component, but I do have a problem updating the existing HTML table. My code is pretty standard.
<sql:query var="retrieveSecurity" dataSource="jdbc/SecurityApp">SELECT * FROM security</sql:query>
<tbody>
<c:forEach var="row" items="${retrieveSecurity.rows}">
<tr>
<td>${row.security_id}</td>
<td>${row.description}</td>
<td class="center">${row.bid_price}</td>
<td class="center">${row.bid_percent_change}</td>
<td>${row.comment}</td>
</tr>
</c:forEach>
</tbody>
What I basically want to do is to have another SQL query, something like this...
<sql:query var="retrieveSecurity" dataSource="jdbc/SecurityApp">SELECT * FROM security where trade_date = "MYVALUE"
</sql:query>
I then want to be able to update the the tbody tag to point to this new SQL query, and call it instead. The columns won't change, so it should be the same table, just with filtered data. Not sure if what I am asking is the easiest/best solution, just looking for something that will work quickly for a prototype.
Hope this makes sense.

How can I insert a HTML tag before its parent tag using the Transformer from Genshi?

I need to modify the file table in my trac browser view by creating a class which implements the ITemplateStreamfilter class. I tried using the Transformer from genshi.filters.transform. My table looks like
<tbody>
<tr class="even">
<td class="name">
<a class="partent" title="Parent Directory" ..>..</a>
</td>
..
</tr>
..
</tbody>
I now need to insert a </td> tag just before the frist cell in the first row of the table. The problem is that I only can identify the position of column where I want to put the new cell befor by searching for the "Parent Directory" title: Transformer('//*[#title="Parent Directory"]'). How can I step one tag up than put the new cell before the first <td class="name"> tag?
I'm not THAT familiar with the support for XPATH of Transformer BUT:
What about
Transformer('(//td[*[#title="Parent Directory"]])[1]') and then using the before method?
As far as I understand, this should select the first td node with a child node with an attribute title="Parent Directory".
If you want to select any td with that kind of child node use
Transformer('//td[*[#title="Parent Directory"]]')
However, this only works if Transformer supports those XPATH expressions.
Edit 1
If you're sure, your td has an attribute class="name" you can also use Transformer('(//td[class="name" and *[#title="Parent Directory"]])[1]')