1

At runtime, I have Javascript create html and I want to bind an object on them to pass onto a function for later.

Something like this:

var projects = //(json object)
projects.forEach(function(p) {
   $("#container").append("<div onclick=handleClick(p)></div>");
});

function handleClick(p) {
  //...
}

It seems like doing this makes p become the string [object object] instead of the actual Project object and using JQuery's built in $.click function is the same thing. I know I have to bind these elements to a function at runtime somehow.

What is the proper way to do something like this without excessive searching and DOM access?

2
  • You can use jQuery's .data() method to store the object against the element in question. Then in the click handler use $(this).data() to retrieve it. Read the .data() doco and give it a try; come back if you still have trouble. Commented Mar 28, 2017 at 1:54
  • Handle the click on the parent and decide based on which div was clicked. If you have an id to identify which project was clicked, you can use that as a data attribute so you can identify Commented Mar 28, 2017 at 1:56

1 Answer 1

3

You can create your content and set its click handler with JavaScript instead of inline HTML handlers.

var projects = [{id: 1}, {id:2}, {id:3}];
projects.forEach(function(p) {
   $("#container").append($("<div>Test </div>").click(function(e){
       handleClick(p);
   }));
});

function handleClick(p) {
  console.log('Clicked project', p.id);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
Content here
</div>

Note that a better alternative (because you only need a single handler and you don't have to worry about adding handlers later) would be to set a handler on the parent and you could use a data-pid attribute on each div that will let your handler find the correct project based on which div was clicked.

$(() => {
  var projects = [{id: 1}, {id: 2}, {id: 3}];
  projects.forEach(function(p) {
    $("#container").append("<div class=clicky data-pid=" + p.id + ">Project " + p.id + " </div>");
  });
  $("#container").click('.clicky', (e) => {
    console.log('Clicked paragraph for ' + $(e.target).data('pid'));
  })

})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  Content
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! Just the solution I was looking for
.. though you are right with your 2nd example, since projects will be updated without page refresh, adding more handlers later seems like a bad idea. Will use your 2nd approach
I'm thinking about your second approach, but my objects are much more complex than yours and are nested within multiple json layers & arrays and I have to search the json data file for the object from the id from what it seems like, which is what I want to avoid. Do you have any tips for this, or should I go with the second approach and rebind when new projects are created in the DOM?
My suggestion is use a single handler if possible. It can't be that expensive to search through your structure. If needed, create maps like the answer you linked to

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.