Populate html table with multiple value ranges from an array - javascript

I'm trying to populate the table with the "cost" values from the array.
e.g. cells 1A - 1D should display the price $3.49,
2A - 6D should display $6.59, and 7A - 10D should display $1.99
It's working for the last range (cells 7A - 10D) as seen in my jsfiddle
Any help is much appreciated.
JsFiddle: https://jsfiddle.net/Fraser_M/ct9Lm9er/
JS:
$(function () {
var myArray = [{
"range": ["1A", "1D"],
"cost": 3.49,
"group": "My group 1"
}, {
"range": ["2A", "6D"],
"cost": 6.59,
"group": "My group 2"
}, {
"range": ["7A", "10D"],
"cost": 1.99,
"group": "My group 3"
}];
var rows = $('.row').length;
for (var i = 0; i < rows; i++) {
// number each row 1-10
var rowIndex = $('.row')[i].rowIndex + 1;
console.log(rowIndex);
}
for (var i = 0; i < rows; i++) {
// get range start number
var rangeBegin = (myArray[i].range[0].replace(/\D/g, ''));
// get range end number
var rangeEnd = (myArray[i].range[1].replace(/\D/g, ''));
console.log(rangeBegin, rangeEnd);
if ((rowIndex >= rangeBegin) && (rowIndex <= rangeEnd)) {
// Append values to table
$('.row' + (rangeBegin - 1)).nextUntil('.row' + (rangeEnd + 1)).children().append("<br>$" + myArray[i].cost);
}
}
});

Here's a way to do it using a collection of <td> cells and slice() method to filter the appropriate cells to populate
Basic concept is to get beginning and ending indices from the range selectors.
var $cells= $('td')
$.each(myArray, function(_,item){
// index range elements within `$cells` collection
var startIndex = $cells.index( $('#' + item.range[0]) ),
lastIndex = $cells.index( $('#' + item.range[1]) ) + 1;
// slice and populate $cells
$cells.slice(startIndex, lastIndex).append('<br>$' + item.cost);
});
DEMO

Loop through starting row to ending row and inside this loop through A to D using ASCII value like following.
var myArray = [{
"range": ["1A", "1D"],
"cost": 3.49,
"group": "My group 1"
}, {
"range": ["2A", "6D"],
"cost": 6.59,
"group": "My group 2"
}, {
"range": ["7A", "10D"],
"cost": 1.99,
"group": "My group 3"
}];
$.each(myArray, function () {
var start = this.range[0].slice(0, -1) * 1; // get starting row num
var end = this.range[1].slice(0, -1) * 1; // get ending row num
for (var i = start; i <= end; i++) { //loop through starting row to ending row
for (var j = 65; j <= 68; j++) { //loop through 'A' to 'D'
$('#' + i + String.fromCharCode(j)).append('<br/>$' + this.cost);
}
}
});
FIDDLE

$(function () {
var myArray = [{
"range": ["1A", "1D"],
"cost": 3.49,
"group": "My group 1"
}, {
"range": ["2A", "6D"],
"cost": 6.59,
"group": "My group 2"
}, {
"range": ["7A", "10D"],
"cost": 1.99,
"group": "My group 3"
}];
var rows = $('.row').length;
var rowIndex = 0;
for (var i = 0; i < rows; i++) {
// number each row 1-10
rowIndex = $('.row')[i].rowIndex + 1;
console.log(rowIndex);
}
for (var i = 0; i < rows; i++) {
// get range start row number
var rangeBegin = (myArray[i].range[0].replace(/\D/g, ''));
// get range end row number
var rangeEnd = (myArray[i].range[1].replace(/\D/g, ''));
rangeEnd = parseInt(rangeEnd) +1;
console.log(rangeBegin, rangeEnd);
if ((rowIndex >= rangeBegin) || (rowIndex <= rangeEnd)) {
$('.row' + (rangeBegin)).children().append("<br>$" + myArray[i].cost);
$('.row' + (rangeBegin)).nextUntil(".row"+rangeEnd).children().append("<br>$" + myArray[i].cost);
}
}
});
td {
border: 1px solid black;
padding: 2px 10px 2px 10px;
text-align: center;
border-radius: 2px;
}
<table>
<tr class="row row1">
<td class='m' id='1A'>1A</td>
<td class='m' id='1B'>1B</td>
<td class='m' id='1C'>1C</td>
<td class='m' id='1D'>1D</td>
</tr>
<tr class="row row2">
<td class='m' id='2A'>2A</td>
<td class='m' id='2B'>2B</td>
<td class='m' id='2C'>2C</td>
<td class='m' id='2D'>2D</td>
</tr>
<tr class="row row3">
<td class='m' id='3A'>3A</td>
<td class='m' id='3B'>3B</td>
<td class='m' id='3C'>3C</td>
<td class='m' id='3D'>3D</td>
</tr>
<tr class="row row4">
<td class='m' id='4A'>4A</td>
<td class='m' id='4B'>4B</td>
<td class='m' id='4C'>4C</td>
<td class='m' id='4D'>4D</td>
</tr>
<tr class="row row5">
<td class='m' id='5A'>5A</td>
<td class='m' id='5B'>5B</td>
<td class='m' id='5C'>5C</td>
<td class='m' id='5D'>5D</td>
</tr>
<tr class="row row6">
<td class='m' id='6A'>6A</td>
<td class='m' id='6B'>6B</td>
<td class='m' id='6C'>6C</td>
<td class='m' id='6D'>6D</td>
</tr>
<tr class="row row7">
<td class='m' id='7A'>7A</td>
<td class='m' id='7B'>7B</td>
<td class='m' id='7C'>7C</td>
<td class='m' id='7D'>7D</td>
</tr>
<tr class="row row8">
<td class='m' id='8A'>8A</td>
<td class='m' id='8B'>8B</td>
<td class='m' id='8C'>8C</td>
<td class='m' id='8D'>8D</td>
</tr>
<tr class="row row9">
<td class='m' id='9A'>9A</td>
<td class='m' id='9B'>9B</td>
<td class='m' id='9C'>9C</td>
<td class='m' id='9D'>9D</td>
</tr>
<tr class="row row10">
<td class='m' id='10A'>10A</td>
<td class='m' id='10B'>10B</td>
<td class='m' id='10C'>10C</td>
<td class='m' id='10D'>10D</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>

Solution with a single for loop:
$(function() {
var myArray = [{
"range": ["1A", "1D"],
"cost": 3.49,
"group": "My group 1"
}, {
"range": ["2A", "6D"],
"cost": 6.59,
"group": "My group 2"
}, {
"range": ["7A", "10D"],
"cost": 1.99,
"group": "My group 3"
}];
var rows = $('.row').length;
var rangeObj = { // set of number limits
'group1': [myArray[0].range[0][0], myArray[0].range[1][0]],
'group2': [myArray[1].range[0][0], myArray[1].range[1][0]],
'group3': [myArray[2].range[0][0], myArray[2].range[1].substr(0,2)]
};
var rowIndex = 0;
for (var i = 0; i < rows; i++) {
var currentIndex = $('.row')[i].rowIndex + 1;
if (rowIndex > currentIndex) {
continue; // bypass redundant iterations
} else {
rowIndex = currentIndex;
}
var groupIndex = 0;
if ((rowIndex >= rangeObj.group1[0]) && (rowIndex <= rangeObj.group1[1])){
groupIndex = '1';
} else if ((rowIndex >= rangeObj.group2[0]) && (rowIndex <= rangeObj.group2[1])) {
groupIndex = '2';
} else if ((rowIndex >= rangeObj.group3[0]) && (rowIndex <= rangeObj.group3[1])) {
groupIndex = '3';
}
// get range start row number
var rangeBegin = parseInt(rangeObj['group' + groupIndex][0]);
// get range end row number
var rangeEnd = parseInt(rangeObj['group' + groupIndex][1]);
//console.log(rangeBegin, rangeEnd);
var startClass = (rangeBegin - 1)? (rangeBegin - 1) : 1;
if ((rowIndex >= rangeBegin) && (rowIndex <= rangeEnd)) {
if (rowIndex === 1) $('.row' + startClass).children().append("<br>$" + myArray[parseInt(groupIndex) - 1].cost);
$('.row' + startClass).nextUntil('.row' + (rangeEnd + 1)).children().append("<br>$" + myArray[parseInt(groupIndex) - 1].cost);
rowIndex = rangeEnd + 1;
}
}
});
https://jsfiddle.net/272kk7yx/

Related

jQuery - Combine <TR>(s) values that are in same Section # with same Group # / remove duplicates

I have updated the code, which is currently working up to the Place for each Group #. The existing code determines a matching Section # with Group #, and combines the TR values, adding the Average(s) and dividing by the number of TR(s), and removing any duplicate(s).
I am attempting to determine a Place for each Group # within a Section #. (*example - Section 1: Group #1 - 1st / Group #2 - 3rd / Group #3 - 2nd)
$(function() {
alert('View Table Before Grouping');
sort_array();
combine_rows();
compute_average();
});
//function sort_array
function sort_array() {
var $table = $('table');
var header = $('table tr:first-child').html();
var l = [];
$table.find('tr').each( function() {
//get values from td(s) from each row
var section = $(this).find('.class_section_number').text();
var group_number = $(this).find('.group_number').text();
var average = $(this).find('td:eq(2)').text();
var place = $(this).find('td:eq(3)').text();
//add to array
l.push([section, group_number, average, place]);
//remove saved row
$(this).remove();
});
l = l.slice(1);
//sort the array by section #, then group #
l.sortBy(0, true, 1, true, 2, false);
$table.prepend(header);
//rebuild table after sort
$.each(l, function(key, value) {
$('table').append('<tr><td class="class_section_number">' + value[0] + '</td><td class="group_number">' + value[1] + '</td><td class="grade">' + value[2] + '</td><td>' + value[3] + '</td></tr>');
});
}
//function combine_rows
function combine_rows() {
$('table tr').each( function() {
//get current row data
var section = $(this).find('.class_section_number').text();
var group = $(this).find('.group_number').text();
var average = $(this).find('td:eq(2)').text();
//get next row data
var next_section = $(this).next('tr').find('.class_section_number').text();
var next_group = $(this).next('tr').find('.group_number').text();
var next_average = $(this).next('tr').find('td:eq(2)').text();
//check for section # / group # row match
if ((section === next_section) && (group === next_group)) {
//check for empty average
if (average === 'No Data') {
average = 0 + ',' + next_average;
}
else {
average = average + ',' + next_average;
}
//set combined average
$(this).next('tr').find('td:eq(2)').text(average);
//remove matching row
$(this).remove();
}
});
}
//function compute_average
function compute_average() {
$('table tr').each( function() {
//get average from row
var average = $(this).find('td:eq(2)').text();
//split average into array (*if comma separated values)
average_array = average.split(',');
var total = 0;
//total average values from array / divide by count and set
for (var i = 0; i < average_array.length; i++) {
total += (+average_array[i]);
$(this).find('td:eq(2)').text((total / average_array.length).toFixed(2));
}
});
}
//array sort function
Array.prototype.sortBy = function (propertyName, sortDirection) {
var sortArguments = arguments;
this.sort(function (objA, objB) {
var result = 0;
for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {
var propertyName = sortArguments[argIndex];
result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;
result *= sortArguments[argIndex + 1] ? 1 : -1;
}
return result;
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th>Section #</th>
<th>Group #</th>
<th>Averages</th>
<th>Place</th>
</tr>
<tr>
<td class="class_section_number">1</td>
<td class="group_number">2</td>
<td class="grade">78.29</td>
<td>Test Place 1st</td>
</tr>
<tr>
<td class="class_section_number">1</td>
<td class="group_number">2</td>
<td class="grade">85.52</td>
<td>Test Place 1st</td>
</tr>
<tr>
<td class="class_section_number">1</td>
<td class="group_number">1</td>
<td class="grade">74.41</td>
<td>Test Place 2nd</td>
</tr>
<tr>
<td class="class_section_number">1</td>
<td class="group_number">2</td>
<td>No Data</td>
<td>Test Place 3rd</td>
</tr>
<tr><td class="class_section_number">2</td>
<td class="group_number">1</td>
<td class="grade">78.90</td>
<td>Test Place 2nd</td>
</tr>
</tr>
<tr><td class="class_section_number">1</td>
<td class="group_number">3</td>
<td class="grade">91.03</td>
<td>Test Place 2nd</td>
</tr>
</tr>
<tr><td class="class_section_number">2</td>
<td class="group_number">2</td>
<td class="grade">81.69</td>
<td>Test Place 2nd</td>
</tr>
<tr>
<td class="class_section_number">2</td>
<td class="group_number">2</td>
<td class="grade">81.13</td>
<td>Test Place 1st</td>
</tr>
<tr>
<td class="class_section_number">2</td>
<td class="group_number">2</td>
<td class="grade">78.13</td>
<td>Test Place 1st</td>
</tr>
</tbody>
</table>

Populate specific html elements with javascript variable values

I have a JS-function that counts duplicate keys from array of objects and prints keys (category names) and the amount of duplicate keys.
What I want to do is loop through a set of html-elements with specific class and print the values in them.
Here is the HTML I want to achieve
<table>
<th>Category name</th>
<th>Category count</th>
<tr>
<td class="cat_name">Shoes</td>
<td class="cat_amount">2</td>
</tr>
<tr>
<td class="cat_name">Shirts</td>
<td class="cat_amount">1</td>
</tr>
<tr>
<td class="cat_name">Hats</td>
<td class="cat_amount">3</td>
</tr>
</table>
And here is what I have achieved so far with my javascript function.
<table>
<th>Category name</th>
<th>Category count</th>
<tr>
<td class="cat_name">Shoes</td>
<td class="cat_amount">2</td>
</tr>
<tr>
<td class="cat_name">Shoes</td>
<td class="cat_amount">2</td>
</tr>
<tr>
<td class="cat_name">Shoes</td>
<td class="cat_amount">2</td>
</tr>
</table>
So basically i probably should somehow loop through all the elements and all the values and individually inject the values but i don't know how.
My code:
var myObject = [
{
"product": "Tennis shoes",
"price": "10€",
"categoryname": "Shoes"
},
{
"product": "High heels",
"price": "40€",
"categoryname": "Shoes"
},
{
"product": "Basic shirt",
"price": "20€",
"categoryname": "Shirts"
},
{
"product": "Huge Cap",
"price": "15€",
"categoryname": "Hats"
},
{
"product": "Mage hat",
"price": "25€",
"categoryname": "Hats"
},
{
"product": "Wizard hat",
"price": "45€",
"categoryname": "Hats"
}
];
function countCategorynames() {
var counter = {};
for (var i = 0; i < myObject.length; i += 1) {
counter[this.myObject[i].categoryname] = (counter[this.myObject[i].categoryname] || 0) + 1;
}
for (var key in counter) {
if (counter[key] > 0) {
console.log("we have ", key, " duplicated ", counter[key], " times");
var el1 = document.getElementsByClassName('cat_name');
for (var i = 0; i < el1.length; i++) {
el1[i].innerHTML = key;
}//for
var el2 = document.getElementsByClassName('cat_amount');
for (var i = 0; i < el2.length; i++) {
el2[i].innerHTML = counter[key];
}//for
}//if
}// for
}// function
<table>
<th>Category name</th>
<th>Category count</th>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
</table>
<button onClick="countCategorynames()">Count</button>
You were on the right track. Here's an example of one way to loop through your values and insert them into a table.
// declaration of myObject for this example
var myObject = [{
"categoryname": "Shoes"
},
{
"categoryname": "Shoes"
},
{
"categoryname": "Shirts"
},
{
"categoryname": "Hats"
},
{
"categoryname": "Hats"
},
{
"categoryname": "Hats"
}
];
var el1 = document.getElementsByClassName('cat_name');
var el2 = document.getElementsByClassName('cat_amount');
function countCategorynames() {
var counter = {};
for (var i = 0; i < myObject.length; i++) {
counter[myObject[i].categoryname] = (counter[myObject[i].categoryname] || 0) + 1;
}
var j = 0; // variable to use as a counter for the table
for (var key in counter) {
if (counter[key] > 0) {
console.log("we have ", key, " duplicated ", counter[key], " times");
//This prints out each categoryname and the amount of duplicates
//for example
//we have Shoes duplicated 2 times
//we have Shirts duplicated 1 times etc...
el1[j].innerHTML = key;
el2[j++].innerHTML = counter[key]; // increment the counter
}
}
}
countCategorynames();
<table>
<th>Category name</th>
<th>Category count</th>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
<tr>
<td class="cat_name"></td>
<td class="cat_amount"></td>
</tr>
</table>
From the looks of what you have in your code so far, myObject seems to be an array of objects; you may want to consider renaming it. If it isn't an array, then you'll need to loop through it using the keys rather than just the .length property.
You were declaring el1 and el2 multiple times, which isn't really wrong but doesn't need to be done. You can declare the variables one time and refer to them in each iteration, since the elements inside the node list aren't changing.
The way you had it set up, you were grabbing the last value for both the category name and the number each time, so that's the only value that was getting applied. Your code was heading in the right direction; it was just the timing that was off.
both for loops you are running to embed the html is at wrong place.. those will always run and finally updated the last value to your html.
You need to do some changes in code as follows:
function countCategorynames(myObject) {
var counter = {};
for (var i = 0; i < myObject.length; i += 1) {
counter[myObject[i].categoryname] = (counter[myObject[i].categoryname] || 0) + 1;
}
var el1 = document.getElementsByClassName('cat_name');
var el2 = document.getElementsByClassName('cat_amount');
for (var key in counter) {
if (counter[key] > 0) {
console.log("we have ", key, " duplicated ", counter[key], " times");
//This prints out each categoryname and the amount of duplicates
//for example
//we have Shoes duplicated 2 times
//we have Shirts duplicated 1 times etc...
//This is my attempt to get all elements with class
//'cat_name' and 'cat_amount'
//and populate them with values from the object
el1[i].innerHTML = key;
el2[i].innerHTML = counter[key];
}
}
}

I can't swap images in the first or last row of my table

I am trying to make pictures swap. there is 16 squares however for some reason I cant move to the last or first row of the 2d array of table cells.
does anyone see my problem? this is my Javascript:
var cellArray;
var knight = "<img src=\"Knight.png" + "\">";
var pit = "<img src=\"Pit.png" + "\">";
var princess = "<img src=\"princess.png" + "\">";
function makeCells()
{
cellArray = new Array(
[
document.getElementById("c1"),
document.getElementById("c2"),
document.getElementById("c3"),
document.getElementById("c4")],
[ document.getElementById("c5"),
document.getElementById("c6"),
document.getElementById("c7"),
document.getElementById("c8")],
[ document.getElementById("c9"),
document.getElementById("c10"),
document.getElementById("c11"),
document.getElementById("c12")],
[ document.getElementById("c13"),
document.getElementById("c14"),
document.getElementById("c15"),
document.getElementById("c16")
]);
placePictures();
}
function placePictures()
{
// var princess = document.createElement("img");
// princess.src = "princess.png";
// var pit = document.createElement("img");
// pit.src = "Pit.png";
//var randomArrayElement = Math.floor(Math.random() * (16));
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(i == 0 && j == 0)
{
cellArray[i][j].innerHTML = knight;;
for(k = 0; k < 3; k++)
{
var row = Math.floor(Math.random() * (3));
var col = Math.floor(Math.random() * (3));
if(row !== 0 && col !== 0 || row !== col || row !== 3 && col !== 3)
cellArray[row][col].innerHTML = pit;
}
}
if(i == 3 && j == 3)
{
cellArray[i][j].innerHTML = princess;
}
}
}
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(cellArray[i][j].innerHTML == "")
cellArray[i][j].innerHTML = "<img src = Floor.png>";
}
}
}
function clickIt(row, col)
{
var top = (row - 1);
var bottom = (row + 1);
var left = (col - 1);
var right = (col + 1);
var temp = cellArray[row][col].innerHTML;
if(cellArray[top][col].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[top][col].innerHTML;
cellArray[top][col].innerHTML = temp;
}
else if(cellArray[bottom][col].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[bottom][col].innerHTML;
cellArray[bottom][col].innerHTML = temp;
}
else if(cellArray[row][left].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[row][left].innerHTML;
cellArray[row][left].innerHTML = temp;
}
else if(cellArray[row][right].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[row][right].innerHTML;
cellArray[row][right].innerHTML = temp;
}
else
{
alert("NOPE");
}
alert("End");
}
HTML:
<html>
<head>
<title>Maze Runner</title>
<script src="javascriptMazeRunner.js"></script>
<link rel="stylesheet" type="text/css" href="MazeRunnerCSS.css"/>
</head>
<body onload="makeCells()">
<form id="MainForm">
<table id="MazeTable">
<tr id="Row1">
<td id="c1" class="Blue" onclick="clickIt(0,0)"></td>
<td id="c2" class="Blue" onclick="clickIt(0,1)"></td>
<td id="c3" class="Blue" onclick="clickIt(0,2)"></td>
<td id="c4" class="Blue" onclick="clickIt(0,3)"></td>
</tr>
<tr id="Row2">
<td id="c5" class="Blue" onclick="clickIt(1,0)"></td>
<td id="c6" class="Blue" onclick="clickIt(1,1)"></td>
<td id="c7" class="Blue" onclick="clickIt(1,2)"></td>
<td id="c8" class="Blue" onclick="clickIt(1,3)"></td>
</tr>
<tr id="Row3">
<td id="c9" class="Blue" onclick="clickIt(2,0)"></td>
<td id="c10" class="Blue" onclick="clickIt(2,1)"></td>
<td id="c11" class="Blue" onclick="clickIt(2,2)"></td>
<td id="c12" class="Blue" onclick="clickIt(2,3)"></td>
</tr>
<tr id="Row4">
<td id="c13" class="Blue" onclick="clickIt(3,0)"></td>
<td id="c14" class="Blue" onclick="clickIt(3,1)"></td>
<td id="c15" class="Blue" onclick="clickIt(3,2)"></td>
<td id="c16" class="Blue" onclick="clickIt(3,3)"></td>
</tr>
</table>
</form>
</body>
</html>
I found that your top,bottom,right variables cross the boundary of cellArray(top become -1 and bottom,right become 4), I recommend you try this code and modify it based on your demand:
var cellArray;
var knight = "<img src=\"Knight.png" + "\">";
var pit = "<img src=\"Pit.png" + "\">";
var princess = "<img src=\"princess.png" + "\">";
function makeCells()
{
cellArray = new Array(
[
document.getElementById("c1"),
document.getElementById("c2"),
document.getElementById("c3"),
document.getElementById("c4")],
[document.getElementById("c5"),
document.getElementById("c6"),
document.getElementById("c7"),
document.getElementById("c8")],
[document.getElementById("c9"),
document.getElementById("c10"),
document.getElementById("c11"),
document.getElementById("c12")],
[document.getElementById("c13"),
document.getElementById("c14"),
document.getElementById("c15"),
document.getElementById("c16")
]);
placePictures();
}
function placePictures()
{
// var princess = document.createElement("img");
// princess.src = "princess.png";
// var pit = document.createElement("img");
// pit.src = "Pit.png";
//var randomArrayElement = Math.floor(Math.random() * (16));
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (i == 0 && j == 0)
{
cellArray[i][j].innerHTML = knight;
;
for (k = 0; k < 3; k++)
{
var row = Math.floor(Math.random() * (3));
var col = Math.floor(Math.random() * (3));
if (row !== 0 && col !== 0 || row !== col || row !== 3 && col !== 3)
cellArray[row][col].innerHTML = pit;
}
}
if (i == 3 && j == 3)
{
cellArray[i][j].innerHTML = princess;
}
}
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (cellArray[i][j].innerHTML == "")
cellArray[i][j].innerHTML = "<img src = Floor.png>";
}
}
}
function clickIt(row, col)
{
var top = (row - 1);
var bottom = (row + 1);
var left = (col - 1);
var right = (col + 1);
var temp = cellArray[row][col].innerHTML;
if(top < 0)
top = 0;
if(bottom >= cellArray[row].length)
bottom = cellArray[row].length-1;
if(right >= cellArray[row].length)
right = cellArray[row].length-1;
if (cellArray[top][col].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[top][col].innerHTML;
cellArray[top][col].innerHTML = temp;
} else if (cellArray[bottom][col].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[bottom][col].innerHTML;
cellArray[bottom][col].innerHTML = temp;
} else if (cellArray[row][left].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[row][left].innerHTML;
cellArray[row][left].innerHTML = temp;
} else if (cellArray[row][right].innerHTML === knight && cellArray[row][col].innerHTML !== pit)
{
cellArray[row][col].innerHTML = cellArray[row][right].innerHTML;
cellArray[row][right].innerHTML = temp;
} else
{
alert("NOPE");
}
alert("End");
}
makeCells();
<form id="MainForm">
<table id="MazeTable">
<tr id="Row1">
<td id="c1" class="Blue" onclick="clickIt(0, 0)"></td>
<td id="c2" class="Blue" onclick="clickIt(0, 1)"></td>
<td id="c3" class="Blue" onclick="clickIt(0, 2)"></td>
<td id="c4" class="Blue" onclick="clickIt(0, 3)"></td>
</tr>
<tr id="Row2">
<td id="c5" class="Blue" onclick="clickIt(1, 0)"></td>
<td id="c6" class="Blue" onclick="clickIt(1, 1)"></td>
<td id="c7" class="Blue" onclick="clickIt(1, 2)"></td>
<td id="c8" class="Blue" onclick="clickIt(1, 3)"></td>
</tr>
<tr id="Row3">
<td id="c9" class="Blue" onclick="clickIt(2, 0)"></td>
<td id="c10" class="Blue" onclick="clickIt(2, 1)"></td>
<td id="c11" class="Blue" onclick="clickIt(2, 2)"></td>
<td id="c12" class="Blue" onclick="clickIt(2, 3)"></td>
</tr>
<tr id="Row4">
<td id="c13" class="Blue" onclick="clickIt(3, 0)"></td>
<td id="c14" class="Blue" onclick="clickIt(3, 1)"></td>
<td id="c15" class="Blue" onclick="clickIt(3, 2)"></td>
<td id="c16" class="Blue" onclick="clickIt(3, 3)"></td>
</tr>
</table>
</form>
I hope this work :)
from what i can spot in your code is, whenever any border rows are clicked for ex: ID "C1", the line:
cellArray[top][col].innerHTML
would imply
cellArray[-1][-1].innerHTML
which is rather an invalid reference and this will cause the script to crash and not execute any further thus, contributing to your problem.

Iterate over table cells, re-using rowspan values

I have a simple HTML table, which uses rowspans in some random columns. An example might look like
A | B |
---|---| C
D | |
---| E |---
F | | G
I'd like to iterate over the rows such that I see rows as A,B,C, D,E,C, then F,E,G.
I think I can probably cobble together something very convoluted using cell.index() to check for "missed" columns in later rows, but I'd like something a little more elegant...
without jquery:
function tableToMatrix(table) {
var M = [];
for (var i = 0; i < table.rows.length; i++) {
var tr = table.rows[i];
M[i] = [];
for (var j = 0, k = 0; j < M[0].length || k < tr.cells.length;) {
var c = (M[i-1]||[])[j];
// first check if there's a continuing cell above with rowSpan
if (c && c.parentNode.rowIndex + c.rowSpan > i) {
M[i].push(...Array.from({length: c.colSpan}, () => c))
j += c.colSpan;
} else if (tr.cells[k]) {
var td = tr.cells[k++];
M[i].push(...Array.from({length: td.colSpan}, () => td));
j += td.colSpan;
}
}
}
return M;
}
var M = tableToMatrix(document.querySelector('table'));
console.table(M.map(r => r.map(c => c.innerText)));
var pre = document.createElement('pre');
pre.innerText = M.map(row => row.map(c => c.innerText).join('\t')).join('\n');
document.body.append(pre);
td {
border: 1px solid rgba(0,0,0,.3);
}
<table>
<tr>
<td colspan=2>A</td>
<td rowspan=2>B</td>
</tr>
<tr>
<td>C</td>
<td rowspan=3>D</td>
</tr>
<tr>
<td rowspan=2>E</td>
<td rowspan=4>F</td>
</tr>
<tr></tr>
<tr>
<td rowspan=2 colspan=2>G</td>
</tr>
<tr></tr>
<tr>
<td rowspan=3 colspan=3>H</td>
</tr>
<tr></tr>
<tr></tr>
<tr>
<td colspan=3>I</td>
</tr>
</table>
Try this:
<table id="tbl">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="2" rowspan="2">A</td>
<td rowspan="2">C</td>
</tr>
<tr>
<td rowspan="2">E</td>
</tr>
<tr>
<td>F</td>
<td>G</td>
</tr>
</table>
Script:
var finalResult = '';
var totalTds = $('#tbl TR')[0].length;
var trArray = [];
var trArrayValue = [];
var trIndex = 1;
$('#tbl TR').each(function(){
var currentTr = $(this);
var tdIndex = 1;
trArray[trIndex] = [];
trArrayValue[trIndex] = [];
var tdActuallyTraversed = 0;
var colspanCount = 1;
$('#tbl TR').first().children().each(function(){
if(trIndex > 1 && trArray[trIndex - 1][tdIndex] > 1)
{
trArray[trIndex][tdIndex] = trArray[trIndex - 1][tdIndex] - 1;
trArrayValue[trIndex][tdIndex] = trArrayValue[trIndex - 1][tdIndex];
finalResult = finalResult + trArrayValue[trIndex][tdIndex];
}
else
{
if(colspanCount <= 1)
{
colspanCount = currentTr.children().eq(tdActuallyTraversed).attr('colspan') != undefined ? currentTr.children().eq(tdActuallyTraversed).attr('colspan') : 1;
}
if(colspanCount > 1 && tdIndex > 1)
{
trArray[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed + colspanCount).attr('rowspan') != undefined ?currentTr.children().eq(tdActuallyTraversed + colspanCount).attr('rowspan') : 1;
trArrayValue[trIndex][tdIndex] = trArrayValue[trIndex][tdIndex - 1];
colspanCount--;
}
else
{
trArray[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed).attr('rowspan') != undefined ?currentTr.children().eq(tdActuallyTraversed).attr('rowspan') : 1;
trArrayValue[trIndex][tdIndex] = currentTr.children().eq(tdActuallyTraversed).html();
tdActuallyTraversed++;
}
finalResult = finalResult + trArrayValue[trIndex][tdIndex];
}
tdIndex++;
});
trIndex++;
});
alert(finalResult);
Fiddle
i am not sure about the performance, but it works well.
what I understood with your question is: You want to split the merged cell with same value and then iterate the table simply by row.
I've created a JSFiddle that will split the merged cells with the same value. Then you'll have a table that can be iterated simply by rows to get the desired output that you specified.
See it running here http://jsfiddle.net/9PZQj/3/
Here's the complete code:
<table id="tbl" border = "1">
<tr>
<td>A</td>
<td>B</td>
<td rowspan="2">C</td>
</tr>
<tr>
<td>D</td>
<td rowspan="2">E</td>
</tr>
<tr>
<td>F</td>
<td>G</td>
</tr>
</table>
<br>
<div id="test"> </div>
Here's the jquery that is used to manipulate the table's data.
var tempTable = $('#tbl').clone(true);
var tableBody = $(tempTable).children();
$(tableBody).children().each(function(index , item){
var currentRow = item;
$(currentRow).children().each(function(index1, item1){
if($(item1).attr("rowspan"))
{
// copy the cell
var item2 = $(item1).clone(true);
// Remove rowspan
$(item1).removeAttr("rowspan");
$(item2).removeAttr("rowspan");
// last item's index in next row
var indexOfLastElement = $(currentRow).next().last().index();
if(indexOfLastElement <= index1)
{
$(currentRow).next().append(item2)
}
else
{
// intermediate cell insertion at right position
$(item2).insertBefore($(currentRow).next().children().eq(index1))
}
}
});
console.log(currentRow)
});
$('#test').append(tempTable);
You can use this Gist. It supports all the requirements by W3C, even "rowspan=0" (which seems to be only supported by Firefox).

How to count number of disabled columns in a table from javascript?

My table format is
<table class"tabletop">
<tr>
<td>
<table>
<tr>
<td id="mycol1"></td>
<td id="mycol2"></td>
<td id="mycol3"></td>
<td id="mycol4"></td>
</tr>
</table>
</td>
</tr>
<tr>
</tr>
</table>
I have to count columns(having id's) that are not disabled(or their display is not none) and that are disabled.
Suppose columns disabled are 4 and not disabled are 2.
So it must return disabled: 4 and not disabled: 2
td's are disabled by their id.
eg
mycol1.style.display="none";
Working Solution try this
<script type = "text/javascript" language = "javascript">
function getHiddenColumnCount() {
var tbl = document.getElementById("myTbl");
var HiddenColumnCount = 0;
for(var OuterCounter = 0 ; OuterCounter < tbl.rows.length ; OuterCounter++)
{
for(var InnerCounter = 0 ; InnerCounter < tbl.rows[OuterCounter].cells.length;InnerCounter++)
{
if (tbl.rows[OuterCounter].cells[InnerCounter].style.display == "none")
HiddenColumnCount++;
}
}
alert("There are " + HiddenColumnCount + " Hidden Columns in Table");
}
</script>
You can use
$('table td:visible').length
Try this: fiidle
<table border="1" id="myTbl">
<tr>
<td class="mycol1">
1
</td>
<td class="mycol2">
2
</td>
<td class="mycol3">
3
</td>
<td class="mycol4">
4
</td>
</tr>
</table>
<script>
function hideColumn(columnClass) {
var els = document.getElementsByClassName(columnClass);
for (var i = 0; i < els.length; i++) {
els[i].style.display = "none";
}
}
hideColumn('mycol1');
hideColumn('mycol2');
function getHiddenColumnsCount() {
var rows = document.getElementById('myTbl').rows;
var count = 0;
for (var i = 0; i < rows.length; i++) {
for (var j = 0; j < rows[i].cells.length; j++) {
if (rows[i].cells[j].style.display == "none")
count++;
}
}
alert(count);
}
getHiddenColumnsCount();
</script>
First of all you should use class for defining column instead of id as id should not be duplicate & to define a column we will have to give similar id to all cells of a column.

Categories

Resources