1

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 ) ) );
    }
}
Community
  • 1
  • 1
Inkers
  • 219
  • 7
  • 27
  • All DOM elements contain circular references (for example via `parentNode.childNodes…`. Serialize them to HTML, instead of trying JSON stringification. – Bergi Jan 19 '13 at 16:24

1 Answers1

3

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.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • OK, so if I am understanding correctly it is trying to stringify the whole way back up the DOM so I should target the table like so localStorage.setItem(name, JSON.stringify(table.innerHTML)); ? And I just noticed I should have name as key instead of table in last log. – Inkers Jan 19 '13 at 16:26
  • You **could** do that, but why ? Serializing a part of the page isn't standard practice. – Denys Séguret Jan 19 '13 at 16:28
  • That works. The table is unique to different users so I want the user to see their particular table when the enter the page. I'm not sure that I understand what you are getting at. I should save the whole page? – Inkers Jan 19 '13 at 16:50
  • No, you shouldn't save any HTML. Can't your table be built from a small piece of data that you could save ? – Denys Séguret Jan 19 '13 at 16:52
  • Are you talking about a cookie or something? – Inkers Jan 19 '13 at 16:55
  • No, I mean you could simply save an ID of your user in localStorage instead of saving a table. But it entirely depends on your application logic. – Denys Séguret Jan 19 '13 at 16:57