39

How can I create a dynamic button with a click event with JavaScript?

I tried this, but when I click the add button, an alert message show up! It's not what I want - I want to be able to click the button which is dynamically created.

<script language="javascript">
    function add(type) {
        //Create an input type dynamically.   
        var element = document.createElement("input");
        //Assign different attributes to the element. 
        element.setAttribute("type", type);
        element.setAttribute("value", type);
        element.setAttribute("name", type);
        element.setAttribute("onclick", alert("blabla"));

        var foo = document.getElementById("fooBar");
        //Append the element in page (in span).  
        foo.appendChild(element);

    }
</script>
Mustafa Ekici
  • 7,263
  • 9
  • 55
  • 75

4 Answers4

67

Wow you're close. Edits in comments:

function add(type) {
  //Create an input type dynamically.   
  var element = document.createElement("input");
  //Assign different attributes to the element. 
  element.type = type;
  element.value = type; // Really? You want the default value to be the type string?
  element.name = type; // And the name too?
  element.onclick = function() { // Note this is a function
    alert("blabla");
  };

  var foo = document.getElementById("fooBar");
  //Append the element in page (in span).  
  foo.appendChild(element);
}
document.getElementById("btnAdd").onclick = function() {
  add("text");
};
<input type="button" id="btnAdd" value="Add Text Field">
<p id="fooBar">Fields:</p>

Now, instead of setting the onclick property of the element, which is called "DOM0 event handling," you might consider using addEventListener (on most browsers) or attachEvent (on all but very recent Microsoft browsers) — you'll have to detect and handle both cases — as that form, called "DOM2 event handling," has more flexibility. But if you don't need multiple handlers and such, the old DOM0 way works fine.


Separately from the above: You might consider using a good JavaScript library like jQuery, Prototype, YUI, Closure, or any of several others. They smooth over browsers differences like the addEventListener / attachEvent thing, provide useful utility features, and various other things. Obviously there's nothing a library can do that you can't do without one, as the libraries are just JavaScript code. But when you use a good library with a broad user base, you get the benefit of a huge amount of work already done by other people dealing with those browsers differences, etc.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
6
<!DOCTYPE html>
<html>
<body>

<p>Click the button to make a BUTTON element with text.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    var btn = document.createElement("BUTTON");
    var t = document.createTextNode("CLICK ME");

    btn.setAttribute("style","color:red;font-size:23px");

    btn.appendChild(t);
    document.body.appendChild(btn);

    btn.setAttribute("onclick", alert("clicked"));

}
</script>

</body>
</html>
shashidhar
  • 61
  • 1
  • 2
  • Please add an explaination to your code. Code only answers are not welcome on StackOverflow. – L. Guthardt Jul 17 '18 at 08:10
  • @L.Guthardt I am not agree with you. If the code does its job, absence of explanation is not a big deal. – yılmaz Dec 18 '19 at 08:21
  • @yılmaz *Code can only tell you the how, it doesn't tell you the why. That's what you need comments for. [...] While a code-only answer get the person who asked the question past whatever hurdle they might be facing, it doesn't do them or future visitors much good in the long run.* Please have a look at [this meta discussion](https://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code-only-ques/148274) – L. Guthardt Dec 19 '19 at 08:32
  • @L.Guthardt "it doesn't tell you the why" > "sometimes" is missing. – yılmaz Dec 24 '19 at 09:26
  • @yılmaz No it does not. Code can only explain **how** itself works, but not **why** this code works here and why you should choose this code instead of something else. – L. Guthardt Jan 10 '20 at 14:58
  • 1
    @L.Guthardt "sometimes" part is valid for those who can read code. – yılmaz Jan 14 '20 at 10:56
  • @yılmaz I agree. When I am in trouble, all I need is a tiny code snippet that has been tested by a pioneer who had it working right. One look at it, and I know where my own code went wrong. I don't read lengthy explanations, any way. – Raja Feb 28 '21 at 17:37
6

this:

element.setAttribute("onclick", alert("blabla"));

should be:

element.onclick = function () {
  alert("blabla");
}

Because you call alert instead push alert as string in attribute

neworld
  • 7,757
  • 3
  • 39
  • 61
  • 4
    No no *no*. It should be `el.onclick=function(){}`. – Jared Farrish Oct 09 '11 at 22:48
  • 1
    element.setAttribute("onclick", 'alert("blabla")'); – Mustafa Ekici Oct 09 '11 at 23:07
  • 2
    @mekici - When you use the form in that comment, you're using `eval()` to evaluate the `alert()`. This is generally considered a Bad Idea (both in performance and security). Using an anonymous function set to the handler (as neworld has and T.J. Crowder have) is the accepted best practice. – Jared Farrish Oct 09 '11 at 23:13
  • Yes your solution works too! thanks for that! i didnt check element.setAttribute("onclick", 'alert("blabla")'); on chrome but it works on ie9 and mozilla. @T.J. Crowder's solution doesnt work ie9, mozilla chrome.. – Mustafa Ekici Oct 09 '11 at 23:17
  • 3
    @mekici - That doesn't make any sense. *What part didn't work*? – Jared Farrish Oct 09 '11 at 23:24
0

Firstly, you need to change this line:

element.setAttribute("onclick", alert("blabla"));

To something like this:

element.setAttribute("onclick", function() { alert("blabla"); });

Secondly, you may have browser compatibility issues when attaching events that way. You might need to use .attachEvent / .addEvent, depending on which browser. I haven't tried manually setting event handlers for a while, but I remember firefox and IE treating them differently.

Sam Dufel
  • 17,560
  • 3
  • 48
  • 51