cheerio fetch tr:nth-child() length for iteration - node.js

All,
I am using cheerio package for web scraping,
cheerio tr selector as below. i want to find length of x to iterate
body > table > tbody > tr:nth-child(x) > th:nth-child(2)
Below is my score card html, i want to calculate the total marks of subjects.
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"/><title>Student Score Card</title><h3>Score card</h3>
<table>
<tr><th>Subject</th><th>Marks</th></tr>
<tr><th>English</th><th>78</th></tr>
<tr><th>Maths</th><th>98</th></tr>
<tr><th>Science</th><th>83</th></tr>
<tr><th>Lab</th><th>80</th></tr>
<tr><th>Physical</th><th>75</th></tr>
</table></html>
here i know the row count as 6, so hard coded the value. however it may change in future. so not able to find the max value via code, looking for help here.
Sample logic
const $ = cheerio.load(scorecard.html);
let total = 0;
for(i=0;i<6;i++){
total += parseInt($("body > table > tbody > tr:nth-child("+i+") > th:nth-child(2)").text().valueOf());
}
console.log(total);

If I understand correctly what you are trying to do, then this should help.
const selectors = Array.from($("body > table > tbody > tr"));
let total = 0;
for (let i = 0; i < selectors.length; i++) {
total += parseInt($(selectors[i]).find("th:nth-child(2)").text());
}
console.log(total);

Related

String with multiple lines of weblink images. How to display them?

I've got a String full of weblink image (23 links) :
listItem.text = String(item.movieimage);
If I do trace(String(item.movieimage)); the output is :
http://www.thewebsite.nc/Content/images/AFFICHES/xxx_3.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/vaiana.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/tous_scene.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/fits.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/boyfriend.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/sahara2017.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/resident_evil_final.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/raid_dingue.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/passengers2017.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/lego_batman.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/grande_muraille.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/fille_brest.jpg
Know, I've got 9 UILoader on my stage.
So I would like to do
uiloader1.source = item.movieimage[1];
uiloader2.source = item.movieimage[2];
uiloader3.source = item.movieimage[3];
...etc...
How can I do that ?
Thanks
Assuming they're separated by an indent
//Put all the links in an array
var myItems:Array = listItem_txt.text.split("\n");
//You say you only have nine, so only iterate until the 9th
for (var i:int = 0; i < 9; i++)
{
//Also assuming your "uiloader" is a custom class you made with a .source property
this.getChildByName("uiloader" + i).source = myItems[i];
}

Conditional Formatting for items created in the last 5 minutes in SharePoint 2010

All,
I've been looking all day and have tried numerous solutions, but just can't get it to work. Our team projects a list that is constantly updated and we want to highlight only newly created items for 5 minutes. After 5 minutes, the row would return to normal. (FYI- the list is projected on a display and updated using AJAX asynchronous update every 15 seconds)
Basically, I want to set conditional formatting on list items created in the last 5 minutes. If the item was created in the last 5 minutes, the row will be highlighted. After the 5 minutes are up, the row would return to normal.
I tried SharePoint Designer conditional formatting by creating a calculated column in Date/Time format called "Created + 5" and tried to set an expression where the formatting is applied (row is highlighted) when "Created + 5" is greater than or equal to current date. So after 5 minutes, the row will no longer be highlighted (because the current date/time will exceed the "Created + 5" value)
Here is the expression from the SPD Advanced Condition Builder:
ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($thisNode/#Created_x0020__x002b__x0020_5_x))) >=
ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))
I think the problem is that the [Current Date] option ($Today in the expression builder) only accounts for date and not time. It looks like it just ends up highlighting everything that was created today, which is not very useful.
Any thoughts or help!? I have never messed with the advanced conditions because usually the basic stuff works fine for me! If anyone has any other ideas too like JavaScript or anything else that would work, I am open to that too as long as it will continuously update!
Thanks all!!!!
[Today] actually doesn't work properly in 2010, there are some workarounds though, e.g. https://abstractspaces.wordpress.com/2008/05/19/use-today-and-me-in-calculated-column/.
You can also use the approach with calculated column: https://blog.splibrarian.com/2012/06/06/using-calculated-columns-to-add-color-coding-to-your-sharepoint-lists/
Since you want this to update automatically without requiring someone to manually refresh the page, JavaScript is your best bet. You can have a function run repeatedly on a specified interval, checking the current date against the values in a date column.
Something like the following code would work, though you may need to tweak the CSS selectors specified in the calls to document.querySelector and querySelectorAll to match your particular HTML.
<script>
formatCell();
function formatCell(){
var frequencyToCheck = 2 /* num seconds between updates */
var minutes = 5; /* num minutes back to highlight */
var targetColumn = "Display name of the column you want to check";
var formatting = "background-color:darkred;color:red;font-weight:bold;";
var comparisonDate = new Date();
comparisonDate.setHours(comparisonDate.getHours() - minutes);
var tables = document.querySelectorAll("table.ms-listviewtable"); /* should get all list view web parts on the page */
var t_i = 0;
while(t_i < tables.length){
var headings = tables[t_i].rows[0].cells;
var columnIndex = null;
var h_i = 0;
while(h_i < headings.length){
var heading = headings[h_i].querySelector("div:first-child");
if(heading != null){
var displayName = heading.DisplayName ? heading.DisplayName : (heading.innerText ? heading.innerText : heading.textContent);
displayName = displayName.replace(/^\s+|\s+$/g,''); /* removes leading and trailing whitespace */
if(displayName === targetColumn){
columnIndex = h_i;
break;
}
}
h_i += 1;
}
if(columnIndex != null){ /* we found a matching heading */
var rows = tables[t_i].rows;
for(var i = (rows.length > 0 ? 1 : 0); i < rows.length; i++){
var cells = rows[i].children;
if(cells.length <= columnIndex){continue;}
var valueToEval = cells[columnIndex].innerText ? cells[columnIndex].innerText : cells[columnIndex].textContent;
if(typeof valueToEval == "undefined"){valueToEval = "";}
valueToEval = new Date(valueToEval);
if(valueToEval > comparisonDate){
cells[columnIndex].setAttribute("style",formatting);
}else{
cells[columnIndex].setAttribute("style","");
}
}
}
t_i +=1;
}
setTimeout(formatCell,frequencyToCheck * 1000);
}
</script>
One potential pitfall is that while this approach will "age" records appropriately based on their displayed values (causing them to stop being highlighted as they grow stale), it won't automatically pick up new changes to the list; you'd need to refresh the page (or at least refresh the view in the web part) whenever you want to see updated information.

how to display an excel spreadsheet on browser using jsps.?

i had a excel sheet which is coming to a jsp from the servlet. Can someone help me of how to write a jsp page to display the excel contents in the browser.
Thanks in advance.
If the excel is not changing the structure dynamically, I recommend you to build a set of objects and parse these information in the server, and then in the jsp read these objects to build an html table with this set of objects.
You can load an Excel file with the class HSSFWorkbook or XSSFWorkbook, and then loop to the rows and cells for building your objects.
Please have a look at the examples of Apache Poi here
You can do something like this...
if(sheet.getPhysicalNumberOfRows() > 0) {
lastRowNum = sheet.getLastRowNum();
for(int j = 0; j <= lastRowNum; j++) {
row = sheet.getRow(j);
lastCellNum = row.getLastCellNum();
for(int i = 0; i <= lastCellNum; i++) {
cell = row.getCell(i);
if(cell == null) {
csvLine.add("");
}
else { //set your properties here...
}
}
}
}

How to insert new tr every third iteration in Jade

I'm new in node.js and Jade.
I searched for solutions without success (maybe I asked wrong questions in google, I don't know).
I want to create table rows in each loop in Jade. The thing is that after every 3rd td I want insert new tr. Normally it's quite simple but with Jade I simply can't achieve that.
My Jade file:
table
thead
tr
td Header
tbody
each item, i in items
if (i % 3 === 0)
tr
td
a(href="#{baseUrl}/admin.html?id=#{item.id}")
I know that something is wrong with my if statement. I tried many configurations without luck. I'm sure that it will be quite easy issue.
Thanks in advance for help!
EDIT
Based on #Laurent Perrin answer I modified a little my code. Now it creates tr, then 3 td and then new tr so it's a little closer...
New Jade
if (i % 3 === 0)
tr
td: a(href="#{baseUrl}/admin.html?id=#{item.id}") dsdsd #{i}
Generated HTML
<tr></tr>
<td>0</td>
<td>1</td>
<td>2</td>
<tr></tr>
EDIT: this code should do what you want, but it's not very elegant:
table
thead
tr: td Header
tbody
- for(var i = 0, nbRows = items.length/3; i < nbRows; i++) {
tr
if items[3*i]
td: a(href="#{baseUrl}/admin.html?id=#{items[3*i].id}")
if items[3*i + 1]
td: a(href="#{baseUrl}/admin.html?id=#{items[3*i + 1].id}")
if items[3*i + 2]
td: a(href="#{baseUrl}/admin.html?id=#{items[3*i + 2].id}")
- }
What you could do instead is tweak your model to make it more Jade-friendly, by grouping items by rows:
function getRows(items) {
return items.reduce(function (prev, item, i) {
if(i % 3 === 0)
prev.push([item]);
else
prev[prev.length - 1].push(item);
return prev;
}, []);
}
This will turn:
[{id:1},{id:2},{id:3},{id:4},{id:5}]
into:
[
[{id:1},{id:2},{id:3}],
[{id:4},{id:5}]
]
Then your jade code becomes much simpler:
table
thead
tr: td Header
tbody
each row in rows
tr
each item in row
td: a(href="#{baseUrl}/admin.html?id=#{item.id}")
An example of jade + bootstrap, each 4 elements(columns) one row, and the rows goes inside the row.
```
- var i = 0
- var itens_per_line = 4
each order in viewBag.orders
- if (i % itens_per_line === 0 || i === 0) {
.row
- }
.col-md-3.column
p #{order.number}
- i++
```
Here is what I did for a single array (e.g. ['1','2','3','4']) to convert it into two values per row, it could be adjusted for 3.
(mixins are templates in Jade/Pug)
mixin mInput
div.form-group.col-md-6
p=oval
- var valcounter = 0
- var row = [];
each val in JSON.parse(formvalues)
if(valcounter % 2 === 0)
- var col = [];
- col.push(val)
else
- col.push(val)
- row.push(col)
- valcounter++
each orow in row
div.row
each oval in orow
+mInput

Apple Script to output text and links to spreadsheet

My goal is to get a Apple script running that can pull text from the top 50 apps and put them into a spread sheet with a few different columns. One for rank, App Name, and download link.
Heres the link: http://www.apple.com/itunes/charts/free-apps/
I'm not the best apple scripture but any advice or code would be VERY much appreciated. Thanks for listening!
I don't have numbers but I'm sure you can figure out the rest...
tell application "Safari"
set myUrls to do JavaScript "var hitList = [];
for (i = 0; i<50; i++)
{
hitList.push(document.getElementsByTagName('strong')[i].parentNode.childNodes[1].href)
}
hitList;" in document 1
set appNames to do JavaScript "var hitList = [];
for (i = 0; i<50; i++)
{
hitList.push(document.getElementsByTagName('strong')[i].parentNode.childNodes[2].childNodes[0].childNodes[0].nodeValue)
}
hitList;" in document 1
end tell
display dialog "1st App name: " & item 1 of appNames & return & "1st URL: " & item 1 of myUrls

Resources