defer events when table is being populated - javascript

I'm creating a simple dropdown plugin where the values of the dropdown were in tabular manner.
what I want is to halt the event while my table is being loaded.
here's my code.
//appendTableForThePanel
$('#appendHere').append('<table class="table table-hover table-condensed"></table>');
$('#appendHere').find('table').append('<thead></thead>');
$('#appendHere').find('table').append('<tbody></tbody>');
$('#appendHere').find('table').find('thead').append('<tr></tr>');
for(appendCountHeader = 0; appendCountHeader < tableHeader.length; appendCountHeader++ ){
$('#appendHere').find('table').find('thead').find('tr').append('<th>'+tableHeader[appendCountHeader]+'</th>');
}
//count tbody tbody_tr
var tbody_tr = tbody.length / tableHeader.length;
//count how many column / row
var tbody_td = tbody.length / tbody_tr;
//append tbody tr tdcontent
for(var i = 0; i < tbody.length; i += tbody_td) {
$newRow = $("<tr>");
for(var j = 0; j < tbody_td; j++) {
$newRow.append(
$("<td>").html(tbody[i + j])
);
}
$("#appendHere").find('table').find('tbody').append($newRow);
}
$('body').on('click', '#appendHere table tbody tr', function() {
// alert($(this).find('td:nth-child(1)').html() + ' : ' + $(this).find('td:nth-child(2)').html());
$($element.selector).val($(this).find('td:nth-child(2)').html());
$('#appendHere').hide();
});
// **I want to deferred below functions when the table is appending**
$($element.selector).blur(function(){
setTimeout(function(){
$('#appendHere').hide();
}, 200);
});
$($element.selector).on('click', function(){
$('#appendHere').show();
});
$($element.selector).keyup(function(){
});
I know it is possible but I can't grasp the idea of deferring a function.
thanks in advance.

Related

How to get th when child td is clicked?

I trying to get the <th> content of the clicked <td> item.
here is the fiddle: http://jsfiddle.net/zrccq447/
the thing is, the <th> can have colspan 2 or 3, this is the point where I am stuck. this is my code
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var x = $('#headerx9 th:nth-child(' + (clicked_pos) + ')').text();
var xy = td.text();
alert(x);
});
i want x to be the <th> of clicked td. the problem is now that if you click on some td that shares the th with other tds, i am getting the wrong th.
appreciate any help
I've updated your JsFiddle with the answer found here: Finding a colSpan Header for one of the cells or td's is Spans
JsFiddle: http://jsfiddle.net/zrccq447/4/
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var x = $('#headerx9 th:nth-child(' + thLocator[clicked_pos] + ')').text();
var xy = td.text();
alert(x);
});
var thLocator = [], colCount = 1;
$('#table9').find('tr:first th').each(function () {
for (var i = 0; i < this.colSpan; i++) {
thLocator.push(colCount);
}
colCount++;
});
Following on from my comment you need to sum up the colspans (or default 1) for each TH until you get enough to match the column you desire:
http://jsfiddle.net/TrueBlueAussie/zrccq447/5/
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var cols = 0;
var $table = td.closest('table');
var $ths = $table.find('tr th');
for (var i = 1; i < $ths.length; i++) {
var $th = $ths.eq(i);
cols += ~~$th.attr('colspan') || 1;
if (cols >= clicked_pos) {
var x = $th.text();
alert(x);
break;
}
}
});
I tried to keep it generic, so it finds the appropriate table and headers on the fly.
One approach is to get store a reference to each TH, in order, in an array and call the text from the array based on the location of the td.
var thholder = $('table th'),
th = [];
for(var i = 0; i < thholder.length; i++) {
var thi = $(thholder[i]);
for(var j = 0; j < (thi.attr('colspan') || 1); j++) {
th.push(thi);
}
}
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
alert(th[clicked_pos].text());
});
http://jsfiddle.net/zrccq447/3/
This code is not optimised, but shows the approach:
Loop through all the TH in the table.
If the TH does not have the attribute 'colspan', then set the attribute to a value of 1.
Create a loop for each value of colspan and save a reference to the current TH in the array.
When you click on a TD, get it's clicked position and retrieve the text of the TH at that position in the array and alert it :)

Mobile Tables - Jquery, so close, stuck on the last part

I'm trying to make a script to make my applications tables more mobile friendly.
The tables are all very similar, but very in number of row and columns, since they will be dynamically created, I'll have little control over this, so i've come up with the script below, it almost works but one function is not be passed on to each table, it stops after the first.
I suggest looking at the js fiddle: http://jsfiddle.net/e4vC3/1/
Here is the piece of the script that is not working correctly:
// Create content for new headers in mobile table by copying from original table
var HeaderArray = [];
$("table thead tr th").each(function(){
var innerArray = [];
$(this).each(function () {
innerArray.push($(this).text());
});
HeaderArray.push(innerArray); // Put content for new headers in array
});
$("table.mobile_table tbody tr").each(function(index, elem){ // Place content of array where array position and row index are the same
$(this).find("td").first().text(HeaderArray[index]);
});
Again, if you check the fiddle, you will see that the first arry stops copying objects after the first table, i cant get it to run all the way thought.
If anyone could help me with them, i would really, realy appreciate it..... http://jsfiddle.net/e4vC3/1/
The problem is that there are multiple data rows while only 1 header row. So, you will have to use mod operator like this(index has been replaced with index % TableSize):
$("table.mobile_table tbody tr").each(function(index, elem){ // Place content of array where array position and row index are the same
$(this).find("td").first().text(HeaderArray[index % TableSize]);
});
Updated your code # http://jsfiddle.net/souviiik/e4vC3/4/, see if this is helpful. For the first mobile_table I was not able to put the TH values, I hope you can modify my code :)
var TableSize = $("#ContactsPhoneTable .tableHedaer").size(); // Get # of columns
var i = 1;
var TableRowCount = $(".no_edit").size(); // Get # of body rows
$(".tableHedaer").each(function () {
$(this).attr("id", i++); // Give headers incrementing ID
});
for (var CreateTables = 1; CreateTables < TableRowCount; CreateTables++) { // Create new table class="mobile_table" for each row
$("table").after("<table class='mobile_table'></table>");
}
for(var i = 0 ; i < TableSize ; i++)
{
var tableRow = $("<tr/>").appendTo(".mobile_table");
for(var j = 0 ; j < TableRowCount ; j++)
{
var cellValue = $("#ContactsPhoneTable").find("tr").eq(i).find("td").eq(j).text();
$("<td/>", {
text: cellValue
}).appendTo(tableRow);
}
}
Updated code is at http://jsfiddle.net/souviiik/b6QZT/2/, see if this is acceptable. The code is as below.
var columnCount = $("table thead tr th").not("table.mobile_table thead tr th").size(); // Get # of columns
var rowCount = $("table tbody tr").size(); // Get # of body rows
for (var CreateTables = 0; CreateTables < rowCount; CreateTables++) { // Create new table class="mobile_table" for each row
$("<table/>", {
"class": "mobile_table"
}).appendTo(".newTableContainer");
}
var tableHedaers = [];
for(var th = 0 ; th < columnCount ; th++)
{
tableHedaers.push($(".sortable th").eq(th).text());
}
$(".mobile_table").each(function(idx){
var thisTable = $(this);
for(var i = 0 ; i < columnCount ; i++)
{
var thisTableRow = $("<tr/>").appendTo(thisTable);
for(var j = 0 ; j < 2 ; j++)
{
if(j == 0)
{
$("<td/>", {
"text": tableHedaers[i],
"style": "font-weight: 700"
}).appendTo(thisTableRow);
}
else
{
var cellValue = $("#ContactsPhoneTable").find("tr").eq(idx+1).find("td").eq(i).text();
$("<td/>", {
"text": cellValue
}).appendTo(thisTableRow);
}
}
}
});

Separate rows and columns while creating 2d dynamic table

I can't separate row and column td's as I create a 2d table with jquery..
How do I create 10 rows 10 columns 2d table:
what I have done so far:
$(document).ready(function () {
for (var i = 1; i <= 10; i++) {
$('.box').append('<td/>' + '</p>');
for (var j = 1; j <= 10; j++); {
$('.box').append('<td/>');
}
}
});
http://jsfiddle.net/VS37n/
thnx in advance!
You want a table that has 10 columns and 10 rows.
var rows = 10;
var cols = 10;
In an HTML table structure, rows come first in the hierarchy, so, create those first:
$(document).ready(function() {
var rows = 10;
var cols = 10;
var box = $('.box');
for (var r = 0; r < rows; r++) {
var tr = $('<tr>');
//Here we will append the columns to the row before appending it to the box.
box.append(tr);
}
});
The above code only makes 10 rows for us. Now we need to add 10 columns to each row:
$(document).ready(function() {
var rows = 10;
var cols = 10;
var box = $('.box');
for (var r = 0; r < rows; r++) {
var tr = $('<tr>');
for (var c = 0; c < cols; c++) {
tr.append($('<td><p></p></td>')); //Create the table cell, with a p element as in your example, and append it to the row.
}
box.append(tr);
}
});
See this FIDDLE
UPDATE
I just noticed that the jQuery selector from your post selects the <div> element with class .box. You want to add these rows and columns, however, to a <table> element, which doesn't exist. I'd suggest you add a <table> element into your HTML, or, add it with Javascript before adding the rows.
If you can add a <table> element inside of your .box div, then you would just change the following line:
var box = $('.box');
to:
var box = $('.box table:first');
If you can't change the HTML for some reason, then you can dynamically create the table before the rows and columns:
var box = $('<table>').appendTo('.box');
Is this what you're trying to do?
$(document).ready(function () {
var tdHtml = "":
var trHtml = "";
var tableHtml = "";
for(var i=1;i<=10;i++)
{
tdHtml += "<td></td>";
}
for(var j=1;j<=10;j++);
{
trHtml += ("<tr>" + tdHtml + "</tr>");
}
tableHtml = ("<table>" + trHtml + "</table>");
$('.box').innerHtml(tableHtml);
});
You had a ; after your for loop :
for (var j = 1; j <= 10; j++); {
$('.box').append('<td/>');
}
Furthermore, you are not adding <tr> elements.
See the updated fiddle

Combine HTML Table Rows with Javascript

Is there an easy way to combine rows in an HTML table where the first column is the same? I basically have a table set up like:
<table>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
</table>
and I want it to generate:
<table>
<tr><td>test</td><td>37035</td><td>37035</td><tr>
<tr><td>test2</td><td>24690</td><td>24690</td><tr>
</table>
using jQuery:
var map = {};
$('table tr').each(function(){
var $tr = $(this),
cells = $tr.find('td'),
mapTxt = cells.eq(0).text();
if(!map[mapTxt]){
map[mapTxt] = cells;
} else {
for(var i=1, l=cells.length; i<l; i++){
var cell = map[mapTxt].eq(i);
cell.text(parseInt(cell.text()) + parseInt(cells[i].text()));
}
$tr.remove();
}
});
this is a "dumb" script -- no error handling for cases like different number of cells, fields being non-numeric, etc. Add those if necessary.
Also, depending on how it's generated, it's better to do this server-side.
Here's a plain JavaScript version.
window.onload = function() {
var table = document.getElementById('mytable');
var tr = table.getElementsByTagName('tr');
var combined = Array();
for (i = 0; i < tr.length; i++) {
var td = tr[i].getElementsByTagName('td');
var key = td[0].innerText;
if (!combined[key]) {//if not initialised
combined[key] = Array();
for (j = 0; j < td.length - 1; j++) combined[key][j] = 0;
}
for (j = 0; j < td.length - 1; j++)
combined[key][j] += parseInt(td[j + 1].innerText);
}
while (table.hasChildNodes()) table.removeChild(table.lastChild);
var tbody = document.createElement('tbody');//needed for IE
table.appendChild(tbody);
for (var i in combined) {
tr = document.createElement('tr');
tbody.appendChild(tr);
td = document.createElement('td');
td.innerText = i;
tr.appendChild(td);
for (j = 0; j < combined[i].length; j++) {
td = document.createElement('td');
td.innerText = combined[i][j];
tr.appendChild(td);
}
}
}
This will work on tables with any number of rows and any number of cells. I suppose you want to make the sum for every column, that's what this script does.
And as cwolves mentioned, it is more logical to do this serverside. Users that have JS disabled will see the not so clean uncombined table.

remove/hide table's empty column(s), including <th>

How can I hide the column with all empty cells including the title <th> in that column, while leaving the other columns and their titles as it is. Following jquery hides the entire <th>, which is not I want. Here is a sample, where I want to hide only the entire 'Column3' including <th>. Many thanks in advance.
$('table#mytable tr').each(function() {
if ($(this).children('td:empty').length === $(this).children('td').length) {
$(this).hide();
}
});
Took a while to piece together. Thanks to nxt for some of the code.
$('#mytable th').each(function(i) {
var remove = 0;
var tds = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')')
tds.each(function(j) { if (this.innerHTML == '') remove++; });
if (remove == ($('#mytable tr').length - 1)) {
$(this).hide();
tds.hide();
}
});
If you want to hide the column if all cells (ignoring the header) are empty, you could do something like:
$('#mytable tr th').each(function(i) {
//select all tds in this column
var tds = $(this).parents('table')
.find('tr td:nth-child(' + (i + 1) + ')');
//check if all the cells in this column are empty
if(tds.length == tds.filter(':empty').length) {
//hide header
$(this).hide();
//hide cells
tds.hide();
}
});
Sample: http://jsfiddle.net/DeQHs/
Sample 2 (adapted for jQuery > 1.7): http://jsfiddle.net/mkginfo/mhgtmc05/
None of the solutions here worked for me. This was what I used to hide empty columns with or without a text in the header:
$('table').each(function(a, tbl) {
var currentTableRows = $(tbl).find('tbody tr').length;
$(tbl).find('th').each(function(i) {
var remove = 0;
var currentTable = $(this).parents('table');
var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')');
tds.each(function(j) { if ($(this).text().trim() === '') remove++; });
if (remove == currentTableRows) {
$(this).hide();
tds.hide();
}
});
});
http://jsfiddle.net/nlovatt/JsLn8/
A multi-table example which avoids using the table id in the selectors
You need the next code:
HTML
<table id="mytable" border="1">
<thead>
<tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4</th></tr>
</thead>
<tbody>
<tr class="data"><td>1st</td><td>1.1</td><td></td><td>1</td></tr>
<tr class="data"><td>2nd</td><td>2.01</td><td></td><td>2</td></tr>
<tr class="data"><td>3rd</td><td>3.001</td><td></td><td>3</td></tr>
<tr class="data"><td>4th</td><td>4.01</td><td></td><td>4</td></tr>
</tbody>
</table>
JavaScript
var $table = $('#mytable');
var thead = $table[0].tHead, tbody = $table[0].tBodies[0];
var colsLen = tbody.rows[0].cells.length, rowsLen = tbody.rows.length;
var hideNode = function(node) { if (node) node.style.display = "none"; };
for (var j = 0; j < colsLen; ++j) {
var counter = 0;
for (var i = 0; i < rowsLen; ++i) {
if (tbody.rows[i].cells[j].childNodes.length == 0) ++counter;
}
if (counter == rowsLen) {
for (var i = 0; i < rowsLen; ++i) {
hideNode(tbody.rows[i].cells[j]);
}
hideNode(thead.rows[0].cells[j]);
}
}
If the table data are from a MySQL query it possible to verify if a column is empty by using count on the field (count = 0 means that there are no values).
It is quite fastidious when you have many fields, and the IF condition is needed for the corresponding header and footer cells too. But it works...
if ($sum_field>'0') echo "<th>field</th>";
if ($sum_field>'0') echo "<td>" . $row['field'] . "</td>";
#nmat solution works fine but doesn't handle footers.

Categories