How to split the jquery array - javascript

I have a table and I need to get values for each row (in array), something like:
[{1,'test'}, {2,'another test'}, {3, 'nothing'}], but the only I can get is:
["1 test", "2 another test","3 nothing"]. I need to send this values by ajax as json object ... and create another table - thus I need an array of values ...
var table = $("table");
var rowsAll = table.find("tbody tr");
rowsAll.each(function(i,l) {
var rows = [];
$(this).each(function(t,l){
rows[rows.length] = cells[t]= $(this).text();
return rows; //returns rows, but I need cells of each row
}).serialize();//or get()
});
the html is something like this:
<table id="deal">
<thead>
<tr>
<th> num </th>
<th> string </th>
</tr>
</thead>
<tbody>
<tr> <td> 1 </td> <td> test </td> </tr>
<tr> <td> 2 </td> <td> another test </td> </tr>
<tr> <td> 3 </td> <td> nothing </td> </tr>
</tbody>
</table>
I really need help ...

This form of data makes no sense as it's very hard to read with javascript:
[{1,'test'}, {2,'another test'}, {3, 'nothing'}]
I'm going to assume that what you want is this:
{"1": "test", "2": "another test", "3": "nothing"}
To get that second form, you could use this code:
var results = {};
$("#deal tbody tr").each(function() {
var cols = $(this).find("td");
results[$.trim(cols.eq(0).text())] = $.trim(cols.eq(1).text());
});
Working example here: http://jsfiddle.net/jfriend00/WjgrC/.

Related

Parsing html with cheerio

I used cheerio for the first time today
This is a simplified version of the html source I want.
<div id="country-table">
<!-- div duplicate cause style -->
<div>
<div>
<table>
<tbody>
<tr>
<td>1</td>
<td>USA</td>
<td>1.6</td>
<td>75.8</td>
<td>132,000</td>
</tr>
<tr>
<td>2</td>
<td>INDIA</td>
<td>12123</td>
<td>1322</td>
<td>123213</td>
</tr>
<tr>
<td>3</td>
<td>BRAZIL</td>
<td>3123</td>
<td>213123</td>
<td>134</td>
</tr>
<tr>
<!-- and more... -->
</tbody>
</table>
</div>
</div>
</div>
and i tried to this:
const axios = require("axios").default;
const cheerio = require("cheerio").default;
axios.get("https://coronaboard.kr").then((html) => {
const arr = [];
const $ = cheerio.load(html.data, { xml: true, xmlMode: true });
const data = $("#country-table>div>div>table>tbody").each((index, item) => {
arr.push(item);
});
console.log(arr);
});
I want to put information in td into tr.
ex){number:x,name:USA,confirmed:x,and more...}
If anyone knows how to do it, please answer me!
If you're wanting to extract the data from the table, then this will help. Follow the comments to help you understand how it works.
var $ = cheerio.load(html.data);
// targets the specific table with a selector
var html_table = $('#country-table>div>div>table');
// gets table cell values; loops through all tr rows
var table_data = html_table.find('tr').map(function() {
// gets the cells value for the row; loops through each cell and returns an array of values
var cells = $(this).find('td').map(function() {return $(this).text().trim();}).toArray();
// returns an array of the cell data collected
return [cells];
}).toArray();
// output table data
console.log('table_data', table_data);

how to loop a nested array object in javascript with jquery

Hey im working on a project and i can't seem to get the hang of this. I want to loop through my nested array object "products" so that i can display it all and not just the last index.
// jquery getting our json order data from firebase
$.get("http://localhost:8888/orderslist", (data) => {
// i is for the index of the array of orders
let i = 0;
//for each loop through our array list
$.each(data, function () {
//console.log(data)
//console.log(i);
// is how we arrange the data and show it to the frontpage
$(`<table id = order_table_layout>
<tr>
<th>Customer</th>
<th>Date</th>
<th>Time</th>
<th>Total</th>
<th>Order</th>
<th>Order Status</th>
</tr>
<tr>
<td>${data[i].customer_name}</td>
<td>${data[i].date}</td>
<td>${data[i].time}</td>
<td>${data[i].total} Kr.</td>
<td>
${data[i].products[i].name}
${data[i].products[i].price} Kr.
</td>
<td>
</td>
</tr>
</table>`
).appendTo("#frontpage_new_ordertable");
// counts 1 up for each loop to go through list
i++;
//console.log(i);
});
});
Edit:
An example of the json data I'm working with look like this:
[
{
id: "4WQITi6aXvQJsKilBMns",
customer_name: "Susanne",
date: "22-12-2002",
time: "12:43:19",
total: 222,
products: [
{ name: "product name", price: 100 },
{ name: "product name2", price: 20 }
]
There's a couple of issues in your code. Firstly you're creating a brand new table for every object in the data array. It makes far more sense to instead create a new row in the table for each item.
Also, it appears that you want to loop through the child products array. As such you need an inner loop to create the HTML string for those elements outside of the template literal.
However it's worth noting that it's not good practice to have that much HTML in your JS. A better approach is to have a hidden template tr in your HTML which you can clone, update with the data from the data array, then append to the DOM in the tbody of the table.
With that said, try this:
//$.get("http://localhost:8888/orderslist", (data) => {
// mock response:
let data = [{id:"4WQITi6aXvQJsKilBMns",customer_name:"Susanne",date:"22-12-2002",time:"12:43:19",total:222,products:[{name:"product name",price:100},{name:"product name2",price:20}]},{id:"asjdkjk21ijjjew",customer_name:"Foo Bar",date:"10-05-2020",time:"16:46:16",total:68,products:[{name:"Lorem ipsum",price:50},{name:"Fizz buzz",price:18}]}];
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.find('.customer-name').text(item.customer_name);
$clone.find('.date').text(item.date);
$clone.find('.time').text(item.time);
$clone.find('.total').text(item.total + ' Kr.');
let products = item.products.map(prod => `${prod.name}: ${prod.price} Kr.`);
$clone.find('.products').html(products.join('<br />'));
return $clone;
});
$("#frontpage_new_ordertable tbody").append(rows);
//});
tfoot {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="frontpage_new_ordertable">
<tbody>
<tr>
<th>Customer</th>
<th>Date</th>
<th>Time</th>
<th>Total</th>
<th>Order</th>
<th>Order Status</th>
</tr>
</tbody>
<tfoot>
<tr>
<td class="customer-name"></td>
<td class="date"></td>
<td class="time"></td>
<td class="total"></td>
<td class="products"></td>
<td></td>
</tr>
</tfoot>
</table>
<td>${data[i].total} Kr.</td>
<td>
${data[i].products[i].name}
${data[i].products[i].price} Kr.
maybe that's what's wrong?
is the number of the order similar to the number of product in products array?

How to loop over a elements that are members of a class to get data and turn that data into an object?

I have an odd case where I need to loop with Javascript over HTML elements with class name ui-selected to grab the data associated with that class and insert the grabbed data into an object's attributes for further data manipulation. The whole goal of this ideally is so when some clicks on several different rows on a HTML table they can download the selected rows into a CSV file.
My train of thought was that I need to create an object with arrays as attributes and loop over my class name, get the data, insert the data into an array and then insert that array as an object's attribute. I hope this isn't a completely flawed way of thinking and makes sense. My issue is that I am not really sure on how to do this. I am familiar with looping over 2D arrays, but not something like this where it would require multiple looping if I understand correctly.
Here is what I have so far using jQuery, but I will probably try to opt out of jQuery:
$('#downloadBtn').click(function() {
$('.ui-selected').each(function(index, value) {
$(value).find('td').slice(0,2).each(function(i, v) {
var tdText = $(v).text();
if([0,1].indexOf(i) > -1) {
copyText += tdText + ',';
if([0,1].indexOf(i) == 1) {
copyText += '\n';
}
}
});
});
console.log("CopyText : " + copyText)
});
Basically an easy way to think of what I am trying to accomplish is I need a functionality where I can select multiple rows within a HTML table, and when I click download it should grab only the "selected" rows and turn them into a CSV file to then be downloaded.
Here is basically what the table would look like in HTML (I am using the DataTable library from jQuery):
<table id="icpTable" class="cell-border " width="95%" align="center" style="margin-top: 20px;">
<thead>
<tr>
<th>
<strong>Customer Name</strong>
</th>
<th style="width: 20%">
<strong>Tester Note</strong>
</th>
<th>
<strong>Crucible No.</strong>
</th>
<th>
<strong>Dry Weight</strong>
</th>
<th>
<strong>Wet Weight</strong>
</th>
<th>
<strong>Moisture</strong>
</th>
<th>
<strong>Corrected WW</strong>
</th>
<th>
<strong>Volume</strong>
</th>
<th>
<strong>Dilution</strong>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Example Customer Inc.</td>
<td>SL-001-01-01</td>
<td>123~01~01</td>
<td>1.0000</td>
<td>1.1233</td>
<td></td>
<td>1.012</td>
<td>0.02</td>
<td>0.0001</td>
</tr>
<tr>
<td>Example Customer2 Inc.</td>
<td>SL-002-01-01</td>
<td>124~01~01</td>
<td>1.0000</td>
<td>1.1233</td>
<td></td>
<td>1.012</td>
<td>0.02</td>
<td>0.0001</td>
</tr>
</tbody>
</table>
I really only need tow columns from the table. Tester Note and Customer Name respectively. So the CSV would be something like this:
2018-18-10, 'Sample','Standard', 'test', (Customer Name),(Tester Note), 0.2,'','Tester','A1'
Edit:
I've been playing with this and this is what I have so far:
$('.ui-selected').each(function(index, value) {
var row = table.insertRow(-1);
$(value).find('td').each(function(i, v) {
var tdText = $(v).text();
console.log(tdText)
});
});
So this at least gets me the individual pieces of data. Now I just need to grab the first and second piece only and assign that to a variable.
Here is what I get in my console.log:
Example corp.
Example-066-1-S2
1~1~1
1.0003
1.0150
0.9993
100
100.0686
$('#downloadBtn').click(function() {
let csv = "Customer Name, Tester Note\n";
let elementarray = document.getElementsByClassName('ui-selected');
for (i = 0; elementarray.length > i;i++) {
var dataTags = elementarray[i].getElementsByTagName('td');
var dataArr = [];
dataArr.push(dataTags[0].innerText.trim());
dataArr.push(dataTags[1].innerText.trim());
csv += dataArr.join(', ') + "\n";
}
var a = document.createElement("a");
a.href = "data:text/csv;charset=utf-8,"+ encodeURI(csv);
a.download = "data.csv";
a.click();
});
Here try this.
Here is the output i get.

Highlight cell with highest value in ng-repeat with AngularJS 1.4.14

I am working on a dashboard and I'd like some help '_'.
I get a JSON from an API and I get an array of 5 element and each contain this structure (I simplified it but it is close to that).
{
"app_id": "id",
"app_name": "name",
"users_percentiles": {
"users_percentile_1": "3408",
"users_percentile_2": "2356",
"users_percentile_3": "988",
"users_percentile_4": "1099",
}
}
Then, I use a table to organize those elements in my dashboard.
<tbody ng-repeat="dash in dashboard">
<tr>
<td>{{dash.app_id}}</td>
<td>{{dash.app_name}}</td>
<td ng-repeat="percentile in dash.users_percentiles">
{{(percentile}}%
</td>
</tr>
</tbody>
I'd like for each ng-repeat highlight the highest value of percentile (if two are equals, then both should be highlighted).
I think i should add something like :
ng-class="{max : percentile == maxPercentile}"
and a function :
$scope.maxPercentile = -1;
angular.forEach(percentiles, function (percentile) {
if (percentile > $scope.maxPercentile) {
$scope.maxPercentile = percentile;
}
});
But I don't know really where to use this method.
I tried with a $watch but no matter how I tried I didn't get it to work...
<tbody ng-repeat="dash in dashboard">
<tr>
<td>{{dash.app_id}}</td>
<td ng-init = "maxpercentile = getMaxPercentile(dash.users_percentiles)">{{dash.app_name}}</td>
<td ng-class="{max : percentile === maxpercentile}"
ng-repeat="percentile in dash.users_percentiles">
{{percentile}}%
</td>
</tr>
</tbody>
$scope.getMaxPercentile = function(percentiles){
var maxPercentile = -1;
angular.forEach(percentiles, function (percentile) {
if (percentile > $scope.maxPercentile) {
maxPercentile = percentile;
}
});
return maxPercentile;
}

Convert table HTML to JSON

I have this:
<table>
<tr>
<th>Name:</th>
<td>Carlos</td>
</tr>
<tr>
<th>Age:</th>
<td>22</td>
</tr>
</table>
And I need a JSON format.
{"Name":"Carlos","Age": 22}
I've tried with https://github.com/lightswitch05/table-to-json but it doesn't work for the headings in every row :(
EDIT: http://jsfiddle.net/Crw2C/773/
You can convert the table in the OP to the required format by first converting it to an Object, then using JSON.stringify to get the required string:
<table id="t0">
<tr>
<th>Name:</th>
<td>Carlos</td>
</tr>
<tr>
<th>Age:</th>
<td>22</td>
</tr>
</table>
<script>
function tableToJSON(table) {
var obj = {};
var row, rows = table.rows;
for (var i=0, iLen=rows.length; i<iLen; i++) {
row = rows[i];
obj[row.cells[0].textContent] = row.cells[1].textContent
}
return JSON.stringify(obj);
}
console.log(tableToJSON(document.getElementById('t0'))); // {"Name:":"Carlos","Age:":"22"}"
</script>
However, that is an ad hoc solution, so will need some work to be adapted to a more general case. It shows the concept though.
Note that there is no guarantee that the object properties will be returned in the same order as they appear in the table, you may get {"Age:":"22","Name:":"Carlos"}.
Assuming all you need is to get the first/second cells of each row as key/value pairs, you can use .reduce() to iterate of the rows and just grab the text content of .cells[0] and .cells[1] to use as each key/value pair:
var t = document.querySelector("table");
var j = [].reduce.call(t.rows, function(res, row) {
res[row.cells[0].textContent.slice(0,-1)] = row.cells[1].textContent;
return res
}, {});
document.querySelector("pre").textContent = JSON.stringify(j, null, 2);
<table>
<tr>
<th>Name:</th>
<td>Carlos</td>
</tr>
<tr>
<th>Age:</th>
<td>22</td>
</tr>
</table>
<pre></pre>
The Array.prototype.reduce method takes a collection and uses an accumulator to reduce it down to whatever state you want. Here we just reduce it to an object, so we pass one in after the callback.
For every row, we use the first cell's content as the object key, and the second cell's content as the value. We then return the object from the callback so that it's given back to us in the next iteration.
Finally, .reduce() returns the last thing we returned (which of course is the object we started with), and that's your result.
var t = document.querySelector("table");
var j = [].reduce.call(t.rows, function(res, row) {
res[row.cells[0].textContent.slice(0,-1)] = row.cells[1].textContent;
return res
}, {});
document.querySelector("pre").textContent = JSON.stringify(j);
<table>
<tr>
<th>Name:</th>
<td>Carlos</td>
</tr>
<tr>
<th>Age:</th>
<td>22</td>
</tr>
</table>
<pre></pre>
The Table-to-JSON library that you are using is expecting a different format in your table.
It is expecting a table with all of your headers in the first row, followed by the data in subsequent rows.
In other words, it's expecting your table to be structured like this
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr>
<td>Carlos</td>
<td>22</td>
</tr>
</table>
Here's a forked version of your JSFiddle in which this is working.

Categories

Resources