I have multiple tables being generated, and I am calculating a total of the column for each table.
The following works perfectly for the first table, but if I remove the ":first" then it gives me the sum of all tables, which I dont want.
var total = 0;
jQuery('table.views-table:first td.views-field-qty').each(function()
{
var price = parseInt(jQuery(this).text());
if (!isNaN(price))
{
total += price;
}
});
jQuery('table.views-table:first').after('<p> Total Tickets Sold: <strong>' + total + '</strong></p>');
How do I do the above for each table, with a summary under every table, when all classes and td classes are the same. Its no good numbering the table classes, as there could be any amount.
Wrap your table in a .each loop
jQuery('table.views-table').each(function(i,el){
var table = jQuery(el);
var total = 0;
table.find('td.views-field-qty').each(function()
{
var price = parseInt(jQuery(this).text());
if (!isNaN(price))
{
total += price;
}
});
table.after('<p> Total Tickets Sold: <strong>' + total + '</strong></p>');
});
You need to amend your logic so that you call each() on the table and then again on each td within that table. Try this:
jQuery(function($) {
$('table.views-table').each(function() {
var $table = $(this), total = 0;
$table.find('td.views-field-qty').each(function() {
total += parseInt(jQuery(this).text(), 10) || 0;
});
$table.after('<p> Total Tickets Sold: <strong>' + total + '</strong></p>');
});
});
Note that you can negate the need for the if statement by using the || operator as a shortcut to providing a default value for the variable.
Related
JS:
function add(){
while(i < $('.tabledata').length){
var current_val = $('.tabledata').eq(i).text();
arr.push(current_val);
$('.tabledata').eq(i).text() = "<img src='/flags/'" + (flagsarr[current_val].toLowerCase() + '.png') + ' width="20px" style="margin-bottom: 2px;"><b>' + current_val + '</b>';
i++;
}
}
$(document).ready(function(){ add(); });
current_val is a Country. flagsarr[curren_val] is the country code: eg ES (Spain).
in this case, i want to add 'es.png' before the text 'Spain' in the table.
I tried using text() but I realised it was a function.
Please note: there are around 200 rows in the table, each with 5 pieces of data (so 5 columns), the first being the Country. Each of the first column items share the class 'tabledata'.
How can I fix this?
You can use each to iterate over tabledata and html() instead of text() to get its content:
function add() {
var $tableData = $('.tableData');
$.each($tableData, function(index, value){
var current_val = $(value).html();
arr.push(current_val);
$(value).html("<img src='/flags/'" + flagsarr[current_val].toLowerCase() + ".png'" + ' width="20px" style="margin-bottom: 2px;"><b>' + current_val + '</b>');
});
}
$(document).ready(function(){ add(); });
For eg.
col1 col2 col3 col4 col5 col6
1 pass NA Pass NA NA
2 pass NA pass NA pass
3 fail NA pass NA NA
Then hide col3 and col5. Resulting table is below:
col1 col2 col4
1 pass Pass
2 pass pass
3 fail pass
col3 and col5 is hidden now.
Note : I am populating all rows through ajax. For each rows ajax is triggered.
Here is my existing code:
function hideOneValueColumns(table_id, ignore_row_class, ignore_column_class) {
var row_count = $('#' + table_id + ' tr:not(.' + ignore_row_class + ')').length;
if (row_count > 2) {
//first go through the column headers
$('#' + table_id + ' th').each(function (i) {
//only process the column if it isn't one of the column we should ignore
if (!$(this).hasClass(ignore_column_class)) {
//get all cells of the columns (in order to show or hide them)
var all_cells = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')');
//get the cells we'll use to decide whether we want to filter the column or not
var filtered_cells = $(this).parents('table').find('tr:not(.' + ignore_row_class + ') td:nth-child(' + (i + 1) + ')');
//array containing the list of different values in a column
var values = new Array();
//gather the different cell values
filtered_cells.each(function () {
var value = this.innerHTML;
// gather all cells which has values NA
if (values == 'NA') {
values.push(value);
}
});
//hide if less than 2 different values and show if at least 2 different values
if (values.length == $('#' + table_id + ' tr').length) {
$(this).hide();
all_cells.hide();
} else {
$(this).show();
all_cells.show();
}
}
});
} else {
$('#' + table_id + ' th').show();
$('#' + table_id + ' tr td').show();
}
}
// call the method
// spcl is table id
hideOneValueColumns('spcl', 'filters', 'no-hide');
You need to loop over each table row and, for each column, work out if the cell contains 'NA'. If it does not, then leave the entire column alone.
In this code snippet I get the number of columns from the first row (assuming them to be row headers). Then, for each number of columns, for each row, get that column. The default functionality I have done here is to hide the column. If any of the cells in the column does not contain NA, then show the column.
"use strict";
function hideOneValueColumns(table_id) {
var columnCount = jQuery('#'+table_id+' tr:first-of-type th').length + 1;
for(var i = 1; i < columnCount; i++) {
var func = 'hide';
jQuery('tr:not(:first-of-type)').each(function(){
var $td = jQuery(this).find('td:nth-child('+i+')');
if($td.text() != 'NA') {
func = 'show';
}
});
jQuery('tr td:nth-child('+i+'), tr th:nth-child('+i+')')[func]();
}
}
hideOneValueColumns('some_id');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="some_id">
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
<th>col4</th>
<th>col5</th>
<th>col6</th>
</tr>
<tr><td>1</td><td>pass</td><td>NA</td><td>Pass</td><td>NA</td><td>NA</td></tr>
<tr><td>2</td><td>pass</td><td>NA</td><td>pass</td><td>NA</td><td>Pass</td></tr>
<tr><td>3</td><td>fail</td><td>NA</td><td>pass</td><td>NA</td><td>NA</td></tr>
</table>
I'm trying to create a table on the fly... it almost works but I have an issue with the number of cell it adds.
My table has 8 columns (monday to Friday plus a total column at the end).
Here is the fiddle for it: http://jsfiddle.net/kaf9qmh0/
As you can see, on row 1, it adds the 8 columns 3 times, then on row 2 it adds the columns twice and only on the last row does it only add 8 columns.
I suspect it is because Im using .append to add the rows as follows (line 105 in the fiddle) but my Javascript being very limited, Im not entirely sure how to make it stop add the columns to row 1 and 2.
$("#timesheetTable > tbody").append('<tr id="' + sourceTableRowID + '" data-tt-id="' + sourceTableRowID + '" class="timesheetRow row' + rowIndex2 + '"></tr>');
How can I make it to only add the cells (td) to the next row when it loops through rowIndex2 and increments it?
Can somebody point me in the right direction please?
You had a loop within a loop - which was causing the additional cells. Here's an updated fiddle; and here's an extract of the modified code:
function createSampleRows() {
var sourceTable = document.getElementById('activityTable');
var sourceTableRows = sourceTable.rows.length;
var targetTable = document.getElementById('timesheetTable');
var rowindex;
var targetTableColCount;
for (var rowIndex = 0; rowIndex < targetTable.rows.length; rowIndex++) {
if (rowIndex == 1) {
targetTableColCount = targetTable.rows.item(rowIndex).cells.length;
continue; //do not execute further code for header row.
}
}
for (rowIndex = 0; rowIndex < (parseInt(sourceTableRows)-2); rowIndex++) {
var sourceTableRowID = document.getElementsByClassName('activityTaskRow')[rowIndex].id;
$("#timesheetTable > tbody").append('<tr id="' + sourceTableRowID + '" data-tt-id="' + sourceTableRowID + '" class="timesheetRow row' + rowIndex + '"></tr>');
};
// This loop was nested within the above loop
for (x = 0; x < targetTableColCount; x++) {
$("#timesheetTable > tbody > tr").append('<td id="' + x + '" style="width: 60px;height: 34px;" class=""></td>');
};
};
Basically, I want the user the just change the 'height' variable to how ever many rows he wants, and then store the words which each td in the row should contain, and the code should then generate the table.
My html is just this:
<table id="newTable">
</table>
This is my Javascript:
<script type="text/javascript">
var height = 2; // user in this case would want 3 rows (height + 1)
var rowNumber = 0;
var height0 = ['HeadingOne', 'HeadingTwo']; // the words in each td in the first row
var height1 = ['firstTd of row', 'secondTd of row']; // the words in each td in the second row
var height2 = ['firstTd of other row', 'secondTd of other row']; // the words in each td in the third row
$(document).ready( function() {
createTr();
});
function createTr () {
for (var h=0; h<height + 1; h++) { // loop through 3 times, in this case (which h<3)
var theTr = "<tr id='rowNumber" + rowNumber + "'>"; // <tr id='rowNumber0'>
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
for (var i=0; i<window['height' + rowNumber].length; i++) {
if (i == window['height' + rowNumber].length-1) { // if i==2, then that means it is the last td in the tr, so have a </tr> at the end of it
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td></tr>";
$('#rowNumber' + rowNumber).append(theTr); // append to the end of the Tr
} else {
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td>";
$('#rowNumber' + rowNumber).append(theTr);
}
}
rowNumber += 1;
}
}
</script>
I did 'alert(theTr);' and 'alert(theTd);' and they looked correct. How come this code doesn't generate any table?
You should change the line
$('#rowNumber' + rowNumber).append(theTr);
into
$('#rowNumber' + rowNumber).append(theTd);
You are adding the Tr-Code again in the inner loop, but you actually wanted to add the Td-Code.
All that window["height"+rowNumber] stuff is a poor way to do it. Use an array, and pass it as a parameter to the function so you don't use global variables. And use jQuery DOM creation functions instead of appending strings.
<script type="text/javascript">
var heights = [['HeadingOne', 'HeadingTwo'], // the words in each td in the first row
['firstTd of row', 'secondTd of row'], // the words in each td in the second row
['firstTd of other row', 'secondTd of other row'] // the words in each td in the third row
];
$(document).ready( function() {
createTr(heights);
});
function createTr (heights) {
for (var h=0; h<heights.length; h++) { // loop through 3 times, in this case (which h<3)
var theTr = $("<tr>", { id: "rowNumber" + h});
for (var i=0; i<heights[h].length; i++) {
theTr.append($("<td>", { "class": "row"+h + " column"+i,
text: heights[h][i]
}));
}
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
}
}
</script>
JSFIDDLE
I have a table with 2 rows, the first has an input for quantity and the following has to output that same value. Since I'm using jQuery this is my code:
var i, quant;
for (i = 0; i < $(".qnt").length; i++){
$(".qnt:eq(" + i + ")").keyup(function(){
quant = $(this).val();
console.log($(this));
console.log(i);
console.log($(".cst:eq(" + i + ")"));
$(".cst:eq(" + i + ")").text(quant);
});
}
And the sample for the rows is :
<tr>
<td><input class="qnt"/></td><td class="cst"></td>
</tr>
The jsfiddle is : http://jsfiddle.net/qrhJ4/
Question : why is the .cst selector not working and how do I make it work?
You are over-complicating things, try something like:
$('.qnt').keyup(function() {
$(this).parent().next('.cst').text(this.value);
});
http://jsfiddle.net/aasqW/