I am new to javascript. I have a table of content which I want to rearrange its row and column based on user's window size using window.onresize.
window.onresize = function () {
var w = window.innerWidth;
var nocolumn = Math.floor(w / 252);
if (nocolumn == 0) {
nocolumn = 1;
}
var table = document.getElementById("MainContent_DataList1");
var tbody = table.getElementsByTagName("tbody")[0];
var link = tbody.getElementsByTagName("a");
var norow = Math.ceil(link.length / nocolumn);
tbody.innerHTML = "";
console.log(norow + " " + link.length + " " + nocolumn);
for (var i = 0; i < norow; i++) {
var row = document.createElement("tr");
tbody.appendChild(row);
for (var j = 0; j < nocolumn; j++) {
var cell = document.createElement("td");
row.appendChild(cell);
if ((i * nocolumn + j) < link.length) {
cell.appendChild(link[i * nocolumn + j]);
}
}
}
};
I dont understand why the variable "link" array becomes empty after I use innerHTML = ""; but I stored it before its cleared. Is it somewhere I did wrongly or there are other ways to do this?
When you delete the innerHTML you delete the DOM objects thus every reference to them will point to null.
A work around it will be to clone these objects:
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
window.onresize = function () {
var w = window.innerWidth;
var nocolumn = Math.floor(w / 252);
if (nocolumn == 0) {
nocolumn = 1;
}
var table = document.getElementById("MainContent_DataList1");
var tbody = table.getElementsByTagName("tbody")[0];
var tmp = tbody.getElementsByTagName("a");
var link = clone(tmp);
var norow = Math.ceil(link.length / nocolumn);
tbody.innerHTML = "";
...
}
Credit for the clone() method: https://stackoverflow.com/a/728694/1057429
As other answers have suggested, getElementsByTagName returns a live NodeList. Therefore, when you delete all the elements from the body, the NodeList is updated to contain no nodes.
As an alternative, you can use querySelectorAll, which returns a static NodeList, or use getElementsByTagName and assign references to an array before clearing the nodes from the body, e.g.
function getNodes() {
var tbody = document.body || document.getElementsByTagName('body')[0];
var nodes, link;
if (tbody.querySelectorAll) {
link = tbody.querySelectorAll('*');
} else {
nodes = tbody.getElementsByTagName("*");
link = [];
for (var i=0, iLen=nodes.length; i<iLen; i++) {
link[i] = nodes[i];
}
}
return link;
}
Related
UPDATED WITH FULL CODE
I'm trying to dynamically add a div onto some other DIV's stored in an array
The array which contains DIV's is named categoryData which contains an attribute with its category name
The shop-row div's (categoryData) is empty at the beginning.
I've got another array which contains the product object stored in an array called
storeCategoryData
The product object is in the following format,
{CategoryName:categoryname,StoreObject:store_clearfix} // store_clearfix is another div
I'm trying to add the StoreObject into the DIV categoryData.
Unfortunately some objects get added and not the others. I can figure out what i'm doing wrong here. Any help would be much appreciated.
Thanks!
I tried doing everything possible. Still no luck :(
var store_list = document.getElementsByClassName("shop-list")[0];
if(data['stores']!=null && data['stores'] !== typeof undefined){
var numstores = Object.keys(data["stores"]).length;
var count = 0;
while (count < numstores) {
var categories = data["stores"][count].Categories;
var catcount = categories.length;
var c=0;
while(c<catcount){
var cat = categories[c];
if (!(storeCategories.indexOf(cat) > -1)) {
var category_element = document.createElement("li");
if(count==0 && c==0){
category_element.className="active";
}
var clickable = document.createElement("a");
clickable.href = "#";
clickable.innerText = cat;
clickable.setAttribute("category-data", cat);
storeCategories.push(cat);
category_element.appendChild(clickable);
category_list.appendChild(category_element);
var div = document.createElement("div");
div.className = "shop-row";
div.setAttribute("category-name", cat);
categoryData.push(div);
}
c++;
}
count++;
}
count = 0;
while (count < numstores) {
var StoreId = data["stores"][count].StoreId;
var WebsiteUrl = data["stores"][count].WebsiteUrl;
var LogoUrl = data["stores"][count].LogoUrl;
var categories = data["stores"][count].Categories;
var store_clearfix = document.createElement("div");
store_clearfix.className = "single-products-catagory clearfix";
var store_atag = document.createElement("a");
store_atag.className = "home-shop";
store_atag.href = WebsiteUrl;
var store_img = document.createElement("img");
store_img.className = "shop-icon";
store_img.src = LogoUrl;
store_img.alt = StoreId;
store_atag.appendChild(store_img);
store_clearfix.appendChild(store_atag);
c=0;
catcount = categories.length;
while(c<catcount){
var categoryname = categories[c];
var i = 0;
var datacount = categoryData.length;
while(i<datacount){
var datarow = categoryData[i];
if(categoryname==datarow.getAttribute("category-name")) {
var storeObj = {CategoryName:categoryname,StoreObject:store_clearfix};
storeCategoryData.push(storeObj);
break;
}
i++;
}
c++;
}
count++;
}
categories_tab.appendChild(category_list);
i=0;
for (i = 0; i < categoryData.length; i++) {
var div = categoryData[i];
console.log(div);
var name = div.getAttribute("category-name");
var c;
for (c = 0; c < storeCategoryData.length; c++) {
console.log(storeCategoryData[c].CategoryName);
if(storeCategoryData[c].CategoryName==name){
console.log(storeCategoryData[c].StoreObject);
div.appendChild(storeCategoryData[c].StoreObject);
}
}
console.log("Finished "+name );
console.log(div);
store_list.appendChild(div);
}
}
Example variable data defined as follows
{
"status": "success",
"stores": [
{
"StoreId": "randomStore",
"WebsiteUrl": "https://abcd.com",
"LogoUrl": "https://abcd.come",
"Categories": [
"ALL",
"MENS",
"WOMENS"
]
},
{
"StoreId": "someStoreId",
"WebsiteUrl": "https://someurl.com",
"LogoUrl": "https://someLogo.com",
"Categories": [
"MENS"
]
}
]
}
The problem you are facing here is caused by the following behavior:
The Node.appendChild() method adds a node to the end of the list of
children of a specified parent node. If the given child is a reference
to an existing node in the document, appendChild() moves it from its
current position to the new position (MDN: Node.appendChild())
What this means is that appendChild will remove the node if already present in the DOM, which is what we are seeing here. This can be easily solved by creating a deep clone of the node first using cloneNode, before appending it to the target div, as follows:
var clone = storeCategoryData[c].StoreObject.cloneNode(true);
div.appendChild(clone);
You can also refer to the snippet below for a working example:
var categories_tab = document.getElementById('category-tab');
var store_list = document.getElementById('store-list');
var storeCategories = [];
var storeCategoryData = [];
var data = {
"status": "success",
"stores": [{
"StoreId": "randomStore",
"WebsiteUrl": "https://abcd.com",
"LogoUrl": "https://abcd.come",
"Categories": [
"ALL",
"MENS",
"WOMENS"
]
},
{
"StoreId": "someStoreId",
"WebsiteUrl": "https://someurl.com",
"LogoUrl": "https://someLogo.com",
"Categories": [
"MENS"
]
}
]
};
var categoryData = [];
var category_list = document.createElement("ul");
if (data['stores'] != null && data['stores'] !== typeof undefined) {
var numstores = Object.keys(data["stores"]).length;
var count = 0;
while (count < numstores) {
var categories = data["stores"][count].Categories;
var catcount = categories.length;
var c = 0;
while (c < catcount) {
var cat = categories[c];
if (!(storeCategories.indexOf(cat) > -1)) {
var category_element = document.createElement("li");
if (count == 0 && c == 0) {
category_element.className = "active";
}
var clickable = document.createElement("a");
clickable.href = "#";
clickable.innerText = cat;
clickable.setAttribute("category-data", cat);
storeCategories.push(cat);
category_element.appendChild(clickable);
category_list.appendChild(category_element);
var div = document.createElement("div");
div.className = "shop-row";
div.setAttribute("category-name", cat);
categoryData.push(div);
}
c++;
}
count++;
}
count = 0;
while (count < numstores) {
var StoreId = data["stores"][count].StoreId;
var WebsiteUrl = data["stores"][count].WebsiteUrl;
var LogoUrl = data["stores"][count].LogoUrl;
var categories = data["stores"][count].Categories;
var store_clearfix = document.createElement("div");
store_clearfix.className = "single-products-catagory clearfix";
var store_atag = document.createElement("a");
store_atag.className = "home-shop";
store_atag.href = WebsiteUrl;
var p = document.createElement("p");
p.className = "shop-icon";
var t = document.createTextNode(LogoUrl);
p.appendChild(t)
store_atag.appendChild(p);
store_clearfix.appendChild(store_atag);
c = 0;
catcount = categories.length;
while (c < catcount) {
var categoryname = categories[c];
var i = 0;
var datacount = categoryData.length;
while (i < datacount) {
var datarow = categoryData[i];
if (categoryname == datarow.getAttribute("category-name")) {
var storeObj = {
CategoryName: categoryname,
StoreObject: store_clearfix
};
storeCategoryData.push(storeObj);
break;
}
i++;
}
c++;
}
count++;
}
categories_tab.appendChild(category_list);
i = 0;
for (i = 0; i < categoryData.length; i++) {
var div = categoryData[i];
console.log(div);
var name = div.getAttribute("category-name");
var c;
for (c = 0; c < storeCategoryData.length; c++) {
console.log(storeCategoryData[c].CategoryName);
if (storeCategoryData[c].CategoryName == name) {
console.log(storeCategoryData[c].StoreObject);
var clone = storeCategoryData[c].StoreObject.cloneNode(true);
div.appendChild(clone);
}
}
console.log("Finished " + name);
console.log(div);
store_list.appendChild(div);
}
}
<div id="category-tab" style="min-height: 20px; border: 1px solid; padding: 10px"></div>
<div id="store-list" style="min-height: 20px; border: 1px solid green; padding: 10px; margin-top: 30px"></div>
I can not completely understand what you wrote there but as I can see you want to attach from the JSON string and not Node with appendChild.
var div = categoryData[i];
It should be something like this:
store_list.innerHTML += DIV;
I would not even start a while loop with NULL or empty array categoryData. I would outsource this in a function because if I want to call it dynamically again or first see if it's even available. storeCategoryData is an object and not an array ... etc
I think the reason is that one store element can only be appended to only one category element, even it could belong to multiple categories.
========keep history below:====================
The log looks perfect to me. I can't see the problem.
You wrote the statement:
if(storeCategoryData[c].CategoryName==name)
So, some StoreObject are appended; others are not.
I'm writing a program in JS for checking equal angles in GeoGebra.
This is my first JS code, I used c# formerly for game programming.
The code is:
var names = ggbApplet.getAllObjectNames();
var lines = new Set();
var angles = new Set();
var groups = new Set();
for(var i=0; i<names.length; i++)
{
if(getObjectType(names[i].e)==="line")
{
lines.add(names[i]);
}
}
for(var i=0;i<lines.size;i++)
{
for(var j=0;j<i;j++)
{
var angle = new Angle(i,j);
angles.add(angle);
}
}
for(var i=0;i<angles.size;i++)
{
var thisVal = angles.get(i).value;
var placed = false;
for(var j=0;j<groups.size;j++)
{
if(groups.get(j).get(0).value===thisVal)
{
groups.get(j).add(angles.get(i));
placed = true;
}
}
if(!placed)
{
var newGroup = new Set();
newGroup.add(angles.get(i));
groups.add(newGroup);
}
}
for(var i=0;i<groups.size;i++)
{
var list="";
for(var j=0;j<groups.get(i).size;j++)
{
list = list+groups.get(i).get(j).name;
if(j != groups.get(i).size-1)
{
list = list+",";
}
}
var comm1 = "Checkbox[angle_{"+groups.get(i).get(0).value+"},{"+list+"}]";
ggbApplet.evalCommand(comm1);
var comm2 = "SetValue[angle_{"+groups.get(i).get(0).value+"}+,0]";
ggbApplet.evalCommand(comm2);
}
(function Angle (i, j)
{
this.lineA = lines.get(i);
this.lineB = lines.get(j);
this.name = "angleA_"+i+"B_"+j;
var comm3 = "angleA_"+i+"B_"+j+" = Angle["+this.lineA+","+this.lineB+"]";
ggbApplet.evalCommand(comm3);
var val = ggbApplet.getValue(this.name);
if(val>180)
{val = val-180}
this.value = val;
ggbApplet.setVisible(name,false)
});
function Set {
var elm;
this.elements=elm;
this.size=0;
}
Set.prototype.get = new function(index)
{
return this.elements[index];
}
Set.prototype.add = new function(object)
{
this.elements[this.size]=object;
this.size = this.size+1;
}
It turned out that GeoGebra does not recognize Sets so I tried to make a Set function.
Basically it collects all lines into a set, calculates the angles between them, groups them and makes checkboxes to trigger visuals.
the GeoGebra functions can be called via ggbApplet and the original Workspace commands via ggbApplet.evalCommand(String) and the Workspace commands I used are the basic Checkbox, SetValue and Angle commands.
The syntax for GeoGebra commands are:
Checkbox[ <Caption>, <List> ]
SetValue[ <Boolean|Checkbox>, <0|1> ]
Angle[ <Line>, <Line> ]
Thank you for your help!
In short, the syntax error you're running to is because of these lines of code:
function Set {
and after fixing this, new function(index) / new function(object) will also cause problems.
This isn't valid JS, you're likely looking for this:
function Set() {
this.elements = [];
this.size = 0;
}
Set.prototype.get = function(index) {
return this.elements[index];
};
Set.prototype.add = function(object) {
this.elements[this.size] = object;
this.size = this.size + 1;
};
Notice no new before each function as well.
I'm not sure what you're trying to accomplish by creating this Set object though - it looks like a wrapper for holding an array and its size, similar to how something might be implemented in C. In JavaScript, arrays can be mutated freely without worrying about memory.
Here's an untested refactor that removes the use of Set in favour of native JavaScript capabilities (mostly mutable arrays):
var names = ggbApplet.getAllObjectNames();
var lines = [];
var angles = [];
var groups = [];
for (var i = 0; i < names.length; i++) {
if (getObjectType(names[i].e) === "line") {
lines.push(names[i]);
}
}
for (var i = 0; i < lines.length; i++) {
for (var j = 0; j < i; j++) {
angles.push(new Angle(i, j));
}
}
for (var i = 0; i < angles.length; i++) {
var thisVal = angles[i].value;
var placed = false;
for (var j = 0; j < groups.length; j++) {
if (groups[j][0].value === thisVal) {
groups[j].push(angles[i]);
placed = true;
}
}
if (!placed) {
groups.push([angles[i]]);
}
}
for (var i = 0; i < groups.length; i++) {
var list = "";
for (var j = 0; j < groups[i].length; j++) {
list += groups[i][j].name;
if (j != groups[i].length - 1) {
list += ",";
}
}
var comm1 = "Checkbox[angle_{" + groups[i][0].value + "},{" + list + "}]";
ggbApplet.evalCommand(comm1);
var comm2 = "SetValue[angle_{" + groups[i][0].value + "}+,0]";
ggbApplet.evalCommand(comm2);
}
function Angle(i, j) {
this.name = "angleA_" + i + "B_" + j;
var comm3 = "angleA_" + i + "B_" + j + " = Angle[" + lines[i] + "," + lines[j] + "]";
ggbApplet.evalCommand(comm3);
var val = ggbApplet.getValue(this.name);
if (val > 180) {
val -= 180;
}
this.value = val;
ggbApplet.setVisible(name, false);
}
Hopefully this helps!
Your function definition is missing the parameter list after the function name.
Also, you're initializing the elements property to an undefined value. You need to initialize it to an empty array, so that the add method can set elements of it.
function Set() {
this.elements=[];
this.size=0;
}
[EDIT] Full application available at: http://bit.ly/1CGZzym
I'm receiving the error:
Uncaught TypeError: Cannot set property '0' of undefined
with the following code. I believe it is due to my not declaring the child array of the 2D array properly but I am really confused as to where I should be declaring this. Any ideas would be excellent.
// Create an array for the tiles we're about to draw
var tileArray = []
is declared out side of the function.
I assume it is because I am trying to create child elements within each [col] so I guess I need to declare each col number somewhere but nothing I attempt seems to be working.
function drawGrid()
{
// Draw diamond grid
var col = 0;
var row = 0;
topTileX = (viewWidth/2);
topTileY = 0;
var nextX = 0;
var nextY = 0;
var getCols = 0;
while (topTileX > -1)
{
tileArray[col][row] = new DiamondTile(topTileX, topTileY, tileWidth, true, col, row);
tileArray[col][row].draw();
while (tileArray[col][row].xPos + tileArray[col][row].tileWidth < (viewWidth) + tileWidth)
{
col++;
nextX = tileArray[col-1][row].xPos + tileArray[col-1][row].tileWidth / 2;
nextY = tileArray[col-1][row].yPos + tileArray[col-1][row].tileHeight / 2;
tileArray[col][row] = new DiamondTile(nextX, nextY, tileWidth, true, col, row);
tileArray[col][row].draw();
if (col == getCols)
{
break;
}
}
row++;
getCols = col;
col = 0;
topTileX = topTileX - tileWidth/2;
topTileY = topTileY + tileHeight/2;
}
};
For the purpose of demonstration, the DiamondTile function is as follows:
function DiamondTile(xPos,yPos,width,interactive,myCol,myRow)
{
// Set x and y position for this sprite
this.xPos = xPos;
this.yPos = yPos;
this.myRow = myRow;
this.myCol = myCol;
// Used for AI pathfinding
this.isObstacle = false;
this.isStart = false;
this.isEnd = false;
this.gValue = 0;
this.hValue = 0;
this.fCost = 0;
this.tileWidth = width;
this.tileHeight = this.tileWidth/2;
var self = this;
// Create sprite
this.spriteObj = new PIXI.Sprite(grass);
this.spriteObj.interactive = interactive;
this.spriteObj.anchor = new PIXI.Point(0.5,0);
this.spriteObj.hitArea = new PIXI.Polygon([
new PIXI.Point(0,0),
new PIXI.Point(100,50),
new PIXI.Point(0,100),
new PIXI.Point(-100,50)
]);
this.spriteObj.mouseover = function()
{
if (self.spriteObj.tint == 0xFFFFFF)
{
self.spriteObj.tint = 0xA7E846;
}
text2.setText(self.myCol + "," + self.myRow + " Start: " + self.isStart);
}
this.spriteObj.mouseout = function()
{
if (self.spriteObj.tint == 0xA7E846)
{
self.spriteObj.tint = 0xFFFFFF;
}
}
this.spriteObj.click = function()
{
if (startStage === true)
{
startStage = false;
self.isStart = true;
self.spriteObj.tint = 0x1AFF00;
text.setText("Now select an end point");
endStage = true;
return true;
}
if (endStage === true)
{
endStage = false;
self.isEnd = true;
self.spriteObj.tint = 0xFF0000;
text.setText("Now place some obstacles");
obsStage = true;
return true;
}
if (obsStage ===true)
{
self.isObstacle = true;
self.spriteObj.tint = 0x3B3B3B;
text.setText("Press 'C' to calculate path");
return true;
}
}
};
That is a multi-dimensional array and you have not initialized the first dimension array correctly. In the while loop you have to initialize the first dimension to be able to access a second dimension element with an index:
while (topTileX > -1)
{
if (tileArray[col] == null)
tileArray[col] = [];
tileArray[col][row] = new DiamondTile(topTileX, topTileY, tileWidth, true, col, row);
tileArray[col][row].draw();
// omitted other code for brevity
}
Javascript arrays are dynamic and it's enough to initialize the first dimension array elements in this case. You don't have to initialize the individual items in the second dimension.
Update: here is a fiddle with working code http://jsfiddle.net/0qbq0fts/2/
In addition your semantics is wrong. By the book, the first dimension of a 2-dimensional array should be rows, and the second dimension should be columns.
You have to explicit create the elements representing the second dimension, e.g.:
function make2DArray(rows, cols) {
var r = Array(rows);
for (var i = 0; i < rows; ++i) {
r[i] = Array(cols);
}
return r;
}
If you don't know in advance how many columns, just use this:
function make2DArray(rows) {
var r = Array(rows);
for (var i = 0; i < rows; ++i) {
r[i] = [];
}
return r;
}
The individual rows can each have independent lengths, and will grow as you add values to them.
Similarly, if you just need to add a new (empty) row, you can just do:
tileArray.push([]);
This should probably me a comment, but SO has crashed on my side. JavaScript might be throwing an exception on your stated line, but the problem may be with the 'DiamondTile' function.
var select = [];
for (var i = 0; i < nameslots; i += 1) {
select[i] = this.value;
}
This is an extract of my code. I want to generate a list of variables (select1, select2, etc. depending on the length of nameslots in the for.
This doesn't seem to be working. How can I achieve this? If you require the full code I can post it.
EDIT: full code for this specific function.
//name and time slots
function gennametime() {
document.getElementById('slots').innerHTML = '';
var namelist = editnamebox.children, slotnameHtml = '', optionlist;
nameslots = document.getElementById('setpresentslots').value;
for (var f = 0; f < namelist.length; f += 1) {
slotnameHtml += '<option>'
+ namelist[f].children[0].value
+ '</option>';
};
var select = [];
for (var i = 0; i < nameslots; i += 1) {
var slotname = document.createElement('select'),
slottime = document.createElement('select'),
slotlist = document.createElement('li');
slotname.id = 'personname' + i;
slottime.id = 'persontime' + i;
slottime.className = 'persontime';
slotname.innerHTML = slotnameHtml;
slottime.innerHTML = '<optgroup><option value="1">00:01</option><option value="2">00:02</option><option value="3">00:03</option><option value="4">00:04</option><option value="5">00:05</option><option value="6">00:06</option><option value="7">00:07</option><option value="8">00:08</option><option value="9">00:09</option><option value="10">00:10</option><option value="15">00:15</option><option value="20">00:20</option><option value="25">00:25</option><option value="30">00:30</option><option value="35">00:35</option><option value="40">00:40</option><option value="45">00:45</option><option value="50">00:50</option><option value="55">00:55</option><option value="60">1:00</option><option value="75">1:15</option><option value="90">1:30</option><option value="105">1:45</option><option value="120">2:00</option></optgroup>';
slotlist.appendChild(slotname);
slotlist.appendChild(slottime);
document.getElementById('slots').appendChild(slotlist);
(function (slottime) {
slottime.addEventListener("change", function () {
select[i] = this.value;
});
})(slottime);
}
}
You'll have to close in the iterator as well in that IIFE
(function (slottime, j) {
slottime.addEventListener("change", function () {
select[j] = this.value;
});
})(slottime, i);
and it's only updated when the element actually change
The cool thing about JavaScript arrays is that you can add things to them after the fact.
var select = [];
for(var i = 0; i < nameSlots; i++) {
var newValue = this.value;
// Push appends the new value to the end of the array.
select.push(newValue);
}
I have a table where I can add images onclick. The table is created dynamically from a form. I have tried to save the table to local storage, but I am getting a circular reference issue. I have read this Example of a circular reference in Javascript? but I am a complete novice and struggling to understand. Can you point it out to me?
function makeChart() {
var table = document.createElement('table'),
taskName = document.getElementById('taskname').value,
header = document.createElement('th'),
numDays = document.getElementById('days').value, //columns
howOften = document.getElementById('times').value, //rows
row,
r,
col,
c;
var cel = null;
var myImages = new Array();
myImages[0] = "http://www.olsug.org/wiki/images/9/95/Tux-small.png";
myImages[1] = "http://a2.twimg.com/profile_images/1139237954/just-logo_normal.png";
var my_div = document.createElement("div");
my_div.id = "showPics";
document.body.appendChild(my_div);
var newList = document.createElement("ul");
my_div.appendChild(newList);
if (taskName == '' || numDays == '') {
alert('Please enter task name and number of days');
}
if (howOften == '') {
howOften = 1;
}
if (taskName != '' && numDays != '') {
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i];
allImages.onclick = function (e) {
if (sel !== null) {
sel.src = e.target.src;
my_div.style.display = 'none';
sel.onclick = null;
sel = null;
}
};
var li = document.createElement('ul');
li.appendChild(allImages);
newList.appendChild(li);
}
my_div.style.display = 'none';
header.innerHTML = taskName;
table.appendChild(header);
function addImage(col) {
var img = new Image();
img.src = "http://cdn.sstatic.net/stackoverflow/img/tag-adobe.png";
col.appendChild(img);
img.onclick = function () {
my_div.style.display = 'block';
sel = img;
};
}
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
}
}
document.getElementById('holdTable').appendChild(table);
document.getElementById('createChart').onclick = null;
console.log(table);
localStorage.setItem(name, JSON.stringify(table));
console.log( JSON.parse( localStorage.getItem( table ) ) );
}
}
Any DOM element holds a reference to the parentNode and to the document, which you can't stringify. In fact each element holds a link to it parent which holds links to its childs.
You can't apply JSON.stringify to a DOM element.
If you really want to save your table, you could save its HTML using table.innerHTML. We could propose other solutions (there even are specific stringify implementations able to produce JSON from circular elements or DOM nodes). But we'd need to know why you try to save a table in localStorage.