I am trying to get the column name when the user clicks on the jquery datatable's footer cell.
I tried to follow this: https://datatables.net/forums/discussion/24593/retreive-column-idx-when-clicking-on-header
And, https://datatables.net/reference/type/column-selector
But, I am getting 'undefined' with the following code,
$('#myTable').on( 'click', 'tfoot th', function () {
var index = table.column( this ).index(); //index is returned as undefined
} );
Any suggestion will be greatly appreciated.
CAUSE
Columns can be selected only if you use header th nodes or table body td nodes, that's why it doesn't work.
SOLUTION
Try the code below to get actual column index.
Modifier :visible is needed because $(this).index() operates with actual DOM elements and returns index of the th node among currently visible columns. However jQuery DataTables may remove columns from DOM when using various extensions, such as Responsive, Buttons - Column visibility, etc, and actual column index may differ from index of the column in DOM.
$('#example').on( 'click', 'tfoot th', function () {
var index = table.column($(this).index() + ':visible').index();
});
See this example for code and demonstration.
Related
Let's say that I have a added 2 children to a datatable row using row().child()
row.child([item1, item2]);
Later, I would like to show one of the children, without regenerating it. row.child.show() works fine, except that it shows both childs.
How to show a specific child from row.child?
Fiddle: http://jsfiddle.net/mg22w6o5/
Try clicking the first generated row. How to only show one of the childs?
My current solution if it helps anyone: http://jsfiddle.net/mg22w6o5/4/
There is no direct API to selectively show or hide child rows. There is row().child() that returns jQuery collection of all child <tr> rows though but it's not helpful in this situation.
The possible solution would be to recreate child rows as shown below:
var dummyChilds = [['child 1'], ['child 2']];
table.row(0).child(dummyChilds);
$('#example tbody').on( 'click', 'tr', function () {
var row = table.row(this);
var children = row.child();
if(children){
var child = row.child;
// Recreate children rows
row.child(dummyChilds[0]);
if ( row.child.isShown() ) {
child.hide();
} else {
child.show();
}
}
} );
See this JSFiddle for demonstration.
You can get it by number of the node:
row.childNodes[0];
If you have unique id's or classes there is also find() in jquery.
I have table which is being dynamically created.
I would like to try not to have any more attributes in the table (like an ID field).
It is a multilevel table where all the TableRows should be expandable and collapse on click in any of the TD in each row.
$('.fylke_click').click(function () {
$(this).parent().nextUntil('.fylke').slideToggle(0);
$('.sted').hide();
});
$('.kom_click').click(function () {
$(this).parent().nextUntil('.kommune').slideToggle(0);
});
See this simplified fiddle:
http://jsfiddle.net/T2Lwn/
So it's basically 3 levels and it is a lot of problems here.
One obvious one is when you are on the second level, which is called "kommune" and if you click on the last TR it removes the "fylke" underneath. As you can see if you click on "MIDTRE GAULDAL"
This is probably because I use .Parent() and I need some sort of if check if I am on the last row?
Is it also other problems with this code? Can I specify the click method class="fylke_click" and class="kom_click" on a more general level?
For example for all <tr class="fylke"> each TD class will have class="fylke_click" and same for kommunne?
If I understand your issue correctly this may help:
Demo Fiddle:
Since you said you're going to be dynamically creating this content, I would recommend delegating off of the main table instead of making a click handler for each row. Also, since all of the stuff you want to show / hide are siblings and not nested, things get a bit tricky. You'll need to be specific with your .nextUntil() by passing a filter, and I found a :not() on the filter was necessary.
Again, since these are all siblings, it's not as easy as hiding the children of the header row, so I set up an "open" class to check if the header was open or not, and hid / showed stuff depending on if it was already open.
JS:
$('.kommune').hide();
$('.sted').hide();
$('.table').on('click', 'tr', function(){
$this = $(this);
if( $this.hasClass('fylke') ){
if ( $this.hasClass('open') ) {
$this.toggleClass('open').nextUntil('.fylke', 'tr').hide();
}
else {
$this.toggleClass('open').nextUntil('.fylke', 'tr:not(.sted)').toggle();
}
}
else if ( $this.hasClass('kommune') ){
$this.nextUntil('.kommune', 'tr:not(.fylke)').toggle();
}
});
I have a table that automatically adds new rows, once u go to the last cell and tab over.
I click on one of the cells - I want to know the rowIndex of the clicked cell (row)
I havent been able to uniquely identify the cell using any attribute eg classname etc, ID is randomly generated. Name , TagName everything is generic - Same for all rows.
How do I get the rowIndex just using a cell's info
No jquery sols pls - not allowed in my framework
You can grab this info from the parent node tr as rowIndex:
td.parentNode.rowIndex
Here td is HTMLTableCellElement element.
td has a reference to its parent row element parentNode (tr), which in its own turn has a property rowIndex. Similarly td itself has a property cellIndex.
Demo: http://jsfiddle.net/prFSd/1/
dfsq provides a good answer, but it uses jquery which you said you could not use. You could put this in each rowonclick="myFunction(this)"then define the function
function myFunction(x)
{
alert("Row index is: " + x.rowIndex);
}
In your source code you can define tfoot before tbody but in the browser tfoot will still be displayed last:
<table>
<thead><tr><th>i get displayed first</th></tr></thead>
<tfoot><tr><td>i get displayed last</td></tr></tfoot>
<tbody><tr><td>i get displayed second</td></tr></tbody>
</table>
Now, I want to grab the tr elements of this table in their visual order, not the order they have in the html. So this of course does not do the trick:
var rows = $('table tr');
jQuery goes through the table and adds the tr elements in the order they appear in the source code.
I thought I could make separate blocks and concatenate them to get the right order:
var header = $('table>thead>tr');
var body = $('table>tbody>tr');
var footer = $('table>tfoot>tr');
var rows = $().add(header).add(body).add(footer);
Strangely enough the order is still the same as if I did $('table tr')! How can this be?
I've also illustrated the problem in a jsFiddle: http://jsfiddle.net/nerdess/sKewX/2/
If you want to have the elements in the exact order you want, you need to build the result manually. I've modified your code in the fiddle: http://jsfiddle.net/lechlukasz/sKewX/3/
var header = $('table>thead>tr');
var body = $('table>tbody>tr');
var footer = $('table>tfoot>tr');
var apppend = function(arr, items) {
for (var i=0;i<items.lenght;i++)
arr.push(items[i])
}
var rows = []
append(rows, header)
append(rows, body)
append(rows, footer)
console.log(rows);
Element selectors look at the DOM, so they will only return the elements in the order they appear in the DOM.
If you want them in the VISUAL order you'll have to determine the positioning of each item yourself.
See: Determining an element's absolute on-document position
From documentation for add() method:
Do not assume that this method appends the elements to the existing
collection in the order they are passed to the .add() method. When all
elements are members of the same document, the resulting collection
from .add() will be sorted in document order; that is, in order of
each element's appearance in the document. If the collection consists
of elements from different documents or ones not in any document, the
sort order is undefined. To create a jQuery object with elements in a
well-defined order, use the $(array_of_DOM_elements) signature.
So yes, it will appear the same as $('table tr');
Because $('table tr') will only look for code (it has nothing to do with the console).
Now because you add the body to var rows before you add the footer, it is logical that the display will be different from the code.
It's the same as publishing a book and then telling the readers to read page 3 before page 2:
Now the readers ('the console') know the correct order, but the book still retains a wrong order of page numbers.
So to make life easy: try to keep code and display as parallel as possible. Hence try to keep the same order in both to avoid unnecessary complexity.
Here's an example using the insertion sort algorithm (http://en.wikipedia.org/wiki/Insertion_sort). By design, add() collects the elements in the DOM order.
The idea is to sort the elements based on how they'd be seen visually (using their offset).
JsFiddle: http://jsfiddle.net/Pv4tj/
I have dynamically created HTML table clicking on its TH will reload the table according to sorted column.
What i want is to apply a class to the TH clicked.
Since the table is reloaded i first put the clicked column name in a Global variable and then when the table get reloaded i want to apply a CSS class.
The requirement is i want to search the THs in a TR by text (without iterating all elements) and then apply a class.
Any help is appreciated
Thanks
EDIT:
We cannot use :contains becuase two column names can contains similar text header
jQuery's filter function allows you to specify a function to be used as the filter.
$("th").filter(function() {
return $(this).text() == "foo";
}).addClass("newClass");
To apply a class to the th when clicked:
$(function () {
$('th').on('click', function () {
$(this).addClass('myClickedClass');
});
});
If you want to apply the class based on the match of a string, use this:
$(function () {
$("th:contains('" + myStringValue + "')").addClass('myClickedClass');
});