Search code examples
javascriptonclicklistitem

Javascript <li> onclick merged


I am attempting to load Case Studies through a clickable list of dynamically generated items. However my issue is, while it loads them properly, and if you click the elements, it loads a Case Study correctly, but it always loads the LAST case study assigned.

For example, if I have Case Study 1, Case Study 2 and Case Study 3, clicking any of the options takes me to Case Study 3.

function MakeList(array){
//Create List Element
var list = document.createElement("ul");

//For each of the Array Elements
for(var i = 0; i < array.length; i++)
{
    //Create a ListItem Element
    window["listItem" + i] = document.createElement("li");
    eval("listItem" + i).setAttribute("id", ("listItem" + i));

    //And if it exists
    if(array[i] != undefined)
    {
        //Use the array elements title variable for the text node and localize the remaining object variables
        eval("listItem" + i).appendChild(document.createTextNode(array[i].title));
        var title = array[i].title;
        var icon = array[i].icon;
        var imageOne = array[i].imageOne;
        var imageTwo = array[i].imageTwo;
        var challenge = array[i].challenge;
        var solution = array[i].solution;
        var results = array[i].results;

        //Give the ListItem some Styling
        eval("listItem" + i).style.cursor = "pointer";
        eval("listItem" + i).style.color = "blue";
        eval("listItem" + i).style.margin = "0 0 1vh 0";

        //And add the onclick function to Load the selected CaseStudy
        eval("listItem" + i).onclick = function()
        {
            RemoveContent();
            LoadCaseStudy(title, icon, imageOne, imageTwo, challenge, solution, results);
        };

        //Add to the List
        list.appendChild(eval("listItem" + i));
    }
}

//Return the List
return list;}

I have tried giving them dynamically assigned IDs and variable names to seperate the on-click call, but no success. Any advice?


Solution

  • At that point in time when you eval the code in the onclick the FOR loop has already finished it's execution and "I" is at the .length - 1 of your array.

    You should do something like this: 1. First declare your onclick handler outside of the code of the FOR loop

    function handler(title, icon, imageOne, imageTwo, challenge, solution, results)
        {
            RemoveContent();
            LoadCaseStudy(title, icon, imageOne, imageTwo, challenge, solution, results);
        }
    
    1. Attach the handler in a bit different way:

      eval("listItem" + i).onclick = handler.bind(null, title, icon, imageOne, imageTwo, challenge, solution, results);

    Where "null" can be an object representing your desired execution context.

    On another note Avoid using "EVAL" at all cost. If you explain your case a bit better I will help you write the code without it. Give some HTML examples, or explain how the HTML is being built.