I draw a table (through datatable) and I would need to retrieve some specific data depending on certain conditions.
here is the table:
tom
dsdsdsds
oo
60
jones
aa
oo
61
I need to parse each tr elements, and if the td input type checkbox contains the class selected, I need to retrieve the value of td with id="id" (of the same tr).
I tried to do the following:
var nbr_lignes = document.getElementById('datatable-table').rows.length;
var i = 0;
var j = 0;
while(i < nbr_lignes){
j=0;
console.log("ligne: "+i);
var nbr_colonnes = document.getElementById('datatable-table').getElementsByTagName('tr')[i].getElementsByTagName('td').length;
console.log("nb colonnes: "+nbr_colonnes);
while(j < nbr_colonnes){
console.log("contenu td: "+document.getElementById('datatable-table').getElementsByTagName('tr')[i].getElementsByTagName('td')[j].
innerHTML);
j++;
}
i++;
}
so I can parse each td of each tr but I don't know how to check if the current td contains the class selected and in that case retrieve the value of the td id="id"
I would appreciate if you can help me.
Here is a simple solution: you're making a counter and iteration through every line ( tr ), whenever you find input.selected inside it, you are asking for value of the div with id of a counter. The result is stored in found table.
https://jsfiddle.net/prowseed/80rmcjgu/19/
var idx = 1;
var found = [];
var trs = [].slice.call(document.querySelectorAll('table tr'));
trs.forEach(function(tr){
var isSelected = (tr.querySelector('input')).classList.contains('selected');
console.log(isSelected);
if(isSelected){
console.log(document.getElementById('id'+idx));
var value = (document.getElementById('id'+idx)).innerText;
found.push({id: idx, value: value});
}
idx++;
});
(document.getElementById('result')).innerHTML = found.reduce(function(p, c){ return p + ' \n ' + c.id + ':' + c.value }, '');
Related
Count duplicate value from table column using j query and show in new td as total duplicate value.
i try this code but not see actual results.
$(document).ready(function(){
var myarry =[];
var el = {};
$("tbody tr").each(function() {
var row = $(this).nextAll();
var first = row.find('td').eq(0).text();
var second =row.find('td').eq(1).text();
var third = row.find('td').eq(2).text();
if(el[first + second + third]) {
myarry.push(el);
}else {
var c = (parseInt(myarry.length) + parseInt(1));
console.log(c);
row.find('td').eq(3).attr("rowspan",2);
el[first + second + third] = 1;
myarry =[];
}
});
});
it should be dynamic .
I means to say table data will be change in future some time there are 3 duplicate and some time 5 or etc.
I have a script that creates a table with specifications given by the user.
The issue is that when the table is printed more than once, it prints below the other table. Turning a 10x10 table into a 10x20 table. (if that makes sense)
In previous assignments I used:
//Clean grid
while(grid.firstChild)
grid.removeChild(grid.firstChild);
to clear the grid, but this assignment is using jQuery and I am not sure how to do it. I've tried:
var divBlock = document.getElementById('my_table');
while (divBlock.firstChild) {
divBlock.removeChild(divBlock.firstChild);
and
$("#my_table").empty();
and
$("#my_table").remove();
and
$('#my_table').remove('table');
but neither seem to work, here is the full code:
// TODO: clear table
var $rows = $("#rows");
var $cols = $("#cols");
var $print_button = $("#print");
var $my_table = $("#my_table");
var $stats = $("#stats");
var arr = [];
var $table_obj = $('<table>'); //Create an element
var $row_obj;
var $col_obj;
var counter = 0;
$print_button.on('click', function() {print_pattern();});
function print_pattern()
{
// Clear table
// var divBlock = document.getElementById('my_table');
// while (divBlock.firstChild) {
// divBlock.removeChild(divBlock.firstChild);
// }
// $("#my_table").empty();
$('#my_table').remove('table');
// Get row and column values
var r = $rows.val(); //Get value of rows
element
var c = $cols.val(); //Get value of cols element
// Create 2-D Array
for (var i = 0; i < r; i++) {
arr[i] = [];
}
// Double for-loop to create table
for (var i = 0; i < r; i++) {
$row_obj = $('<tr>'); // Create row
for (var j = 0; j < c; j++) {
$col_obj = $('<td>'); // Create table cell
var n = Math.floor(Math.random()*10000)%100; //Math methods:
floor and random
$($col_obj).append(n); // Append random number to table cell
$($row_obj).append($col_obj); // Append column to row
$($table_obj).append($row_obj); // Append row to table object
// if random number > 90 -> make background color yellow
if (n > 90) {
$col_obj.css('background-color', 'yellow'); //Change css
counter++; // counter for stats
}
}
$($table_obj).append($row_obj); // Append row to table object
}
$($my_table).append($table_obj); // Append table to div container
// Stats calculation
$stats.html("<b>" + (counter/(r*c)*100).toFixed(2) + "%<b>");
//Change html content
counter = 0; // reset counter
// event function for removing a row when its clicked on
$('tr').on('click', function(){ $(this).fadeOut(500); });
}
So I've tried a number of things, I am not sure if I am just getting the syntax wrong or if I am using the wrong function to clear the div tag.
If anyone can point me in the right direction that would help a lot!
Thank you.
EDIT: I figured out the issue. My original while() block worked fine when I put all the variables inside the function.
First of all, you have to distinguish variables.
A. There is a variable that has to define 1 time, and any changes will
be stored on that.
B. And there is a variable that needs to be reset every function
called.
variable on condition b you need put inside your function so it won't keep last value and make it has double value (last value + new value)
in this case i could say this variable is on condition b:
$table_obj, $row_obj, $col_obj, arr, ...
I have made an array with objects that get there info from three different user variables, however on one of these there are many sub variables that i don't want it to repeat itself every time the user presses the select button(which updates the table) instead i want it to just add onto (or take away) from the sections that it already has in the table. thanks(if you need the variable code let me know) please help!! i really need a solution!!
//creating array
var gProducts = new Array();
var gTotalCost = 0;
// Adding Products to array gProducts
function addProduct
{
var product = new Object();
product.name = name;
product.cost = cost;
gProducts.push(product);
gTotalCost += parseInt(cost)
}
//Getting products from array, use of for in loop setting new table rows in blank var for each array item
function renderProducts()
{
var HTMLadd = ""
for (var i in gProducts)
{
if( gProducts[i].cost > 0){
HTMLadd = HTMLadd +
"<tr>"+
"<td class='tableSettings00' id=tableRow2 >" + gProducts[i].name +
"</td>"+
"<td class='tableSettings'>€<span id=tableRow2part2>" + gProducts[i].cost +
"</span></td>"+
"</tr>";
}
else
{
}
}
document.getElementById('tableRow').innerHTML = HTMLadd;
}
In the loop you always iterate through the whole gProducts, hence the values already placed to the table are doubled every time you execute the function.
This example uses some methods in HTMLTableElement to create new rows and cells. It also has a counter (index) holding the starting position of each iteration.
var index = 0; // Counter for holding the current position in gProducts
function renderProducts () {
var n, row, cell, span;
for (n = index; n < gProducts.length; n++) { // Start looping from the first new index in gProducts
if (gProducts[n].cost > 0) {
row = table.insertRow(-1); // Inserts a row to the end of table
cell = row.insertCell(-1); // Inserts a cell to the end of the newly-created row
cell.className = 'tableSettings00'; // Sets class for the cell
cell.id = 'tableRow' + index; // Sets an unique id for the cell
cell.innerHTML = gProducts[n].name; // Sets the content for the cell
cell = row.insertCell(-1); // Create another cell to row
cell.className = 'tableSettings';
cell.id = 'tableRowPart' + index;
cell.innerHTML = '€';
span = document.createElement('span'); // Creates an empty span element
span.id = 'tableRow2part' + index; // Sets an unique id for span
span.appendChild(document.createTextNode(gProducts[n].cost)); // Appends some text to the span
cell.appendChild(span); // Appends the span to the cell
}
}
index = n; // Sets counter equal to the length of gProducts
}
A live demo at jsFiddle.
As a sidenote, personally I prefer not to use ids for elements within a table. If ids are needed, you probably have constructed your table incorrectly, or the data is not suitable being shown in a table.
You can use indices and table.rows and rows.cells collections to find cells, and if some elements has to be searched for from a cell, use firstElementChild and nextElementSibling properties of a cell to find them.
I created a table in my HTML code. It has 9 columns and 13 rows. It gets filled up completely by a JavaScript loop that fills it with names of people from a few arrays. However, I want to add a validation step that makes sure that no two cells within a row hold the same value and that the value of a each cell does not repeat in the cell directly beneath it.
Since I am only able to access the values of the cells of the table as a NodeList, I decided to make it into an array to use the IndexOf property to search through the array:
var table1 = document.getElementsByTagName("td");
var table1Array = []; //number of "td" elements on page
for (i = 0; i < 117; i++) {
table1Array[i] = table1[i].innerHTML;
}
I don't know of a more elegant method (sort of a beginner here). So I set up some nested loops to compare each cell to each element in the row array I create (for all 13 rows):
function validateCells() {
for (i = 0; i < 117; i = i + 9) { //increment for going to next column (after 9 cells or elements in array)
for (j = 0; j < 8; j++) {
var curCell = table1Array[i];
var curRow = []; //I'm ignoring the first column which is "date", so it has 8 elements rather than 9
for (k = 0; k < 8; k++) {
curRow[k] = document.getElementById("row" + j).children[k].innerHTML;
}
if (curRow.indexOf(curCell) != -1) {
curCell = "CONFLICT"; //trying to change value in table. Doesn't work.
}
}
}
}
Unfortunately, this won't work. I don't even know if modifying the value of the curCell reference variable will actually change the value of the table1Array at that location, even less if it will change the data in the table.
Am I using the indexOf property correctly? Do I use the != comparison operator or !==? Does indexOf return the index as a Is there any other less complicated, more elegant to do this? I just started with jQuery, maybe it can help simplify the code and make it less error-prone.
Sorry for the all the questions, I'm really trying to understand how all of this works. Thanks!
You should get an array of rows, each row is an array of cells. That way the validation is much easier. I'm not sure about how you want to show the conflict. In this demo I've just highlight the duplicated cells (conflicted) in red (at least I like this kind of showing conflict rather than modifying the conflicted cells' text).
HTML:
<table>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>1</td><td>5</td><td>6</td></tr>
<tr><td>7</td><td>8</td><td>7</td></tr>
<tr><td>8</td><td>9</td><td>10</td></tr>
</table>
<button>Check constraints</button>
CSS:
td {
width:100px;
height:50px;
border:1px solid black;
}
table {
border:1px solid black;
border-collapse:collapse;
}
td.invalid {
background:red;
}
JS:
$('td').attr('contenteditable',true);
var cell;
function highlight(){
$(arguments).toggleClass('invalid',true);
}
function checkConstraints(e){
//reset style before re-checking
$('td.invalid').toggleClass('invalid');
//get rows as an array of array
var rows = $('tr').map(function(elem,i){
return [$(this).children('td').toArray()];
}).toArray();
//loop through the rows
for(var i = 0; i < rows.length; i++){
cell = {};
for(var j = 0; j < rows[i].length; j++){
var cellText = $(rows[i][j]).text();
if(cell[cellText]) {
highlight(cell[cellText], rows[i][j]);
} else {
cell[cellText] = rows[i][j];
}
if(i < rows.length - 1 &&
cellText == $(rows[i+1][j]).text()){
highlight(rows[i][j],rows[i+1][j]);
}
}
}
}
$('button').click(checkConstraints);
Demo.
Note that, I set contenteditable for all the cells (td), you can edit the cells text to what you want and click the button to test the demo.
You can use the table rows and cells collections for the iteration. The following does a literal comparison of the text content, you may wish to process the text first to "normalise" it in regard to whitespace.
<table id="t0">
<tr><td>foo<td>bar<td>fum</td>
<tr><td>fum<td>bar<td>foo</td>
<tr><td>foo<td>fum<td>fum</td>
</table>
<script>
compareRows(document.getElementById('t0'));
function compareRows(table) {
var row, rows = table.rows;
var cell, cells;
var rowText;
// For each row in the table
for (var i=0, iLen=rows.length; i<iLen; i++) {
row = rows[i];
cells = row.cells;
// Compare the text in each cell
for (var j=0, jLen=cells.length; j<jLen; j++) {
cell = cells[j];
for (var k=0; k<jLen; k++)
if (k != j && cells[k].textContent == cell.textContent) {
// cell text is repeated in current row
console.log('row ' + i + ' cell ' + j + ' text repeated in cell ' + k);
}
// Compare with the text in the cell immediately below (if there is one)
if (i < iLen-2 && cell.textContent == rows[i+1].cells[j].textContent) {
// cell text is repeated in next row
console.log('row ' + i + ' cell ' + j + ' text repeated in row ' + (i+1));
}
}
}
}
</script>
Note that repeated text in a row will be reported twice.
The above uses the textContent property, which may be supported as innerText in some user agents. It also runs about 10 times faster than the jQuery alternative.
I am trying to add text to each cell in particular column via Javascript. Like every 8th TD would be processed for adding text.
Tell me what I have done wrong here/why it doesn't appear in my table:
<script type="text/javascript">
window.onload = function inventorytable() {
var tableRows = document.getElementById
("inventorytable").getElementsByTagName("tbody")[0].getElementsByTagName("tr");
for(var i = 0, l = tableRows.length; i < l; i++) {
tds = tableRows.getElementsByTagName("td");
var processor = tds[8].innerHTML += " Ghz"
var ram = tds[9].innerHTML += " GB"
var rspeed = tds[11].innerHTML += " Mhz"
}}
</script>
You've forgotten to refer to the i-th row:
tds = tableRows[i].getElementsByTagName("td");
I recommend to use:
window.onload = function inventorytable() {
var tableRows = document.getElementById("inventorytable").rows;
//or .tBodies[0].rows
for(var i=0, l=tableRows.length; i < l; i++) {
var tds = tableRows[i].cells;
/*processor*/ tds[8].innerHTML += " Ghz"
/*ram */ tds[9].innerHTML += " GB"
/* rspeed */ tds[11].innerHTML += " Mhz"
}
}
Do not define unused variables. If you want to clarify their use, use comments.
Also, I have replaced .getElementsByTagName by .rows and .cells.
Update
JavaScript sets are zero-based. So, if you want to refer to the 4th cell, use .cells[3].
At your previous answer, you've showed a fiddle. see http://jsfiddle.net/ndfh2/.
As you can see, the first row is also getting postfixes. To not add postfixes to these cells in the first row, initiate the counter at one: for( var i=1; .. ; .. )
Your current code does probably not work, because your rows don't have twelve (12) rows. Remember, the number at tds[ number ] equals the index of a cell within a row, starting at zero.