3

This seems like a really trivial question, but I cannot for the life of me find a satisfying answer.

How do I add a button with a bound function WITHOUT hardcoding it into the page or string-ifying the "onclick" attribute?

i.e.

some_div_selection.append("button").text("+").on("click", console.log("You clicked me"));

instead the only way I've seen people do this is

some_div_selection.append("button").attr("onclick", "foobar()").text("+")

Which seems very clunky and brittle. Do I need to give the button some kind of data or what?

2 Answers 2

3

I'm a D3 programmer and I must say that in all those years I never saw a single D3 code using the approach you claim is the only one you have seen, which is setting the onclick attribute:

selection.attr("onclick", "foo()")

It does work, but that's not idiomatic D3. In D3, we use the on method. However, the problem with your first snippet is that it's calling the function immediately:

d3.select("body")
  .append("button")
  .html("Click me")
  .on("click", console.log("you clicked me"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

You can see that the console displays "you clicked me" without any click. So, for that to work, we should not call the function. Funnily enough, console.log accepts 3 arguments, have a look at what happens if we don't call console.log:

d3.select("body")
  .append("button")
  .html("Click me")
  .on("click", console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Now console.log works when you click the button, because you passed it as the function reference. However, the first value is undefined because you didn't pass any string to console.log.

That being said, what you want is:

d3.select("body")
  .append("button")
  .html("Click me")
  .on("click", () => {
    console.log("you clicked me")
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Now you're passing a proper function to the click event, which will be called when you click.

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

1 Comment

That makes a lot of sense now. I'm not particularly experienced with web development and couldn't figure out why the function was being immediately executed, this clicked the gears into place.
0

What happens when you:

some_div_selection.append("button").text("+").on("click", function(){console.log("You clicked me")});

Comments

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.