Cheerio.js and working with subsets of the dom - javascript

I've having some issues (probably misunderstanding soemthing most likely) when reading the dom and using cheerio.js to do so from with a simple node.js app.
I'm using request to grab the html from a website and cheerio to navigate it find certain portions.
As and example the html looks like this....
<html>
<body>
<table>
<tr><td class="title"/>Title 1</td></tr>
<tr>
<td>
<table>
<tr>
<td class="dl">Some Name1</td>
</tr>
</table>
<td>
</tr>
<tr><td class="title"/>Title 2</td></tr>
<tr>
<td>
<table>
<tr>
<td class="dl">Some Name2</td>
</tr>
</table>
<td>
</tr>
<tr><td class="title"/>Title 3</td></tr>
<tr>
<td>
<table>
<tr>
<td class="dl">Some Name3</td>
</tr>
</table>
<td>
</tr>
</table>
</body>
</html>
What want to do it find all instances of the td with class title
grab the title text and thne for each one of those then grab the name at the td with class dl.
So far
$('td[class=title]')
will get me all the td with that class and using the each function
$('td[class=title]').each(function(i, elem)
lets me grab the text from each but I want to grab the title then the next td with the dl class before moving on to the next title.
I guess what I'm really asking is can I get that td.dl element while in the
$('td[class=title]'.each function?

Yes you can:
.each(function(){
$(this).parent().next().find('td.d1').text()
})

Related

Using JavaScript variables in a Thymeleaf th:each

I am trying to build a table using th:each and have the whole row of the table clickable as a link through JavaScript.
<table>
<th:block th:each='user : ${list}'>
<script th:inline="javascript">
var userid = [[${user.id}]];
</script>
<tr onclick="location.href='user?id='+userid">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</th:block>
</table>
However, the variable always refers to the latest value and not the one it was when the row was created. Is there a way to do that? Or maybe a different solution to what I'm trying to do?
No need for the th:block, you can simply put the th:each on the tr.
To accomplish the click, I recommend putting the id in a data attribute, and retrieving it in JavaScript. This should work for you:
<table>
<tr th:each="user : ${list}"
th:data-id="${user.id}"
onclick="location.href = 'user?id='+this.getAttribute('data-id')">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</table>
You can avoid using JavaScript by adding an <a> element to each table cell (Inspired by https://stackoverflow.com/a/17147909/40064):
<table>
<th:block th:each='user : ${list}'>
<tr>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.firstName}"></a></td>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.lastName}"></a></td>
</tr>
</th:block>
</table>

How to replace between existing table rows in JavaScript

I am trying to regenerate a table with a new order, the problem i encounter is in the performance,
I Have something like this:
<table>
<tr id="row1"></tr>
<tr id="row2"></tr>
<tr id="row3"></tr>
<tr id="row4"></tr>
</table>
Obviously my table is much more complex, but what i would like is a solution with good performance for a replacing command
my target table should be something like:
<table id="mainTable">
<tr id="row3"></tr>
<tr id="row4"></tr>
<tr id="row1"></tr>
<tr id="row2"></tr>
</table>
When I redraw it the performance is bad(for more then 100 lines)
is there any way to just replace the rows between themselves without redrawing it?
Thanks
For rearranging them append them using append() or next()
$table = $('#mainTable');
$table.append($('#row1,#row2', $table));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="mainTable">
<tr id="row1">
<td>1</td>
</tr>
<tr id="row2">
<td>2</td>
</tr>
<tr id="row3">
<td>3</td>
</tr>
<tr id="row4">
<td>4</td>
</tr>
</table>
The basic sultion is using jquery "after" function , which move the target element after the wanted element ..
$("#row1").after("#row4");
or if you want to sort the table based on its values , you can use plugins like : table sorter

Replace text in an element in HTML from another element (table) using jQuery

I want to replace a particular text in an HTML with another text from another element, which in this case is a table data.().
Here is my table:
<table id="hftable">
<tr>
<td id="hfpn1">V.Sehwag</td>
<td id="hfp1">DNB</td>
<td id="hfp1b">.-.-..-.</td>
</tr>
<tr>
<td id="hfpn2">G.Gambhir</td>
<td id="hfp2">DNB</td>
<td id="hfp2b">.-.-..-.</td>
</tr>
<tr>
<td id="hfpn3">A.Arora</td>
<td id="hfp3">DNB</td>
<td id="hfp3b">.-.-..-.</td>
</tr>
</table>
where batsman1 is the id of the element where the replacement is to take place or more specifically the table looks like:
<table id="current">
<tr>
<td id="batsman1">Batsman 1</td>
<td id="currentbat1"></td>
</tr>
<tr>
<td id="batsman2">Batsman 2</td>
<td id="currentbat2"></td>
</tr>
<tr>
<td>Bowler</td>
<td></td>
</tr>
</table>
I want to replace Batsman 1 (in the table with id="current") with V.Sehwag (in the table with id="hftable") (when someone clicks on a specific button on the page)
I have tried:
$("#batsman1").text($("#hfpn1").val());
This isn't working. Apart of showing "V.Sehwag" in place of "Batsman 1", it is showing me a blank space.
Any ideas where I am wrong? What is the correct and easy way to do this?
Thank You.
Try to use .text() in this context, You are invoking .val() function over a non-input element, obviously it wont work. And do remember that, .val() only works on input elements on which user can input something via the UI.
$("#batsman1").text($("#hfpn1").text());
The TD element does not have a value, it has text. Modify your code as follows:
$("#batsman1").text($("#hfpn1").text());
Here's the jsFiddle
Use the below, I hope this will help you out to fix the problem.
$("#batsman1").html($("#hfpn1").text());

Taking the count of number of 'table' tags using jquery

This is my HTML code
<div class="tableStyle myWebsiteTable">
<table cellspacing="0" cellpadding="0" id="site0" class="site active">
<thead>
<tr>
</tr>
</thead>
<tbody>
<tr class="websiteDetails">
<td colspan="5">
<div id="websiteDetails0" class="divWebsiteDetails" style="display: block;">
<table>
<tbody>
<tr id="190">
<td>index</td>
<td></td>
<td></td>
</tr>
<tr class="addPage">
<td align="center" colspan="5"></td>
</tr>
</tbody>
</table>
</div>
</td>
</tr><!--Website Details-->
</tbody>
</table>
<table id="addNewSiteTable">
<thead>
<tr>
</tr>
</thead>
</table>
</div>`<br/>
Now table get added dynamically to this structure.I want to write some logic based on the no of table inside the first div.I tried doing this but did not work $('myWebsiteTable').children('table').length)
PLease suggest the correct way to achieve it
Thank you
You need to use . before class in Class Selector (“.class”)
Live Demo
$('.myWebsiteTable').children('table').length
Also make sure you have added jQuery and elements are added to DOM.
You may need to use find() as children will give you only first level childs where as find will get all the tables in descendants.
$('.myWebsiteTable').find('table').length
$('.myWebsiteTable').children('table').length
And if you actually want to count nested tables:
$('.myWebsiteTable table').length
i think it's class
http://api.jquery.com/class-selector/
$('.myWebsiteTable')
try this, this is more helpfull for you
Demo Here

Expand / Collapse HTML Tables

I have an HTML table which is generated dynamically from server.
I want to have an expand/collapse in this html table that is when I click on expand I should get a new column and rows and on collapse, it should be as it was before.
I don't want to use any 3rd party plugin for it. I want to use jQuery and Ajax.
Can you help me or provide any info on how can I do this?
Ok I think the question is too vague to be answered completely if you think about.
Where are the contents of the new columns, and rows, coming from? What structure do you have? What've you tried already? What didn't work? David Thomas comment.
If you don't want to use a jQuery plugin like this one it means you will have to do it yourself and a) nobody here will do it for you completely b) much less without any information, that would just be guessing.
That said here is a quick and dirty example of what your approach should be like.
HTML
<table border="1">
<tr class="clickable">
<td colspan="2">Click to toggle Next</td>
</tr>
<tr>
<td>Test</td>
<td>Test 2</td>
</tr>
<tr class="clickable">
<td colspan="2">Click to toggle Next</td>
</tr>
<tr>
<td>Test</td>
<td>Test 2</td>
</tr>
<tr class="clickable">
<td colspan="2">Click to toggle Next</td>
</tr>
<tr>
<td>Test</td>
<td>Test 2</td>
</tr>
</table>
jQuery
$(".clickable").click(function() {
$(this).next().toggle();
});
As I said it's just an example, it's not scalable (doesn't even support hiding two rows) you can see a demo here.
I can update the answer with a better more personalized answer if you update your question.
But if you want to build it yourself, this are some of this could come in handy:
.show()
.hide()
.toggle()
.animate()
:nth-child
.children()
And many other depending on your approach.
Good luck!
Here is a quick example, I hope It helps if I understood your question correctly.
With this structure:
<a class="expand" href="#">Expand</a> | <a class="collapse" href="#">Collapse</a><hr />
<table id="mytable">
<thead>
<tr>
<td>
HEAD
</td>
<td>
HEAD
</td>
<td>
HEAD
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
Demo
</td>
<td>
Demo
</td>
<td>
Demo
</td>
</tr>
<tr>
<td>
Demo
</td>
<td>
Demo
</td>
<td>
Demo
</td>
</tr>
</tbody>
</table>
Maybe you could do something like this:
$(document).ready(function () {
$(".expand").click(function () {
$("#mytable tbody").show("slow");
});
$(".collapse").click(function () {
$("#mytable tbody").hide("fast");
});
});
An accordion is a simple, elegant solution: javascript and css.
This fiddle is from the W3Schools explanation above.

Categories