html table to json - modify cells - javascript

Well, I have following html table:
<table id="people" border="1">
<thead>
<tr>
<th>Name</th>
<th>Places</th>
<th>Grade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Oscar</td>
<td>New York</td>
<td>16.5</td>
</tr>
<tr>
<td>Antonio</td>
<td>
<p>New York</p>
<p>Chicago</p>
<p>Toronto</p>
</td>
<td>14</td>
</tr>
<tr>
<td>Jessica</td>
<td>New York</td>
<td>19</td>
</tr>
</tbody>
Now when I use the jquery tableToJson function I get this output:
[
{"Name":"Oscar","Places":"New York","Grade":"16.5"},
{"Name":"Antonio","Places":"New York\n\t\t\tChicago\n\t\t\t\tToronto","Grade":"14"},
{"Name":"Jessica","Places":"New York","Grade":"19"}
]
Now look at Antonio, the function created
{"Name":"Antonio","Places":"New York\n\t\tChicago\n\t\t\t\tToronto","Grade":"14"}
But instead of
\n
I want places also to be displayed as a JSON array like this:
{"Name":"Antonio","Places":["New York","Chicago","Toronto"],"Grade":"14"}
I know there are options described here (https://github.com/lightswitch05/table-to-json), but I don't know which one to use, or how to use them, as it is not really documented, how to use them in detail.
Any help would be really appreciated :-)

If you want to update the existing array try using this
var places = [
{"Name":"Oscar","Places":"New York","Grade":"16.5"},
{"Name":"Antonio","Places":"New York\n Chicago\n Toronto","Grade":"14"},
{"Name":"Jessica","Places":"New York","Grade":"19"}
];
for(var x=0;x<places.length;x++){
places[x].Places = places[x].Places.split("\n");
}
console.log(places);

Related

Js Jquery td auto numbering with custom locale language

Is there any way to auto numbering table data with local or custom language. I'm a Bengali, I know how to auto numbering table each row 1st data using css and js. But I don’t know how to use custom number, e.g. Bangla or Arabic.
Look at my code:
<table border="1">
<tr>
<td>blue</td>
</tr>
<tr>
<td>red</td>
</tr>
<tr>
<td>black</td>
</tr>
</table>
I want something like that;
১. Apple
২. Banana
৩. Orange
৪. Strawberry
How can I get that using Javascript / jquery.. Without adding any third party plugin.
You need to use toLocaleString() method or Intl.NumberFormat() constructor with the locale language as a parameter.
For example.
For Arabic numbers num.toLocaleString('ar-EG').
For Bangla numbers num.toLocaleString('bn-BD')
const table = document.querySelector('table');
[...table.rows].forEach((row, index) => {
row.cells[0].textContent = (index + 1).toLocaleString('bn-BD')
})
<table border="1">
<tr>
<td></td>
<td>blue</td>
</tr>
<tr>
<td></td>
<td>red</td>
</tr>
<tr>
<td></td>
<td>black</td>
</tr>
A CSS only solution would be using the CSS counter(..) function and pass the counter-style parameter (list-style-type) for 'bengali'.
E.g. td::before { content: counter(some-counter, bengali) }
Reference: MDN: counter() and MDN: list-style-type
table {
counter-reset: row 0;
}
tr {
counter-increment: row;
}
td::before {
content: counter(row, bengali) '. ';
}
<table border="1">
<tr>
<td>blue</td>
</tr>
<tr>
<td>red</td>
</tr>
<tr>
<td>black</td>
</tr>
</table>

Changing Table's tr:even with a different background color

I know how to do this with jquery, by doing this:
$("#rateTable tr:even").css("background", "#e7edea");
However, the format I am using will not allow jquery. I tried the code below, but it is saying that the style is null. Does anyone see what I am doing wrong?
document.getElementById("rateTable tr:even").style.background = "#e7edea";
<table id="rateTable">
<tr>
<td>Blue</td>
<td>Green</td>
</tr>
<tr>
<td>Red</td>
<td>Purple</td>
</tr>
<tr>
<td>Teal</td>
<td>Yellow</td>
</tr>
</table>
You don't really need JavaScript for this. It could been done in plain CSS with the nth-child pseudo-class.
tr:nth-child(even) {
background: #E7EDEA;
}
<table id="rateTable">
<tr>
<td>Blue</td>
<td>Green</td>
</tr>
<tr>
<td>Red</td>
<td>Purple</td>
</tr>
<tr>
<td>Teal</td>
<td>Yellow</td>
</tr>
</table>
You can do it with #rateTable tr:nth-of-type(even) as your selector. document.selectElementById() only works when you give it the exact string being used as an id, not a CSS selector. I would do it with CSS because it will update automatically and is likely faster, but you can do it in JS if you want:
const evenRows = document.querySelectorAll("#rateTable tr:nth-of-type(even)")
for (const row of evenRows) row.style.background = "#e7edea"
<table id="rateTable">
<tr>
<td>Blue</td>
<td>Green</td>
</tr>
<tr>
<td>Red</td>
<td>Purple</td>
</tr>
<tr>
<td>Teal</td>
<td>Yellow</td>
</tr>
<tr>
<td>Orange</td>
<td>Pink</td>
</tr>
</table>
Try to use querySelectorAll and next iterate over received collection to change background. See below:
var trToChange = document.querySelectorAll("#rateTable tr:nth-child(even)");
for(var i = 0; i < trToChange.length; i++){
trToChange[i].style.background = "#e7edea";
}

Clone table and filter out rows

Hello I got a question regarding cloning a table.
I want to filter out some specific results and output those results.
Let me explain myself better with HTML code:
<table class="table table-striped" id="ProfileList2">
<tbody>
<tr>
<td>21</td>
<td>2014-02-28 21:12:12</td>
<td>20</td>
<td>one</td>
<td>166</td>
</tr>
<tr>
<td>22</td>
<td>2014-03-01 14:04:35</td>
<td>20</td>
<td>one</td>
<td>0</td>
</tr>
<tr>
<td>23</td>
<td>2014-03-03 15:22:56</td>
<td>20</td>
<td>one</td>
<td>21</td>
</tr>
<tr>
<td>24</td>
<td>2014-03-03 17:15:56</td>
<td>20</td>
<td>one</td>
<td>21</td>
</tr>
<tr>
<td>25</td>
<td>2014-03-03 17:50:49</td>
<td>20</td>
<td>one</td>
<td>0</td>
</tr>
<tr>
<td>26</td>
<td>2014-03-05 17:33:42</td>
<td>20</td>
<td>one</td>
<td>24</td>
</tr>
</tbody>
</table>
<p class="result"></p>
In my Javascript I want to filter out all the results that have within the last <td> or every <tr> the value 0.
var $mainTable = $("#ProfileList2");
var $training = $mainTable.clone("tr td:nth-child(5):not(:contains('0'))");
$('p').append($training);
This code will clone a direct copy without doing any filtering.
If I change the clone function to, for example: find function, it will only return the table-data: 166 21 21 24.
Is there any function available that will return the whole table-row instead of only the table-data?
JSFIDDLE OVER HERE
To grab the table rows, change this:
$mainTable.find("tr td:nth-child(5):not(:contains('0'))")
… to this:
$mainTable.find("tr td:nth-child(5):not(:contains('0'))").parent()
Also note that a paragraph element cannot contain a table element according to the specification. (Although most browsers allow it.) Changing it to a div would be better.
Fiddle 1
Also note that the contains selector will search for a 0 within the cell, so it will match cells containing "160" as well as those containing "0."
Instead, you could filter to exclude only cells that equal "0":
$mainTable
.find("tr td:nth-child(5)")
.filter(function() {return $(this).text() != '0';})
.parent();
Fiddle 2
Well, you could copy the whole thing and then filter out what you don't like, how about that?
var copy = $("#ProfileList2").clone();
$('p').append(copy);
copy.find("tr td:nth-child(5):contains('0')").parent().remove();
Make note that it is not a good idea to have multiple elements with the same id.

JQuery Tablesorter - Filter by clicking link

I'm using #Mottie's excellent fork of Tablesorter and would like to be able to filter table column(s) with external links.
It isn't strictly necessary, but I'd like to make multiple clicks toggle the filter on and off. Alternatively, I could always add an All Records link that resets the column(s).
I don't need to combine filters in a single column. In other words, the data wouldn't be both January and October.
I found a table sort with external link demo, but that one sorts, not filters, and it doesn't toggle.
I also found a table filter with buttons demo which is pretty close. However, as I mentioned, I'd really like links instead, would like to have the links toggle if possible, and don't need the filters to combine.
Thanks in advance.
This was actually a lot easier than I thought. Here's a working demo that came directly from Mottie's demo code above. I replaced the buttons with links, renamed the associated class so it made more sense and replaced the class on the JavaScript function to match the one on the links.
Fair warning: I don't claim to know everything, so my modifications could have very silly errors.
$('.link-filter').click(function() {
var filters = $('table').find('input.tablesorter-filter'),
col = $(this).data('filter-column'),
txt = $(this).data('filter-text');
// filters.val('');
filters.eq(col).val(txt).trigger('search', false);
});
The filters in the various columns combine, but I only need a single column filter at the moment, so that's not really an issue for me.
Country:<br>
All Countries |
Netherlands |
Belgium |
Germany
<br /><br />
<table id="festivaloverzichttable" class="tablesorter">
<thead>
<tr>
<th width="17%" data-placeholder="Search...">Event</th>
<th width="18%" data-placeholder="Search...">Date</th>
<th width="9%" data-placeholder="Search...">Duration</th>
<th width="12%" data-placeholder="Search...">Place</th>
<th width="10%" data-placeholder="Search...">Country</th>
<th data-placeholder="Zoek...">Genre(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Event 1</td>
<td data-date="06-02">TBA</td>
<td>2</td>
<td>Oisterwijk</td>
<td>Netherlands</td>
<td>Hardstyle</td>
</tr>
<tr>
<td>Event 2</td>
<td data-date="10-11">11 October t/m 13 October</td>
<td>3</td>
<td>Volkel</td>
<td>Netherlands</td>
<td>Pop, Rock, Urban, Electronic</td>
</tr>
<tr>
<td>Event 3</td>
<td data-date="06-02">TBA</td>
<td>1</td>
<td>Amsterdam</td>
<td>Netherlands</td>
<td>Electronic</td>
</tr>
<tr>
<td>Event 4</td>
<td data-date="09-01">TBA</td>
<td>1</td>
<td>Utrecht</td>
<td>Netherlands</td>
<td>Electronic, Urban</td>
</tr>
<tr>
<td>Event 5</td>
<td data-date="07-06">6 July - 7 July</td>
<td>2</td>
<td>Beek en Donk</td>
<td>Netherlands</td>
<td>Electronic, Hardstyle</td>
</tr>
...
</tbody>
</table>​
Javascript
$("#festivaloverzichttable").tablesorter({
sortList: [[0, 0]],
widgets: ['zebra', 'filter', 'saveSort'],
widgetOptions: {
filter_reset: 'button.reset'
}
});
$('.link-filter').click(function() {
var filters = $('table').find('input.tablesorter-filter'),
col = $(this).data('filter-column'),
txt = $(this).data('filter-text');
// filters.val('');
filters.eq(col).val(txt).trigger('search', false);
});

Calculate cell value based on formula and values in other cells

I have a table in a HTML file, and I want to calculate one cell's value based on other cells' values and a cell value as a formula. Take a look at this picture:
In my table, I have 1900 ratios and three factors in three columns. How I can calculate the result column values based on their respective formula column value?
Note: I use only *, /, +, and - in my formulas. Also, the table has an ID (ratiotable), but the <tr> and <td> don't have any ID or class names assigned to them.
If you know another webpage that did something like this, please let me see this.
Thank you very much.
Edit: The HTML code is like this. Note, I snipped a number of the rows. The actual number of rows is 1900:
<table>
<thead>
<tr>
<th>Ratio Name</th>
<th>Factor1</th>
<th>Factor2</th>
<th>Factor3</th>
<th>Formula</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>22</td>
<td>11</td>
<td></td>
<td>Factor1/Factor2</td>
<td></td>
</tr>
<tr>
<td>Name2</td>
<td>22</td>
<td>33</td>
<td>11</td>
<td>Factor1/Factor2*Factor3</td>
<td></td>
</tr>
<tr>
<td>Name1</td>
<td>12</td>
<td></td>
<td>4</td>
<td>(Factor1+Factor2)/Factor3</td>
<td></td>
</tr>
</tbody>
This was a really interesting challenge. I've put together a little JSFiddle here that does what you describe. It essentially replaces the string parts of the formula with their value counterparts, then evals the result. Hopefully this helps!
My Markup
<table>
<thead>
<tr>
<th>Ratio Name</th>
<th>Factor1</th>
<th>Factor2</th>
<th>Factor3</th>
<th>Formula</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>22</td>
<td>11</td>
<td></td>
<td>Factor1/Factor2</td>
<td></td>
</tr>
<tr>
<td>Name2</td>
<td>22</td>
<td>33</td>
<td>11</td>
<td>Factor1/Factor2*Factor3</td>
<td></td>
</tr>
<tr>
<td>Name1</td>
<td>12</td>
<td></td>
<td>4</td>
<td>(Factor1+Factor2)/Factor3</td>
<td></td>
</tr>
</tbody>
</table>
​
My JavaScript
$(function() {
$('tbody tr').each(function() {
var $this = $(this),
f1 = $this.find('td').eq(1).text() || 0,
f2 = $this.find('td').eq(2).text() || 0,
f3 = $this.find('td').eq(3).text() || 0,
formula = $this.find('td').eq(4).text(),
resultTd = $this.find('td').last();
formula = formula.replace('Factor1',f1)
.replace('Factor2',f2)
.replace('Factor3',f3);
resultTd.text(eval(formula));
});
});​
loop through all rows and use javascript eval() function
function cellValue(x,y){
return $('#ratiotable').find('tr:eq('+(y+1)+')>td:eq('+(x+1)+')').text();
}
function setCellValue(x,y,s){
$('#ratiotable').find('tr:eq('+(y+1)+')>td:eq('+(x+1)+')').text(s);
}
$(function(){
$.each($('#ratiotable tr'),function(i,tr){
var Factor1 = parseInt(cellValue(0,i));
var Factor2 = parseInt(cellValue(1,i));
var Factor3 = parseInt(cellValue(2,i));
var Formula = $.trim(cellValue(3,i));
var Result = eval(Formula);
setCellValue(4,i,Result);
});
});
like this

Categories