How to Bind an CSS attribute to a Table Cell with Svelte - dom

I understand that with Svelte (or any other framework) it's not a good idea to access the DOM directly, eg. document.getElementById and then do something over it. I have a non-dynamic table that is already on a page as a Svelte component then I also have the following data: an array representing the table row's cells (let's say I have 5 cells per row) and also another array where each element has the index number where I must add a CSS attribute active='1' in the correspondent table cell.
ex.: arrIdxs = [1,3,4] and arrCells = [a,b,c,d,e]
<table>
<tr>
<td>a</td>
<td active="1">b</td>
<td>c</td>
<td active="1">d</td>
<td active="1">e</td>
</tr>
</table>
What is a good way to accomplish that?

I'm not sure i understand the use case, but you would have to do something like this:
<script>
const arrIdxs = [1, 3, 4];
const arrCells = ['a', 'b', 'c', 'd', 'e'];
</script>
<table>
<tr>
{#each arrCells as cell, index}
<td class:active={arrIdxs.includes(index)}>{cell}</td>
{/each}
</tr>
</table>
<style>
.active {
background-color: red;
}
</style>

Related

use getByRole to select gridcell with particular description

I have some tabular data with the headers ('Type', 'Name'). I would like to select all items in column 'name', to check if they contain a search string. Each item in that column has the role 'gridcell', and the description 'Name'. See attached image1.
getByRole('gridcell', {description: /name/i}) doesn't work. I've looked through the typescript declarations of the queries and nothing seems helpful. How can one accomplish this?
Use getAllByRole('cell', {description: /name/i}) to retrieve an array containing the cells in column Name.
Check the array contains a certain value using toContain(item).
https://jestjs.io/docs/expect#tocontainitem
An example (using React):
'App.js'
function App() {
return (
<div className='App'>
<table>
<thead>
<tr>
<td id='name'>Name</td>
</tr>
</thead>
<tbody>
<tr>
<td aria-describedby='name'>J Blogs</td>
</tr>
<tr>
<td aria-describedby='name'>J Doe</td>
</tr>
<tr>
<td aria-describedby='name'>J Hancock</td>
</tr>
</tbody>
</table>
</div>
);
}
export default App;
'App.test.js'
import { render, screen } from '#testing-library/react';
import App from './App';
test('retrieves all cells described by name', () => {
render(<App />);
const cells = screen.getAllByRole('cell', {description: /name/i});
const cellValues = cells.map(cell => cell.textContent);
expect(cellValues).toContain('J Doe');
});

PuppeteerJS - how can I scrape text content from a td element based on the text of the adjacent td?

I am attempting to scrape a link from a td cell adjacent to another td labeling the type or description of the link using puppeteer. There are no classes or id distinguishing these td cells other than the text content
<tr>
<td scope="row">1</td>
<td scope="row">10-Q</td>
<td scope="row">nflx-093018x10qxdoc.htm</td>
<td scope="row">10-Q</td>
<td scope="row">1339833</td>
</tr>
<tr class="blueRow">
<td scope="row">2</td>
<td scope="row">EXHIBIT 31.1</td>
<td scope="row">nflx311_q32018.htm</td>
<td scope="row">EX-31.1</td>
<td scope="row">14914</td>
</tr>
<tr>
<td scope="row">3</td>
<td scope="row">EXHIBIT 31.2</td>
<td scope="row">nflx312_q32018.htm</td>
<td scope="row">EX-31.2</td>
<td scope="row">14553</td>
</tr>
<tr class="blueRow">
<td scope="row">4</td>
<td scope="row">EXHIBIT 32.1</td>
<td scope="row">nflx321_q32018.htm</td>
<td scope="row">EX-32.1</td>
<td scope="row">12406</td>
</tr>
the link after td containing '10Q'
XPath expressions
This is where XPath expression are great:
//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]
This XPath expression queries for a td element containing the text 10-Q. Then it will take the following td element and return the first link (a) inside. Alternatively, you could use //td[text()='10-Q']/ in the beginning, if you don't just want the element to contain the text, but to exactly match it.
Usage within puppeteer
To get the element with puppeteer, use the page.$x function. To extract information (like href) from the queried node, use page.evaluate.
Putting all together, the code looks like this:
const [linkHandle] = await page.$x("//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]");
const address = await page.evaluate(link => link.href, linkHandle);
You can do this with vanila javascript,
// find all tr elements
[...document.querySelectorAll('tr')]
// check which one of them includes the word
.find(e=>e.innerText.includes('10-Q'))
// get the link inside
.querySelector('a')
With puppeteer $eval, this can be simplified,
page.$$eval('tr', eachTr=> eachTr.find(e=>e.innerText.includes('10-Q')).querySelector('a'))
Or page.evaluate,
page.evaluate(()=> {
// find all tr elements
return [...document.querySelectorAll('tr')]
// check which one of them includes the word
.find(e=>e.innerText.includes('10-Q'))
// get the link inside
.querySelector('a')
// do whatever you want to do with this
.href
})
Readable solution.

Selenium IDE Click on a button in a row identified by text

I am trying to get my script to click on a button called Enter Response located in the same row as a specific text (SID). I am able to locate both separately but can't seem to make both work at the same time.
The table is dynamic so I am using the SID, finding it's row and then want to click on it's response button. I.E. find text '123456' & click on 'Enter Response' found in the same row.
I tried this but am getting an error locator not found:
//tr/td/a[#class='title-abbr' and text()='123456']/following-sibling::td/a[text()='Enter Response']
Table Row Headers:
Title/Source/Source ID/SID/Create Date/(Enter Response button)/Form Type
<tr>
<td class="t-Report-cell" headers="TITLE_ABBR">this is my title</td>
<td class="t-Report-cell" headers="SOURCE_NAME">source1</td>
<td class="t-Report-cell" headers="SOURCE_NUMBER">142417</td>
<td style="background-color: rgb(13, 13, 13);" class="t-Report-cell" headers="SID_ABBR">
123456
</td>
<td class="t-Report-cell" headers="TRANSACTION_DATE">07/28/2016</td>
<td style="background-color: rgb(13, 13, 13);" class="t-Report-cell" headers="LINK" align="center">
<a style="background-color: rgb(0, 255, 255);" class="response-btn" href="f?p=58117:50:27077013481519::NO::P50_TRIGGER_ID:321860">Enter Response</a>
</td>
<td class="t-Report-cell" headers="FORM_TYPE">Questions</td>
</tr>
Any help would be greatly appreciated!
if I am looking right, you should first get to the parent node before trying to get to the next sibling....because "a" element has no sibling, so basically something like that:
//tr/td/a[#class='title-abbr' and text()='123456']/../following-sibling::td/a[text()='Enter Response']
You could also just use following-sibling::td[2] instead of selecting by text in the second part of xpath, but maybe you need it for some reason.
Btw some tips:
If the element could have multiple style classes, you will have to use contains
The same applies to text, beware of spaces etc. you should trim the text or use contains to avoid wrong selectors

Sort a table with multiple tbody?

I have a table structure as follows. Now I need to sort these nested tables separately. Forexample: sorting chapter's row will only update chapters order in a separate table. Whereas, sorting items will update their order in another table.
I managed to setup the code and sorting. However, when I drag the items from chapter 4, it pass on the order of the items in from chapter 1 since they come before chapter 4???
Could someone help me with sorting only relevant items??
NOTE: This list is dynamic coming from database. So I am interested in one jquery code covering all the ordering bits.
<table id=subsortsortable>
<tbody class=content>
<tr id="chapter_1"><td>Chapter one</td></tr>
<tr id="chapter_2"><td>Chapter two</td></tr>
<tr id="chapter_3">
<td>
<table>
<tbody class=subcontent>
<tr id="item_31"><td>three.one</td></tr>
<tr id="item_32"><td>three.two</td></tr>
</tbody>
</table>
</td>
</tr>
<tr id="chapter_4">
<td>
<table>
<tbody class=subcontent>
<tr id="item_41"><td>four.one</td></tr>
<tr id="item_42"><td>four.two</td></tr>
<tr id="item_43"><td>four.three</td></tr>
<tr id="item_44"><td>four.four</td></tr>
<tr id="item_45"><td>four.five</td></tr>
</tbody>
</table>
</td>
</tr>
<tr id="chapter_4"><td>Chapter Four</td></tr>
</tbody>
</table>
The code I am using is as follows:
//for sorting chapters - which is outer table
$("#subsortable tbody.content").sortable({
opacity: 0.7,
cursor: 'move',
placeholder: "ui-state-highlight",
forcePlaceholderSize: true,
update: function(){
var order = $('#subsortable tbody.content').sortable('serialize') + '&action=updateChaptersOrder';
$.post("/admin/ajax/ajax_calls.php", order, function(theResponse){
});
}
});
// For sorting and updating items within a specific chapter - which is nested tbody
$("tbody.sortItems").subcontent({
opacity: 0.7,
cursor: 'move',
placeholder: "ui-state-highlight",
forcePlaceholderSize: true,
update: function(){
var order = $('tbody.subcontent').sortable('serialize');// + '&action=updateListings';
$.post("/admin/ajax/ajax_calls.php", order, function(theResponse){
});
}
});
I have got the answer to my own question.. In case someone else encounter the same problem. I have changed the following code inside the internal table:
var order = $('tbody.subcontent').sortable('serialize');
to
var order = $(this).sortable('serialize');

JQuery .insertAfter() DOM elements

I have a HTML Table which in which i want to manipulate using JQuery
Table:
<tr><td>----Parent One
<Table id="ChildID" >----Child One
First TR1<TR>
<TD><div class=ExternalClass00FA6D5A488C4B2582667D6D8DF15F79>Value 1</div></TD>
<TD class="ms-disc-bordered-noleft">Value 2</TD>
<TD class="ms-disc-bordered-noleft">Value 3</TD>
<TD class="ms-disc-bordered-noleft">
Value 4
</TD></TR>
..........
Second TR2<TR>
<TD><div class=ExternalClass00FA6D5A488C4B2582667D6D8DF15F79>Value 1</div></TD>
<TD class="ms-disc-bordered-noleft">Value 2</TD>
<TD class="ms-disc-bordered-noleft">Value 3</TD>
<TD class="ms-disc-bordered-noleft">
Value 4
</TD></TR>
........and so on
</TABLE>---Child One
</td></tr></TABLE>---Parent One
i am trying to pick "Value 4" the last having string "FolderCTID" in href and insertBefore "Value 1" with div class that starts with "ExternalClass".
I want to insertBefore the each element in the row to the corresponding element in the same row
I am using following code:
$('a[href*="FolderCTID"]').insertBefore($('div[class^="ExternalClass"]'));
But it is inserting all the elements for every row....i think i should make something to specify the entities and loop around** each end of the entity...
Please help me on this
then you may want this,
try this , and let me know,
$('a[href*="FolderCTID"]').each(
function(){
$(this).parents('tr').find('div[class^="ExternalClass"]').before(this);
}
);
$('a[href*="FolderCTID"]').each(
function(){
$(this).siblings(':first').insertBefore(this);
}
)
may this help.