简体   繁体   中英

How to pass an javascript object to a javascript function specified using, for example, onclick

I was looking for some time for a solution to the following problem: I have an object in a javascript function that defines a table of data. I want to pass a row of this table to a function defined using the onclick handler of a table cell (a td element) so that it can open a popup with extra information for that element.

I found quite a few solutions to this, but mostly involving strings prepared from php and then passed to javascript. My case involves no php at the level where the above functionality is required.

After some experimentation I came up with the following.

Passing an object to an inline HTML function requires 2x stringify. The first will create the json string, and the second will escape all double quotes and also add double quotes at the beginning and end. The receiving function then only needs to JSON.parse() the json string passed this way.

// JSON format for json_txt is:
//  { "column 1" : ["c1 data 1", "c1 data 2", ...],
//    "column 2" : ["c2 data 1", "c2 data 2", ...],
//    ...
//  }

function createTable(json_txt, el_id)
{
    var el = document.getElementById(el_id);
    var o = JSON.parse(json_txt);
    var s = '<table>';
    var num = numTableRows(o);  // just returns number of rows
    for (var r=0; r<num; r++)
    {
        s += '<tr class="tbl_data">';
        for (var col in o)
        {
            if (col === 'a special column name here')
            {
                var js = {};
                for (var c in o) js[c] = o[c][r];
                s += "<td onclick='onTrackShowInfo(this," + JSON.stringify(JSON.stringify(js))+" )'>";
            }
            else
                s += '<td>';

            s += o[col][r];
            s += '</td>';
        }
        s += '</tr>';
    }
    s += '</table>';
    el.innerHTML = s; 
}

....

function onTrackShowInfo(el, json_row)
{
    var o = JSON.parse(json_row);
    // ok, we have the row from element 'el' at this point
}

One reason I am posting it here, is to help others who may also be looking for something similar, and also to ask if anyone sees any issues with this, or has come up with a better solution to this specific problem.

EDIT: Added a very simplified version of the createTable() function to show a bit more of the context where this code runs.

As @charlietfl suggests, you should get out of the habit of using JavaScript in your attributes, and use event delegation for this problem:

function createTable(json_txt, el_id) {
    var el = document.getElementById(el_id);
    var o = JSON.parse(json_txt);
    var s = '<table>';
    var num = numTableRows(o);  // just returns number of rows
    var tableData = [];

    for (var r=0; r < num; r++) {
        var rowData = {};

        s += '<tr class="tbl_data">';
        for (var col in o) {
            var curVal = o[col][r];
            rowData[col] = curVal;

            s += "<td data-row='" + r + "'>" + curVal + "</td>";
        }
        s += '</tr>';

        tableData.push(rowData);
    }
    s += '</table>';
    el.innerHTML = s; 

    el.addEventListener("click", function(e) {
        var targ = e.target,
            rowNum,
            data;

        if(targ && targ.nodeName == "TD") {
            rowNum = targ.getAttribute("data-row");
            data = tableData[rowNum];
            if (data) {
                onTrackShowVal(this, data);
            }
        }
    });
}

(Just as a side not, if you are using jQuery, that last part could be done like this, and the "td" string could be altered to give a more specific selector if needed):

$(el).on("click", "td", function () {
    var rowNum = $(this).data("row"),
        data = tableData[rowNum];

    if (data) {
        onTrackShowInfo(this, data);
    }
});

Look at this edit:

var js = {};
for (var c in o) js[c] = o[c][r];
s += "<td onclick='onTrackShowInfo(this, "+c+" )'>"; 

...

function onTrackShowInfo(el, json_row_index)
{
    var o = js[json_row_index];
    // ok, we have the row from element 'el' at this point
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM