0

I am creating a table dynamically, using the following code. The table is created as desired (the code works). The cells are eventually populated via Javascript innerHTML. I need to add two capabilities, and I am asking for suggestions on how to do this:

(1) The font in cells c2 and c3 should be different from the default font used by the browser. For c3, I attempted to do this with c3.style.font = "Sans-serif";, but this has no effect on the font.

(2) When user clicks on a cell, I want Javascript to be called with the (row, column) of the cell that was clicked, preferably without having to add an 'onClick' to every cell.

HTML: <table id="St" cellpadding=5 cellspacing=0></table>

Javascript:

    function MakeTable(nCols, nRows)
    {
    var table = document.getElementById("St");
    for (iRow = 0; iRow < nRows; iRow++) {
        var row = table.insertRow(-1); // add a row at the end
        // Row will have 3 x nCols cells
        for (iCol = 0; iCol < nCols; iCol++) {

            var c1 = row.insertCell(-1);
            c1.style.width = 16; c1.style.borderStyle = "solid";
            c1.style.borderColor = "black";
            c1.style.borderWidth = "thin";

            var c2= row.insertCell(-1);
            c2.style.width = 70; c2.style.borderStyle = "solid";
            c2.style.borderColor = "black";
            c2.style.borderWidth = "thin";

            var c3= row.insertCell(-1);
            c3.style.width = 70; c3.style.font = "Sans-serif";
            c3.style.borderStyle = "solid";
            if (iCol + 1 < nCols) // only separators between columns are thick
                c3.style.borderWidth = "thin 3px thin thin";
            else
                c3.style.borderWidth = "thin";

            c3.style.borderColor = "black";
        }
    }
}
`
Woody20
  • 791
  • 11
  • 30
  • If your browser's default font is a sans-serif font, then changing the font-family to sans-serif would have no affect. If your browser's default font is serif (or dingbats), it would have an affect. For the clicking, look at https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Heretic Monkey Mar 22 '18 at 21:26
  • 1
    Much better to use a class or selector rather than setting style values individually as element style properties. – RobG Mar 22 '18 at 22:20
  • Browser's default is Times New Roman, not a sans-serif font. But still, there is no effect. – Woody20 Mar 22 '18 at 23:12
  • @MikeMcCaughan: I did not see a way to deal with the clicking in Javascript (not jQuery), other than having every cell have its own 'onClick'. – Woody20 Mar 22 '18 at 23:20
  • @RobG: How do you use a class/selector for dynamically-created elements? Or were you just referring to the table cell attributes my existing code sets? – Woody20 Mar 22 '18 at 23:22
  • @Woody20—CSS uses a selector followed by a declaration block. Selectors work on dynamically created elements as soon as they're added to the DOM, so set the style generally than apply something different to the 3rd cell using say `td:nth-child(3) {border-width: thin 3px thin thin;}`. You can write rules dynamically too, but a class would be simpler (e.g. add a class of "lastColumn" or similar). – RobG Mar 23 '18 at 04:42
  • Didn't get past the first answer, huh? https://stackoverflow.com/a/27373951/215552; otherwise there's https://stackoverflow.com/q/34032123/215552 – Heretic Monkey Mar 23 '18 at 12:40
  • @MikeMcCaughan: I was hoping for a solution that would sense a click anywhere in the table, and report the coordinates relative to the table top left point to the handler. The handler would then compute the cell coordinates using the fixed width and height of the cells. This method would avoid having to add an event watcher separately to every of the ~500 cells. – Woody20 Mar 23 '18 at 22:49
  • So, your question only says that you want the row and column index. That's solved in the answers to [Find row and column of clicked table cell in JavaScript without jQuery](//stackoverflow.com/q/28357314) or [Finding the location of a TD in a table](//stackoverflow.com/q/16130062). Technically, the answers there do add a click event to every cell, but you could get the same properties from `e.target` using the delegation method. – Heretic Monkey Mar 24 '18 at 02:45

1 Answers1

0

Incorporating the suggestions from the commenters (tnx, guys), I've got everything working with the following. Some of the cell attributes set in MakeTable can be incorporated into the CSS, which I will do later.

CSS:

td {color: blue; font-family:sans-serif}
td:nth-child(1) {color: black; font-weight:bold; font-family:serif}
td:nth-child(4) {color: black; font-weight:bold; font-family:serif}
td:nth-child(7) {color: black; font-weight:bold; font-family:serif}

This CSS only works for nCols<=3, which is something else that should be fixed.

HTML: <table id="St" cellpadding=5 cellspacing=0 onclick="StClicked(event);"></table> Javascript:

function MakeTable(nCols, nRows)
{
    var table = document.getElementById("St");
    for (iRow = 0; iRow < nRows; iRow++) {
        var row = table.insertRow(-1); // add a row at the end
        // Row will have 3 x nCols cells
        for (iCol = 0; iCol < nCols; iCol++) {
            var c1= row.insertCell(-1);
            c1.style.width = 34; c1.style.borderStyle = "solid";
            c1.style.borderColor = "black";
            c1.style.borderWidth = "thin";

            var c2= row.insertCell(-1);
            c2.style.width = 70; c2.style.borderStyle = "solid";
            c2.style.borderColor = "black";
            c2.style.borderWidth = "thin";

            var c3= row.insertCell(-1);
            c3.style.width = 70; c3.style.borderStyle = "solid";
            c3.style.borderColor = "black";
            if (iCol + 1 < nCols) // only separators between columns are thick
                c3.style.borderWidth = "thin 3px thin thin";
            else
                c3.style.borderWidth = "thin";
        }
    }
}

function StClicked(event)
{
   var table1 = event.target;
   alert("clicked cell at: " + table1.cellIndex + ", " + table1.parentNode.rowIndex);
}
Woody20
  • 791
  • 11
  • 30