Search code examples
javascripthtmlhtml-tableotree

Connect single image to single cell in a table with Javascript


I'm quite new both to programming and to this community, I'll try to be as clear as possible. I need to create an HTML table 16x16 with a button in every cell that displays a different image - a smiley - per cell, without ever showing the same smiley for different cells. I'm a bit stuck and I would also appreciate a hint, just to try and move on on my own. Thanks! Here is my code that creates the table and displays the image:

function displayImage(){
    var num = Math.floor(Math.random() * 256);
    document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
    document.getElementById("YourImage").style.visibility = "visible";
}
for(var r = 0; r < rows;r++)
{
    table += '<tr>';
    for(var c= 0; c< cols;c++)
    {
        table += '<td style="width:50px" id="(i++)">' + '<button type="button" onclick="displayImage()">' +
        "show me" + '</button>' + '</td>';
     }
     table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');

(ImagesArray is not shown for readability but it simply collects all 256 binary combinations). The problem with this is that each time I click on a button it displays a random image and if I click again on the same button it shows another one, while I'd like it to show me always the same image for the same button. NOTE: I cannot delete the button afterwards or similar tricks, as the player (it's an oTree experiment) needs to be able to go back to a smiley he saw any time. Thanks a lot for your help!


Solution

  • I would change the point where the random number is generated and advance it from the display function to the initialization of the table.

    Create an array with the numbers from 0 to 255. While looping through rows and columns to create the table, pick one random number from that array and assign it to the button's id attribute. Be sure to remove this number from the array, so it can't be used again for the following buttons. This way every of the 256 numbers will be used, but in random order. When a user clicks a button, with displayImage(this.id) the button's id is used as a parameter to call displayImage(). Thus always the same number of the button will be used the fetch the according image.

    The code:

    // call displayImage() with parameter
    function displayImage(num){
        document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
        document.getElementById("YourImage").style.visibility = "visible";
    }
    
    // create array 'nums' with numbers from 0 to 255 (= rows * cols)
    var nums = [];
    for (var i = 0; i < (rows * cols); i++) {
        nums.push(i);
    };
    
    for(var r = 0; r < rows; r++)
    {
        table += '<tr>';
        for(var c = 0; c < cols; c++)
        {
            // get random index in array 'nums'
            var random = Math.floor(Math.random() * nums.length);
            // assign an id to the button with a random number from 'nums' and use this id in displayImage()
            table += '<td style="width:50px" id="(i++)">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' +
            "show me" + '</button>' + '</td>';
            // remove the already used random number from 'nums'
            nums.splice(random, 1);
         }
         table += '</tr>';
    }
    document.write('<table id="grid" border="1">' + table + '</table>');
    

    This way you will have the same image connected to every button. It's randomized while creating the table, so the order is different every time you load the page.

    I assume you are using HTML5 because only then it is permitted that id attributes consists only of digits.

    Note: I don't know what exactly you want to achieve with id="(i++)" when creating the <td> element. The way you do it just names every id with the string (i++) which contradicts the idea that ids should be unique. If you want to name the ids ascending from for example td-0 to td-255 you should change the line to:

    table += '<td style="width:50px" id="td-' + (r * rows + c) + '">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' + "show me" + '</button>' + '</td>';
    

    You can't just use the numbers without adding something like td-, because the buttons already have pure numbers as id.