1

I've made a constructor in my script that formats <div>s so they can be created and destroyed on the fly.
Here's the function:

function formatDiv(target,divId,divClass,content,onclick)
{
    $("#"+target).append("<div id=\'" + divId + "\' class=\'" + divClass + "\' onclick=\'" + onclick + "\'>" + content +"</div>");

}

What I've been trying to do with this is pass in a function call as a string from an array, like "Main()" for main menu, and assigning it to the <div>'s onclick="" property. This worked fine prior to upgrading my code with jquery, but now when I click on <div>, the console returns: ReferenceError: Main is not defined.
Assuming that this was caused by the inclusion of jquery (as it still works in my old backup), I decided to update the constructor to us jquery's .click event handler,
resulting in this:

function formatDiv(target,divId,divClass,content,onclick)
{
    $("#"+target).append("<div id=\'" + divId + "\' class=\'" + divClass + "\'>" + content +"</div>");
    $("#"+divId).click(function(){$(onclick)});
}

, and I changed the formatting of the functions to be called in the array piping info to the onclick parameter from "Main()" to Main.
Now when clicking on a <div>, nothing happens at all, no errors or anything.

What is the best way to add an onclick handler to my <div>s? Am I using .click incorrectly? Jquery is still new to me (despite w3schools lessons and the tutorials on jquery's site), so I'm forced to guess that I'm using it incorrectly. Any help would be appreciated.

Here's the whole script:

$(document).ready(function () {


    $(Main);

    //main menu
    function Main()
    {
        var mainList = [">New List",">Show Lists",">Delete Lists"];
        var onClick = [NewList,Main,Main];
        var mainMenu = new Menu("Main Menu","menuMain",mainList,onClick);
        mainMenu.contentMenu();
    }

    //new list menu
    function NewList()
    {
        var mainList = ["> Create a New List"];
        var onClick = [Main];
        var newListMenu = new Menu("New List","menuMain",mainList,onClick);
        newListMenu.contentMenu();
    }

    //menu class
    function Menu(name,divClass,content,onclick)
    {
        $("#interface").html(null);

        //title
        formatDiv("interface",name,divClass,name,null);

        //return
        if(name != "Main Menu")
        {
            formatDiv(name,null,"return","^ Main Menu","Main()");
        }


        //display options
        this.contentMenu = function()
        {
            for(i=0; i<content.length; i++)
            {
                formatDiv("interface",content+i,"menuContent",content[i],onclick[i]);
            }
        }
    }


    //format divs
    function formatDiv(target,divId,divClass,content,onclick)
    {
        $("#"+target).append("<div id=\'" + divId + "\' class=\'" + divClass + "\'>" + content +"</div>");
        $("#"+divId).click(function(){$(onclick)});
    }


});
  • What's this supposed to be doing `$(onclick)`?? – elclanrs Jul 23 '12 at 03:35
  • Although you already selected an Answer and are using `.append();` method, here is your Questions markup working in [**jsFiddle**](http://jsfiddle.net/X4gSs/). Note since the ID is cloned, re-run the jsFiddle after the first click instance. – arttronics Jul 23 '12 at 04:55
  • Thanks, jFiddle looks very cool – user1542645 Jul 23 '12 at 05:09
  • Your welcome. It's ***more efficient*** than your revised `.append();` method since that is using other queries `.attr();` `.html();` and `.click();`. – arttronics Jul 23 '12 at 05:16
  • heh, if you look at the top of my question (second code block) it's almost identical to what I was using initially - it wasn't working in the form I had it in the question – user1542645 Jul 23 '12 at 05:45
  • Edited in the example you posted in that fiddle and it works fine - I was having some kind of syntax issue for sure – user1542645 Jul 23 '12 at 05:48

4 Answers4

0

If you want to call a function just use functionName() instead of $(functionName) so change your code like this

$(document).ready(function () {
    Main();
    ....
            //display options
            this.contentMenu = function () {
                for (i = 0; i < content.length; i++) {
                    formatDiv("interface", "content" + i, "menuContent", content[i], onclick[i]);
                }
            }
    ....
    //format divs
    function formatDiv(target, divId, divClass, content, onclick) {
        $("#" + target).append("<div id=\'" + divId + "\' class=\'" + divClass + "\'>" + content + "</div>");
        $("#" + divId).click(onclick);
    }
Charlie
  • 1,292
  • 8
  • 7
0

Since your divs are created dynamically, you can't use .click() to bind as that only binds to elements that already exit when the script runs. You can however use .on() and bind to an existing element on the page. A worst case would be something like the body element but you can probably find an element closer to where the divs reside than that.

For example:

$("#"+target).append("<div id=\'" + divId + "\' class=\'" + divClass + "\'>" + content +"</div>");
$('body').on('click', "#"+divId, function(){$(onclick)});

From the .on() documentation:

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.

j08691
  • 204,283
  • 31
  • 260
  • 272
  • the div does exists when he binds the click handler, he created it the line before – hackattack Jul 23 '12 at 03:44
  • 1
    @hackattack - you may want to read up on how to bind to elements. – j08691 Jul 23 '12 at 03:47
  • no. He adds the div to the DOM and then puts an event handler on it. The problem is that he is calling the function wrong. If he did the binding before he created the div then you would be right. – hackattack Jul 23 '12 at 03:53
  • I edited my script (targeting the `
    ` with the id `"#interface"` in my html, and the used .on with the parameters you suggested. Still does nothing, still returns no errors in console
    – user1542645 Jul 23 '12 at 04:10
  • formatting it like this: `$("#interface").on("click", "#"+divId, onclick);` returns this error in the console: `TypeError: ((f.event.special[s.origType] || {}).handle || s.handler).apply is not a function` – user1542645 Jul 23 '12 at 04:15
  • is my parameter piping correct? It seems to be, but I'm not sure at this point – user1542645 Jul 23 '12 at 04:19
  • @user1542645, the argument to `"click"` should be a complete function (whereas you have an extra comma in there.) See reply in my answer for updated jsFiddle. – arttronics Jul 23 '12 at 04:49
  • Oops, not my Answer but Kaizen's answer. – arttronics Jul 23 '12 at 05:00
0

It sounds like you are looking for live() type functionality. You don't actually want to use .live() though. Here is a good answer to why you want to actually use .on().

Community
  • 1
  • 1
RBZ
  • 2,034
  • 17
  • 34
  • @hackattack, the answer states `live();` type ***functionality*** via using the `.on()` method. – arttronics Jul 23 '12 at 03:52
  • it doesnt matter what he uses to bind an event to the div, if he calls the function like $(onclick) then its not going to do anything, thats the real issue – hackattack Jul 23 '12 at 03:57
  • Ah, I think I see your confusion. `onclick` in this context is the argument from the `formatDiv();` function and it's a ***variable*** name only. – arttronics Jul 23 '12 at 03:59
  • I'm not confused, like i said to @j08691 take a look here http://jsfiddle.net/jQ2TM/ – hackattack Jul 23 '12 at 04:06
  • Based on your example: [**jsFiddle**](http://jsfiddle.net/X4gSs/). Note since the ID is cloned, re-run the jsFiddle after the first click instance. – arttronics Jul 23 '12 at 04:47
-1

lets start by how you are making a div with jquery. The way you are making a div is correct but not the most efficent. You can make any html element with jQuery with the following syntax

$('<NODE_NAME>')

so for a div it will be

$('<div>')

Now that we have a jquery object we need to add attributes to it, we do that with the attr method. we pass it an object of attribute name/value pairs.

$('<div>').attr({
    className: divClass ,
    id: divId 
});

Now, to add the content in the div we use the .html method

$('<div>')
.attr({
    className: divClass ,
    id: divId 
})
.html(
    content
);

and finally we add the onclick handler

$('<div>')
.attr({
    className: divClass ,
    id: divId 
})
.html(
    content
)
.click(
    onclick
);

What you are doing wrong with the onclick handler is wrapping it in $(). This does not make sense, you want to call the main function, not pass it as a value to the jquery function.

hackattack
  • 1,087
  • 6
  • 9
  • I added your suggestion into the .append, and it's working, partially! It's displaying the `
    `s and their content, it's just not dressing them with css. This is the closest to a solution I've come so for: `$("#"+target).append($('
    ').attr({className: divClass, id: divId}).html(content).click(onclick));`, thanks. I'm just trying to address the loss of css, let me know if you have any thoughts. So far this looks like the solution (not ready to check it yet as it's not fully resolved), but I'm upvoting this cause I don't think it deserved to be downvoted.
    – user1542645 Jul 23 '12 at 04:28
  • F'n solved mate! here's what worked: `$("#"+target).append($('
    ').attr({"class": divClass, "id": divId}).html(content).click(onclick));` hackattack thank you very much, perfect explanations throughout your comments, you managed to make sense of this to me, and I'm getting a better handle on DOM as well! The user who downvoted your answer should redact that, because you seem to have known best what's up
    – user1542645 Jul 23 '12 at 04:35