d3.js : get td value - javascript

I am new with d3.js
The problem i am facing is that i am unsure of how to get the value of td.
html
<table class="table">
<thead><tr>
<th>S No</th>
<th>Name</th>
<th>Credit</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>Arun</td>
<td>Positive</td>
</tr>
<tr>
<td>3</td>
<td>Mickey</td>
<td>Negetive</td>
</tr>
<tr>
<td>4</td>
<td>Zack</td>
<td>Positive</td>
</tr>
</tbody>
I read the documentation on d3.js but i couldnt find the documentation on how can i retrieve data from the table .
Let's say that i would want to append a div with background color (green) on Credit that has value of negetive , how could we achieve this
This is what i tried
let selection = d3.selectAll("tr")
console.log("Get Table " + selection)
let headerElement = selection.nodes()[0];
let output = selection.selectAll("td")
i tried to printout the value of selected column with console.log(output["0"][1])
but i am receving error.
Thank you in advance

Since D3 v4 selections are objects, not arrays anymore, so you cannot treat them like you did in output["0"][1].
The idiomatic way to loop a selection is using selection.each. For instance:
const tds = d3.selectAll("td")
.each(function() {
console.log(d3.select(this).text());
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<table class="table">
<thead>
<tr>
<th>S No</th>
<th>Name</th>
<th>Credit</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>Arun</td>
<td>Positive</td>
</tr>
<tr>
<td>3</td>
<td>Mickey</td>
<td>Negetive</td>
</tr>
<tr>
<td>4</td>
<td>Zack</td>
<td>Positive</td>
</tr>
</tbody>
If you don't want another selection, d3.select(this).text() is the same of this.innerHTML.
Therefore, you can use the same each to set the "background color (green) on Credit that has value of negetive", as you said:
const tds = d3.selectAll("td")
.each(function() {
d3.select(this).style("background-color", this.innerHTML === "Positive" ? "green" : null)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<table class="table">
<thead>
<tr>
<th>S No</th>
<th>Name</th>
<th>Credit</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>Arun</td>
<td>Positive</td>
</tr>
<tr>
<td>3</td>
<td>Mickey</td>
<td>Negetive</td>
</tr>
<tr>
<td>4</td>
<td>Zack</td>
<td>Positive</td>
</tr>
</tbody>

Related

Dynamically add column to table and it's td's

I have a table that is already defined and populated. Now what I'm trying to do is to find a specific column and after that create a new column, at the moment I have the code to handle this:
$(document).ready(function() {
something();
});
function something() {
var newTh = "";
var th = $(`#tblTable th[data-something="1"]`).last();
newTh = `<th data-something="1-1">
New Column
</th>`;
th.after(newTh);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblTable">
<thead>
<tr>
<th>Id</th>
<th data-something="1">Name</th>
<th>Price</th>
</tr>
</thead>
<tbody id="tblBody">
<tr>
<td>1</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>3</td>
<td>a</td>
<td>100</td>
</tr>
</tbody>
</table>
The column is added properly but it's keeping the value from the pre-existing column. What can I do to move the content after/before adding a new column?
You can get the index of th element, and then you can find each tr to append New Column td value. Like below:
$(document).ready(function() {
something();
});
function something() {
var newTh = "";
var th = $(`#tblTable th[data-something="1"]`).last();
var index = th.index();
newTh = `<th data-something="1-1">New Column</th>`;
th.after(newTh);
$("#tblBody").find("tr").each(function(){
var tr = $(this);
tr.find("td").eq(index).after(`<td>new column value</td>`);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblTable">
<thead>
<tr>
<th>Id</th>
<th data-something="1">Name</th>
<th>Price</th>
</tr>
</thead>
<tbody id="tblBody">
<tr>
<td>1</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>3</td>
<td>a</td>
<td>100</td>
</tr>
</tbody>
</table>
The easiest method would be to add another <td> in each <tr> and copy the text into the new <td>.
This works because each <th> must be at the same index as each <tr>.
$(document).ready(function() {
something();
});
function something() {
const th = $('#tblTable th[data-something="1"]').last();
th.after('<th data-something="1-1">New Column</th>');
$('#tblTable tbody').children().each(function() {
$(this).children().eq(th.index()).after('<tr></tr>');
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblTable">
<thead>
<tr>
<th>Id</th>
<th data-something="1">Name</th>
<th>Price</th>
</tr>
</thead>
<tbody id="tblBody">
<tr>
<td>1</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td>a</td>
<td>100</td>
</tr>
<tr>
<td>3</td>
<td>a</td>
<td>100</td>
</tr>
</tbody>
</table>

I want to show the user only 3 columns in UI, But want to Export all table data to excel, So how can I hide the column based on the header text?

This is My Table; I want to show only first 3 columns to User but I want to export all data to Excel. First how can I hide the columns based on the header text ?
<table id="ibms" class="table table-bordered">
<thead>
<tr>
<th>IBMS Code</th>
<th>Location Description</th>
<th>FMS Location Code</th>
<th>FMS Location Description</th>
<th>Site</th>
<th>Level</th>
<th>Area</th>
<th>Zone</th>
<th>Unit</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>IB-0078</td>
<td>Hello</td>
<td>542</td>
<td>Description here</td>
<td>Industry</td>
<td>1</td>
<td>Arizona</td>
<td>five</td>
<td>2</td>
<td>USA</td>
</tr>
<tr>
<td>IB-552</td>
<td>World</td>
<td>576</td>
<td>Description here</td>
<td>Textile</td>
<td>2</td>
<td>Texas</td>
<td>one</td>
<td>10</td>
<td>USA</td>
</tr>
</tbody>
</table>
JS code:
var hidecolumns = $("#ibms").DataTable();
function locationhie(hidecolumns){
var u = $("th:contains(FMS Location Description)").index();
hidecolumns.column(u).visible( false );
}
function locationhieSite(hidecolumns){
var a = $("th:contains(Site)").index();
hidecolumns.column(a).visible( false );
}
function locationhielevel(hidecolumns){
var b = $("th:contains(Level)").index();
hidecolumns.column(b).visible( false );
}
function locationhieArea(hidecolumns){
var c = $("th:contains(Area)").index();
hidecolumns.column(c).visible( false );
}
function locationhieZone(hidecolumns){
var d = $("th:contains(Zone)").index();
hidecolumns.column(d).visible( false );
}
function locationhieUnit(hidecolumns){
var e = $("th:contains(Unit)").index();
hidecolumns.column(e).visible( false );
}
function locationhieLocation(hidecolumns){
var f = $("th:contains(Location)").index();
hidecolumns.column(f).visible( false );
}
Can Anyone help me how to achieve this ? Is there any alternative solutions available to do this in a single function?
You can use CSS :nth-child pseudo-class selector to hide some columns, no JS needed:
.locations td:nth-child(n+4),
.locations th:nth-child(n+4) {
display: none;
}
<table id="ibms" class="table table-bordered locations">
<thead>
<tr>
<th>IBMS Code</th>
<th>Location Description</th>
<th>FMS Location Code</th>
<th>FMS Location Description</th>
<th>Site</th>
<th>Level</th>
<th>Area</th>
<th>Zone</th>
<th>Unit</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>IB-0078</td>
<td>Hello</td>
<td>542</td>
<td>Description here</td>
<td>Industry</td>
<td>1</td>
<td>Arizona</td>
<td>five</td>
<td>2</td>
<td>USA</td>
</tr>
<tr>
<td>IB-552</td>
<td>World</td>
<td>576</td>
<td>Description here</td>
<td>Textile</td>
<td>2</td>
<td>Texas</td>
<td>one</td>
<td>10</td>
<td>USA</td>
</tr>
</tbody>
</table>
.locations td:nth-child(n+4) selects any td element within an element of .locations class starting from the index of 4. Indices are calculated from the first occurence of td in its parent, and the first index is 1.

How do I enter a numeric number in sequence in a table?

There is a table that is sorted by clicking from larger to smaller values. How to make sure that the ordinal number of the value is always between 1 and 5 after sorting the table?
That is, the numerical order should always be between 1 and 5 and should not be sorted.
$(document).ready(function() {
var $table = $('#simpleTable').stupidtable();
$table.find('thead th[data-sort]').on('click', function() {
$(this).eq(0).stupidsort();
});
});
<table id="simpleTable">
<thead>
<tr>
<th data-sort="int">#</th>
<th data-sort="int">int</th>
<th data-sort="float">float</th>
<th data-sort="string">string</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>15</td>
<td>18</td>
<td>banana</td>
</tr>
<tr>
<td>2</td>
<td>95</td>
<td>36</td>
<td>coke</td>
</tr>
<tr>
<td>3</td>
<td>2</td>
<td>152.5</td>
<td>apple</td>
</tr>
<tr>
<td>4</td>
<td>53</td>
<td>88.5</td>
<td>zebra</td>
</tr>
<tr>
<td>5</td>
<td>195</td>
<td>858</td>
<td>orange</td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stupidtable/1.1.3/stupidtable.min.js"></script>
Never heard of - and therefore never used - stupidtable but it doesn't look like there is a call-back event once the sorting has completed.
So instead, I've used a timeout as part of the click event.
The within the timeout finds all the first-child <td> elements, and uses the index of each to set the text of the element.
As the stupidsort code does the sort 10-milliseconds after the client event, I've had to make it 20 in the code for it to work...
$(function() {
var $table = $('#simpleTable').stupidtable();
$table.find('thead th[data-sort]').on('click', function() {
$(this).eq(0).stupidsort();
// After a short period, set the values
setTimeout(function() {
$table.find("tbody tr td:first-child").each(function(i, v) {
$(this).text((i + 1).toString());
});
}, 20);
});
});
<table id="simpleTable">
<thead>
<tr>
<th data-sort="int">#</th>
<th data-sort="int">int</th>
<th data-sort="float">float</th>
<th data-sort="string">string</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>15</td>
<td>18</td>
<td>banana</td>
</tr>
<tr>
<td>2</td>
<td>95</td>
<td>36</td>
<td>coke</td>
</tr>
<tr>
<td>3</td>
<td>2</td>
<td>152.5</td>
<td>apple</td>
</tr>
<tr>
<td>4</td>
<td>53</td>
<td>88.5</td>
<td>zebra</td>
</tr>
<tr>
<td>5</td>
<td>195</td>
<td>858</td>
<td>orange</td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stupidtable/1.1.3/stupidtable.min.js"></script>

I want the table to be sorted in a particular order on load using tablesorter

I have a table which displays like this when I load the page.
But I want the subjects to be in a particular order(math,history,science and physics) but the professor names should be sorted in ascending order.
Can this be done using tablesorter's custom sort?
$('table').tablesorter({
theme: 'blue'
});
<link href="https://mottie.github.io/tablesorter/css/theme.blue.css" rel="stylesheet"/>
<script src="https://mottie.github.io/tablesorter/js/jquery.tablesorter.widgets.js"></script>
<script src="https://mottie.github.io/tablesorter/js/jquery.tablesorter.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="tablesorter">
<thead>
<tr>
<th>subject</th>
<th>professor</th>
</tr>
</thead>
<tbody>
<tr>
<td>math</td>
<td>Jordan</td>
</tr>
<tr>
<td>math</td>
<td>Kent</td>
</tr>
<tr>
<td>math</td>
<td>Wayne</td>
</tr>
<tr>
<td>history</td>
<td>Richards</td>
</tr>
<tr>
<td>history</td>
<td>Xavier</td>
</tr>
<tr>
<td>science</td>
<td>Arthur</td>
</tr>
<tr>
<td>science</td>
<td>John</td>
</tr>
<tr>
<td>physics</td>
<td>Steve</td>
</tr>
<tr>
<td>physics</td>
<td>Wade</td>
</tr>
</tbody>
</table>
JSFiddle
Any help is appreciated. Thanks in advance.
To set a custom sort order you should add your own parser. Check this example in the docs.
Then, to order by default both columns, just pass sortList to your configuration object.
And to add an additional forced sort that will be appended to the dynamic selections by the user use sortAppend.
Note that in the snippet below I have switched "Steve" and "Wade" so you can see that the sortList is working.
// add parser through the tablesorter addParser method
$.tablesorter.addParser({
// set a unique id
id: 'subjects',
is: function(s, table, cell, $cell) {
// return false so this parser is not auto detected
return false;
},
format: function(s, table, cell, cellIndex) {
// format your data for normalization
return s.toLowerCase()
.replace(/math/,0)
.replace(/history/,1)
.replace(/science/,2)
.replace(/physics/,3);
},
// set type, either numeric or text
type: 'numeric'
});
$('table').tablesorter({
theme: 'blue',
sortList: [[0,0], [1,0]],
sortAppend : [[1,0]]
});
<link href="https://mottie.github.io/tablesorter/css/theme.blue.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://mottie.github.io/tablesorter/js/jquery.tablesorter.js"></script>
<table class="tablesorter">
<thead>
<tr>
<th class="sorter-subjects">subject</th>
<th>professor</th>
</tr>
</thead>
<tbody>
<tr>
<td>math</td>
<td>Jordan</td>
</tr>
<tr>
<td>math</td>
<td>Kent</td>
</tr>
<tr>
<td>math</td>
<td>Wayne</td>
</tr>
<tr>
<td>history</td>
<td>Richards</td>
</tr>
<tr>
<td>history</td>
<td>Xavier</td>
</tr>
<tr>
<td>science</td>
<td>Arthur</td>
</tr>
<tr>
<td>science</td>
<td>John</td>
</tr>
<tr>
<td>physics</td>
<td>Wade</td>
</tr>
<tr>
<td>physics</td>
<td>Steve</td>
</tr>
</tbody>
</table>

HTML table complex header

Im pretty new to web dev, so please excuse my probable stupidity. and ive got a small display thing. I have a table with a table in it as one of the tds. I want the inner table part of it to have like a composite heading. In the example below the heading would be Hobbies, and the under it the headings of the hobbies table that would NUMBER, HOBBY and DESCRIPTION. So if you look at the entire table the headings are NAME, SURNAME, JOB and then on a level higher HOBBIES with the sub headings on the same level as the first ones. I hope this makes sense. How can i achieve something like this
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Job</th>
<th>Hobbies</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>McJohnson</td>
<td>Dentist</td>
<td>
<table>
<tbody>
<tr>
<td>1</td>
<td>Lego</td>
<td>I like to play Lego</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Something like this? could be styled better but you get the idea...you will have to use js I think if you want the heading moved up seperate from the second table
td table{display:none;}
tr td:nth-child(4){background-color:gray;}
td:hover table{position:absolute;left:200px;background-color:yellow;display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Job</th>
<th>Hobbies</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>McJohnson</td>
<td>Dentist</td>
<td>Hover Me
<table>
<thead>
<tr>
<th>Number</th>
<th>Hobby</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Lego</td>
<td>I like to play Lego</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>John</td>
<td>McJohnson</td>
<td>Dentist</td>
<td>Hover Me
<table>
<thead>
<tr>
<th>Number</th>
<th>Hobby</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Lego</td>
<td>I like to play Lego</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
/th

Categories