jQuery select multiple table columns by index - javascript

I've seen certain questions knocking around which are similar, but not exactly the same and I'm stumped with this one.
What I'm trying to do is create a widget that takes a table, then goes through the table's td elements and sets a cursor:pointer (for now) to them, but only the ones that I allow.
This is how my code looks:
selectableGrid: function (options) {
var indexes = options.columns // this is [1,2];
return this.each(function () {
// Make the td's in the grid selectable
$(this).find("tbody td").attr("style", "cursor:pointer");
});
}
The end result I'm wanting to achieve?
<tbody>
<td>hello</td> // index 0
<td style="cursor:pointer">hello</td> //index 1
<td style="cursor:pointer">hello</td> // index 2
</tbody>
Bear in mind that I could be sending through 1,3 in my array list of columns, so lt and gt don't work for my scenario (as far as I've tried anyway).
EDIT:
In order to achieve this I went with the following code:
$(this).find("tr").each(function () {
$(this).find("td").each(function (i, el) {
if (indexes.indexOf(i) > -1) {
$(this).css("cursor", "pointer");
};
});
});
For some reason "tbody td" wouldn't work for a singular loop as it only referenced the first iteration of the tag.
Thank you once again Stack Overflow.

Loop through the td elements, and check that their index with respect to their siblings is an index contained in the options.columns array.
selectableGrid: function (options) {
var indexes = options.columns // this is [1,2];
return this.each(function () {
$(this).find("tbody td").each(function(){
var columnIndex = $(this).index();
if($.inArray(columnIndex, options.columns) != -1){
$(this).css("cursor", "pointer");
}
});
});
}

.each takes an index parameter you can reference in your code.....:
var indexes = options.columns;
this.find("tbody td").each(function(i, el) {
if ($.inArray(i,indexes)>-1) { // good idea, ggreiner
$(this).css("cursor","pointer");
};
});

loop through your indexes and use the http://api.jquery.com/eq/ to find the particular td.

Related

jQuery value returned from text() causes unrecognised expression error when adding to array

I have the following code:
$(document).ready(function () {
debugger;
// Empty aarray to store list of headings
var tableHeadings = [];
// For each heading present add it to the array (ordered)
$('#AdvancedTable thead > tr > th').each(function () {
//console.log($(this).text());
$(tableHeadings).add($(this).text());
});
// For each row in the table, add the heading text to the start of each cell
$('#AdvancedTable tbody > tr > td').each(function (index) {
$(this).prepend('<span class="visible-xs">' + tableHeadings[index] + '</span>');
})
});
However, one of my table headings I am storing values from contains the text "Length (L1)". I get the following error in my console:
Uncaught Error: Syntax error, recognised expression: Length (L1)
I understand the basics that this is caused by there being issues with text passing something with brackets in it, but would like to know the details of why this happens and a hint as to how I can solve this/best practices to avoid an error like this.
Use map instead of each.
// Empty aarray to store list of headings
var tableHeadings = $('#AdvancedTable thead > tr > th').map(function () {
return this.innerHTML;
}).get();
You are creating an empty array, iterating over elements, and adding them to an array. This is essentially reinventing the wheel for what map already does.
tableHeadings is a simple array, so you can use push function to add value:
$(document).ready(function () {
let tableHeadings = [];
$('#AdvancedTable thead > tr > th').each( (index, item) => {
tableHeadings.push($(item).text())
});
$('#AdvancedTable tbody > tr > td').each( (index, item) => {
$(item).prepend('<span class="visible-xs">' + tableHeadings[index] + '</span>');
})
});
$(tableHeadings).add($(this).text());
need to be
tableHeadings.push($(this).text())
Not sure why you're using JQuery to add an item to a list; perhaps try:
tableHeadings.push($(this).text());
instead of the original line:
$(tableHeadings).add($(this).text());

Delete rows from table recursively using JQ

I want to write a recursive function that will delete rows from my table.
I have the number of rows to keep and after that number i want to remove all rows.
for example:
I have the number 5 so the first 5 rows need to stay and the rest need to go. (using the row id)
code:
<table id="table">
<tr id="tr1"/>
<tr id="tr2"/>
<tr id="tr3"/>
<tr id="tr4"/>
<tr id="tr5"/>
<tr id="tr6"/>
<tr id="tr7"/>
<tr id="tr8"/>
</table>
I dont know how much rows i will have, thats why i think i need a recursive solution.
You can use several different jQuery filter approaches:
var numRows=5;
$('#table tr').slice(numRows).remove();
OR
$('#table tr:gt(' + (numRows-1) + ')').remove();
DEMO
References:
slice() docs
:gt() selector docs
You can use this
$(document).ready(function(){
var deleteAfter = 5
$.each($("#table tr"),function(key,value){
//do your conditional here
if(key > deleteAfter-1){
value.remove();
}
});
alert("now the table row is "+$("#table tr").length);
});
This is working jsfiddle
I'm sorry if u want to using id as the input please use this instead
$(document).ready(function () {
//define the id first
var deleteAfter = $("#tr5");
var elementNo;
$.each($("#table tr"), function (key, value) {
if (this.id == deleteAfter.attr("id")){
elementNo = key;
}
});
$.each($("#table tr"), function (key, value) {
//do your conditional here
if (key > elementNo) {
value.remove();
}
});
alert("now the table row is " + $("#table tr").length);
});
And i updated the jsfiddle
you can use :gt() selector, it selects all the elements greater than index and then you can remove it.
$(document).ready(function () {
var index = 4; // set index 4, so want to remove 5 elements( 0 to 4)
$('#table tr:gt('+index+')').remove();
});

How to give a unique id for each cell when adding custom columns?

I wrote following code to add a custom column to my table. but i want to add a unique id to each cell in those columns. the format should be a(column no)(cell no>)
ex :- for the column no 4 :- a41, a42, a43, ........
So please can anyone tell me how to do that. Thank You!
$(document).ready(function ()
{
var myform = $('#myform'),
iter = 4;
$('#btnAddCol').click(function () {
myform.find('tr').each(function(){
var trow = $(this);
var colName = $("#txtText").val();
if (colName!="")
{
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td>'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
}
});
iter += 1;
});
});
You seem to have code that's modifying the contents of the table (adding cells), which argues fairly strongly against adding an id to every cell, or at least one based on its row/column position, as you have to change them when you add cells to the table.
But if you really want to do that, after your modifications, run a nested loop and assign the ids using the indexes passed into each, overwriting any previous id they may have had:
myform.find("tr").each(function(row) {
$(this).find("td").each(function(col) {
this.id = "a" + row + col;
});
});
(Note that this assumes no nested tables.)
try this
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'">'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'"><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
you just have to define and iterate the column_no and cell_no variable
When all other cells are numbered consistently (for example using a data-attribute with value rXcX), you could use something like:
function addColumn(){
$('table tr').each(
function(i, row) {
var nwcell = $('<td>'), previdx;
$(row).append(nwcell);
previdx = nwcell.prev('td').attr('data-cellindex');
nwcell.attr('data-cellindex',
previdx.substr(0,previdx.indexOf('c')+1)
+ (+previdx.substr(-previdx.indexOf('c'))+1));
});
}
Worked out in this jsFiddle

How to iterate over htmlCollection

I'm having some difficulty with this. In Backbone, I have a function like this:
functionOne: function(){
$('#myTExtbox-' + budgetLine.attr('id')).on('change keyup paste', function(){
that.mySecondFunction(this);
});
}
In this case, the this is a textbox, which is in a table, inside a div. Then:
mySecondFunction: function(tb){
var tbody = tb.parentElement.parentElement.parentElement.parentElement.parentElement;
//gets main parent, which is a tbody, inside a table, inside a div
}
I then want to iterate over tbody, to go through each row and find a textbox in a specific cell. The problem is that this code:
$.each(tbody, function(index, item){
cost = item;
var t= index;
});
Doesn't seem to allow me to get to any of the items. In this example, if I try to do something like:
item.getElementById('test');
I get an error:
TypeError: Object #<HTMLCollection> has no method 'getElementById'
Why can't I iterate over this object and access objects within?
Thanks
UPDATE
Here's a fiddle: http://jsfiddle.net/HX8RL/14/
Essentially, what should happen is this: When a text box changes, I want to iterate over all the rows in the tb's parent table and sum all the Tb values. Keeping in mind, all the tb's in the same cell position, as there could be other tb's in other places that I dont want to include.
There wont be any collection of TBody
try using children() instead
$.each(tbody.children('tr'), function(index, item){
cost = item;
var t= index;
});
Demo Fiddle
Iterate over all input elements directly to get values.
var tbody = tb.parentElement.parentElement.parentElement;
alert(tbody.id);
var input = $('#tbody').find('input');
alert(input);
console.log(input);
for (var i = 0; i < input.length; i++) {
alert(input[i].value);
alert(i);
}
See fiddle-http://jsfiddle.net/HX8RL/18/
I think there are a few things going wrong here. You know you can only have one ID per page? So you have to do document.getElementByid('test') instead.
Since you are also using jQuery you can use the find function, item.find('#test'). But I think this wouldn't solve you problem. Not sure what you want to achieve, maybe I can help you if you explain a bit more in detail what your problem is.
Also
tb.parentElement.parentElement.parentElement.parentElement.parentElement;
can be written as (in jQuery)
$(tb).parents('tbody');
I've setup a fiddle, maybe it can help you.
Code used in fiddle:
var myFuncs = (function() {
function funcA() {
$('input').on('keyup', function() {
funcB(this);
});
}
function funcB(myInput) {
var $table = $(myInput).parents('table');
$table.find('tr > td > input').each(function() {
var $input = $(this);
if($(myInput).attr('id') != $input.attr('id'))
$input.val("I'm called from another input");
});
}
return {
funcA : funcA
}
})();
myFuncs.funcA();

Identify, and compare, two rows in two different tables

Please see this jsfiddle.
My setup has the following two tables: simTable = datatable-simf-sim and resTable = datatable-simf-res.
I am trying to add a row into resTable everytime the user selects (clicks) on a row in simTable, this works great. However when the user deselects the row, it should be removed from simTable.
resTable = $('#datatable-simf-res').dataTable({});
simTable = $('#datatable-simf-sim').dataTable({});
$('#datatable-simf-sim tr').click(function () {
if ($(this).hasClass('row_selected')) {
$(this).removeClass('row_selected');
var uniqueid = $(this).closest('tr').children('td:eq(0)').text();
$('#datatable-simf-res tr td').each(function () {
if ($(this).text() === uniqueid) {
var rowindex = $(this).closest('tr').index();
resTable.fnDeleteRow(rowindex);
}
});
} else {
$(this).addClass('row_selected');
var rows = [];
$(this).closest('tr').find("td").each(function (cell, v) {
rows.push($(this).text());
});
resTable.fnAddData(rows);
}
resTable.fnDraw();
});
When you play with the jsfiddle (just click a bunch of times on the rows) you will see that it will leave rows untouched, or removes the wrong rows. I am assuming is has to do with the way I identify a row in resTable, as this was the biggest bottleneck for me.
So how do I succesfully identify, and compare, two rows in two different tables?
Thank you very much.
Although the fiddle seems fine to me, a cleaner way to remove the row would be:
// iterate over rows, not all cells
$('#datatable-simf-res tr')
.filter(function () {
// check if the first column contains the unique ID
return $(this).find('td:first').text() === uniqueid
})
.each(function () {
// 'this' is the current DOM element, inside .each()
resTable.fnDeleteRow(this)
});
(The DataTables API says that fnDeleteRow accepts either an index or a <tr> element.)

Categories

Resources