HTML table complex header - javascript

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

Related

Changing Day Date of <td> using JQuery

I am trying to change all the table Due Date values from the 31st to the 25th using jquery. The current code I am using is not working, as it is putting all values instead of the single value.
var dueDate1 = $("td:contains(/31/)").text();
var dueDate = dueDate1.replace(/31/g, "25");
$("td:contains(/31/)").text(dueDate);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Due Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Due Date">08/31/21</td>
<td data-title="Amount">$500</td>
</tr>
<tr>
<td data-title="Due Date">07/31/21</td>
<td data-title="Amount">$1500</td>
</tr>
<tr>
<td data-title="Due Date">06/31/21</td>
<td data-title="Amount">$2500</td>
</tr>
</tbody>
</table>
Your attempt is working on the entire set of data all at once.
$("td:contains(/31/)").text(); will return all the text of all the cells.
Instead, loop through the cells and update them individually.
$("td:contains('31')").each(function(idx, element){
$(element).text($(element).text().replace("31", "25"));
});
td { padding:2px; border:1px solid grey; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Due Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Due Date">08/31/21</td>
<td data-title="Amount">$500</td>
</tr>
<tr>
<td data-title="Due Date">07/31/21</td>
<td data-title="Amount">$1500</td>
</tr>
<tr>
<td data-title="Due Date">06/31/21</td>
<td data-title="Amount">$2500</td>
</tr>
</tbody>
</table>

d3.js : get td value

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>

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>

How can I use ng-repeat in a table body to encompass multiple rows?

I'm trying to transition from jsRender to AngularJs and can't seem to figure out how to generate multiple table rows with ng-repeat.
I need to generate two table rows per ng-repeat, these rows are related to each other. The second row is actually a hidden row that expands out like an accordion. This works perfectly fine with renderJs:
With renderJs:
<table>
<thead>
<tr>
<th>Stuff</th>
<th>Stuff2</th>
</tr>
</thead>
<tbody>
{{for myArray}} <!-- Creates two rows per item in array -->
<tr>
<td>{{data}}</td>
<td>{{data2}}</td>
</tr>
<tr class="special-row">
<td>{{otherData}}</td>
<td>{{otherData2}}</td>
</tr>
{{/for}}
</tbody>
</table>
With AngularJs:
<table>
<thead>
<tr>
<th>Stuff</th>
<th>Stuff2</th>
</tr>
</thead>
<tbody>
<div ng-repeat="element in myArray"> <!-- This gets removed since it's not a valid element for a table body -->
<tr>
<td>{{element.data}}</td>
<td>{{element.data2}}</td>
</tr>
<tr class="special-row">
<td>{{element.otherData}}</td>
<td>{{element.otherData2}}</td>
</tr>
</div>
</tbody>
</table>
I cannot have a <div> inside of my table body to put the ng-repeat on. How can I do this?
You should do it like this
<table>
<thead>
<tr>
<th>Stuff</th>
<th>Stuff2</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="element in myArray">
<td>{{element.data}}</td>
<td>{{element.data2}}</td>
</tr>
<tr ng-repeat-end class="special-row">
<td>{{element.otherData}}</td>
<td>{{element.otherData2}}</td>
</tr>
</tbody>
https://jsfiddle.net/feq6pe7m/1/
<body ng-app="SampleApp">
<table ng-controller="fcController" border="1px">
<thead>
<tr>
<th>Stuff</th>
<th>Stuff2</th>
</tr>
</thead>
<tbody ng-repeat="element in myArray">
<tr>
<td>{{element .Data1}}</td>
<td>{{element .Data2}}</td>
</tr>
<tr class="special-row">
<td>{{element.OtherData1}}</td>
<td>{{element.OtherData2}}</td>
</tr>
</tbody>
</table>
</body>

How to make a html-table sortable while not sorting specific rows?

I have a html-table, that has a header, that is supposed to be clickable to sort the rows on the clicked column. The tricky part here is, that there are some rows in the table, that shouldn't be sorted and the rows, that belong to that specific row should remain under that row. Here is some code so you get what I'm talking about.
<table>
<thead>
<tr>
<th>User</th>
<th>Item</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="5" style="text-align:left;">Peter</th>
</tr>
<tr>
<td></td>
<td>Apple</td>
<td>10</td>
</tr>
<tr>
<td></td>
<td>Pineapple</td>
<td>15</td>
</tr>
<tr>
<th colspan="5" style="text-align:left;">Stan</th>
</tr>
<tr>
<td></td>
<td>Banana</td>
<td>7</td>
</tr>
<tr>
<td></td>
<td>Orange</td>
<td>10</td>
</tr>
</tbody>
</table>
So if I click for example on the Item-Header, the Apple + Pineapple rows should remain between the Peter and the Stan row while being sorted. If I click on the User-Header, Peter and Stan should be sorted, while the Items Apple + Pineapple remain under the Peter row and the Banana and Orange Items remain under the Stan row ... I hope you get what I mean.
I have already tried it with the jquery tablesorter-plugin but I couldn't find any solution that was working for me.
You'll need to enclose each block of rows in a separate tbody.
Then clicking on User will only sort the tbodys, and clicking on the other ths will sort each tbody separately.
EDIT
The table should look like this:
<table>
<thead>
<tr>
<th>User</th>
<th>Item</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="5" style="text-align:left;">Peter</th>
</tr>
<tr>
<td></td>
<td>Apple</td>
<td>10</td>
</tr>
<tr>
<td></td>
<td>Pineapple</td>
<td>15</td>
</tr>
</tbody>
<tbody>
<tr>
<th colspan="5" style="text-align:left;">Stan</th>
</tr>
<tr>
<td></td>
<td>Banana</td>
<td>7</td>
</tr>
<tr>
<td></td>
<td>Orange</td>
<td>10</td>
</tr>
</tbody>

Categories