Add column sorting feature on treegrid html - javascript

I have a treegrid that is build like this:
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Number</th>
</tr>
</thead>
<tbody>
<tr class="treegrid-0">
<th>name2</th>
<th>type2</th>
<th>Number2</th>
</tr>
<tr class="treegrid-1">
<th>name1</th>
<th>type1</th>
<th>Number1</th>
</tr>
<tr class="treegrid-2 treegrid-parent-1" style="display:none;">
<th>name1-A</th>
<th>type1-A</th>
<th>Number1-A</th>
</tr>
<tr class="treegrid-3 treegrid-parent-1" style="display:none;">
<th>name1-B</th>
<th>type1-B</th>
<th>Number1-B</th>
</tr>
<tr class="treegrid-4">
<th>name0</th>
<th>type0</th>
<th>Number0</th>
</tr>
</tbody>
</table>
I would like to add the sorting option when i click on a column.
The sorting option has to be done only on the top parent.
It's a treegrid, so the expected behaviour is that the child nodes has to be moved also with the parent if the parent has to move.
How can i do that with JS ?

instead of doing all the hard work yourself, you can use the awesome js/jQuery library: datatables: https://datatables.net/
Just after defining your table, give it an ID
<table id = "myTable">..</table>
and then add the following snippet which will transform your table into an awesome table.
$(document).ready(function(){
$('#myTable').DataTable();
});
Cheers!

Related

How to reference a data attribute of another element?

I am trying to create a responsive table, that collapses from a horizontal to a vertical layout. For that I use a :before pseudo-element, that gets its value from a data attribute. Consider the following dom-structure:
td:before {
content: attr(data-th);
}
<table>
<thead>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</tr>
</thead>
<tbody>
<tr>
<td data-th="First">Alpha</td>
<td data-th="Second">Beta</td>
<td data-th="Third">Gamma</td>
<td data-th="Fourth">AnotherGreekLetter</td>
</tr>
</tbody>
</table>
This works fine and well, until you realize, that you have to write every single data-attribute by hand, since every new row of data requires the data-attribute.
Ideally I would like to have something like this:
td:before:nth-of-type(4n+1) {
content: attr(data-th:nth-of-type(4n+1));
}
td:before:nth-of-type(4n+2) {
content: attr(data-th:nth-of-type(4n+2));
}
<table>
<thead>
<tr>
<th data-th="First">First</th>
<th data-th="Second">Second</th>
<th data-th="Third">Third</th>
<th data-th="Fourth">Fourth</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alpha</td>
<td>Beta</td>
<td>Gamma</td>
<td>AnotherGreekLetter</td>
</tr>
</tbody>
</table>
where I am referencing the data-attribute of the th-nodes.
Now, as far as I know, there is no way of walking the dom-tree with just css, so I assume this would only be possible with javascript. Yet, I have never made use of the data-attribute, so I am hoping that I am wrong about that.
Can I make this work with (in descending order of preference): only css, php, javascript?
Don't think you can do this via CSS, you could probably use a slightly different approach if using jQuery too as you could use an ID to locate the values from the header and write it out to the body e.g.
<table>
<thead>
<tr data-id="1">
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr data-id="1"></tr>
</tbody>
</table>
And the jQuery:
$(document).ready(function() {
$("thead tr th").each(function( index ) {
$("tbody tr[data-id='" + $(this).parent().attr('data-id') + "']").append('<td>' + $(this).text() + '</td>');
});
});
http://codepen.io/anon/pen/kXdkyY
Hopefully this gives you an alternative idea of how you could loop through and grab data in a different way.

Angular Footable to show selected column data only

I was wondering if there is a way in Footable to show only the data colmuns for the one you have selected and hide the others.
For example, let's say the below are the list of albums (rows in my footable)
album-name-1
album-name-2
album-name-3
And if I select the album 1, it's data appears as follows:
album-name-1
track1
track2
track3
album-name-2
album-name-3
If I select album2, only those details appear and the previously expanded tracks from album 1 get collapsed as follows:
album-name-1
album-name-2
track1
track2
track3
album-name-3
I am using angularJS to use footable. Any suggestions on how to achieve this ? Like I know if I didn't use fancy stuff like Footable, I can achieve this by trigerring a click event using ng-click and pass on the index to show/hide only what I need. Just as this answer I asked previously: AngularJS display list right below the URL
But here, I am trying to do with the Footable plugin. Here is my html snippet for the same:
<table class="footable table table-stripped toggle-arrow-tiny" data-page-size="8">
<thead>
<tr>
<th data-toggle="all">Release Title</th>
<th data-toggle="all">Release Genre</th>
<th data-toggle="all">Classical</th>
<th data-hide="all">Tracks</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="album in vm.albums" footable>
<td ng-click="vm.editAlbum(album, $index)">{{album.data.title}}</small></td>
<td>{{album.data.genre}}</td>
<td ng-if!="album.data.classical">No</td>
<td ng-if="album.data.classical">Yes</td>
<td><br>
<li ng-repeat="track in album.data.tracks">
<a ng-click="vm.selectTrack(album, track)">{{track.title}}</a>
</li>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<ul class="pagination pull-right"></ul>
</td>
</tr>
</tfoot>
</table>

find child table selector from parent table - jQuery

I have a table structure like this. Fairly simple one.
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
At runtime I am binding a new row to this table for a particular rowclick. This new row contains a new table.
Now on clicking the row again, I want to be able to remove the newly added row(the new table).
I am using bootstrap table.
Here is what I have tried so far.
$('#myTable').on('click-row.bs.table', function (e, row, $element) {
//if ($element.has('#newlyAddedTable').length) { ....// did not work
if ($('#myTable').has('#newlyAddedTable').length) { // this removes the table on any row click. Not what I intend to do
{
$("#newlyAddedTable").remove();
} else {
// some operation...
}
}
I want to be able to remove the newly added table on the row it was created.
Just more explanation based on the Answers below:
<tr> ----------> if i click this
<td>
<table id="newlyAddedTable"> ---------> this is added
</table>
</td>
</tr>
<tr> ----------> if i again click this or maybe any other row in the table
<td>
<table id="newlyAddedTable"> ---------> this is removed
</table>
</td>
</tr>
Update: from OP's comment below it sounds like the best way to implement the new table is to use a class selector and not an id selector. The code below has been updated accordingly. ***Where previously there was an id for newTable there is a class ---> #newTable ===> .newTable:
Just change:
$('#myTable').has('#newlyAddedTable').length
To:
$('.newlyAddedTable', $element).length //element === clicked row -- see demo
vvvvv DEMO vvvvv
$('#myTable').bootstrapTable().on('click-row.bs.table', function(e, row, $element) {
if( $('.newTable', $element).length ) {
$('.newTable', $element).remove();
} else {
$('td:first', $element)
.append( '<table class="newTable"><tr><td>NEW TABLE</td></tr></table>' );
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.css" rel="stylesheet"/>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
Try replacing your remove code with this:
$(document).on("click", "#newlyAddedTable", function(){
$(this).remove();
});
The code above registers a click listener on the document. The second parameter filters those events for those with the target #newlyAddedTable. This way you don't have to register a new click handler every time you insert a row (as in #VimalanJayaGanesh's solution).
P.S. If you are adding HTML that looks like this:
<tr>
<td>
<table id="newlyAddedTable">
</table>
</td>
</tr>
Then you are probably actually wanting to remove the parent tr (not the table with the id). There are two ways to fix this.
You can change the selector that filters click events and so have the tr handle the click rather than the table element in my example code:
$(document).on("click", "tr:has(#newlyAddedTable)", function(){
You can leave the selector as is but grab the parent tr from the table and remove that changing the remove line above to:
$(this).parents("tr").first().remove()
or
$(this).parent().parent().remove()
As I don't have your complete code / fiddler, here is a possible solution.
Are you looking for something like this?
$('#add').on('click', function()
{
var newRow = '<tr CLASS="newrow"><td colspan="3"><table><tr><td>Test</td><td>User</td><td>test#example.com</td></table></td></tr>'
$('#myTableBody').append(newRow);
Remove()
});
function Remove()
{
$('.newrow').off('click').on('click', function()
{
$(this).remove();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody id="myTableBody">
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
<button type='button' id='add'>Add</button>
Note:
The following line indicates that,
$('.newrow').off('click').on('click', function()
the click event will be binded to the new row only once.
The reason for adding 'off('click') is, when you are dynamically adding rows (with common class 'newrow') to the table, the events will be binded several times. To avoid that, remove the previously binded click event and add a new one.

how to get first table row "<td></td>" text which are visible using jquery

Here I have a table
<table id="table">
<thead>
<tr>
<th>Name</th>
<th>Course</th>
</tr>
</thead>
<tbody>
<tr style="display:none">
<td>jones</td>
<td>.net</td>
</tr>
<tr style="display:none">
<td>James</td>
<td>SAP</td>
</tr>
<tr>
<td>Charles</td>
<td>Java</td>
</tr>
</tbody>
</table>
I want to get text of first row first td text which are visible using jquery, by
above table, I want result as "Charles".
How can get it. I have tried like
$("#table").closest('tbody').children('tr:first').find('td:first').text()
but not getting result.how can I?
Try to use :visible selector to get the visible rows,
$("#table tbody tr:visible:first td:first").text()
To get the visible one use the according :visible selector that jquery ships:
$('#table > tbody > tr:visible:first > td:first').text();
This is Worked for Me.
$('#table> tbody > tr:visible').first().find('td').first().text();

delete all datatables using jQuery

so, I am using datatables along with jQuery, and am a bit stumped as to why this is not working. My HTML looks like this:
<table id="surnamePrimaryPartitionTable" border=1 class="display partitionDisplay">
<caption>Partitions</caption>
<thead>
<tr style="background-color: #afeeee;">
<th>Partition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
I have several tables, each of which follows a similar format, and each of which uses the partitionDisplay class (really just a class that I use so that I can select all the tables later using jQuery).
So, the problem arises when I try to destroy the datatables. Here is what I have:
function DeletePartitionInformation(data) {
jQuery(".partitionDisplay").each(function(){
jQuery(this).dataTable().fnDestroy();
});
jQuery("table tbody").each(function() {
jQuery(this).html("");
})
}
This code seems to work correctly for the first table, but throws an exception and doesn't work on any subsequent tables. The javascript error message I am getting is the following:
Uncaught TypeError: Cannot read property 'asSorting' of undefined
A quick Google search on this error says that it generally arises from having elements nested in a tag. This does not appear to be the problem, however. I will post the code for the other three tables to demonstrate this:
<table id="surnamePrimarySubpartitionTable" border=1 class="display partitionDisplay">
<caption>SubPartitions</caption>
<thead>
<tr style="background-color: #afeeee;">
<th>Partition</th>
<th>SubPartition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
<th>Begin</th>
<th>End</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table id="givenNullSurnamePartitionTable" border=1 class="display partitionDisplay">
<caption>Partitions</caption>
<thead>
<tr style="background-color: #98fb98;">
<th>Partition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table id="givenNullSurnameSubpartitionTable" border=1 class="display partitionDisplay">
<caption>SubPartitions</caption>
<thead>
<tr style="background-color: #98fb98;">
<th>Partition</th>
<th>SubPartition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
<th>Begin</th>
<th>End</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
One final note: I am actually able to get the behavior I want if I use the below code. Obviously I would prefer not to, however, since I'd really like to loop over the elements rather than hard-code the element id's in.
function DeletePartitionInformation(data) {
jQuery("#surnamePrimarySubpartitionTable").dataTable().fnDestroy();
jQuery("#surnamePrimaryPartitionTable").dataTable().fnDestroy();
jQuery("#givenNullSurnameSubpartitionTable").dataTable().fnDestroy();
jQuery("#givenNullSurnamePartitionTable").dataTable().fnDestroy();
jQuery("table tbody").each(function() {
jQuery(this).html("");
})
}
Uncaught TypeError: Cannot read property 'asSorting' of undefined
This seems to suggest it may be trying to destroy dataTables that weren't created.
The static fnTables should give you an Array of only the <table> elements with a dataTable:
var tables = $.fn.dataTable.fnTables(true);
$(tables).each(function () {
$(this).dataTable().fnDestroy();
});

Categories

Resources