6

I reffered Creating a div element in jQuery and creatd a div element using javascript. However when I added a button element dynamically, click is not working. What change do we need to do to make the button click working?

Note: We cannot move the function outside of document.ready due to kendo control requirements mentioned in Binding to multiple view models nested in the Dom

Updated References

  1. Wiring up click event using jQuery on() doesn't fire on injected HTML via Ajax call
  2. how to attach jquery event handlers for newly injected html?
  3. After injecting html by jquery, the event handlers doesn't work with/without delegate

CODE

<head>

    <title>Test</title>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://cdn.kendostatic.com/2013.2.716/js/kendo.all.min.js"></script>



<script type="text/javascript">

    //lijo
    $(document).ready(function () 
    {

    $(".statiscDIV").append('<div>FIRST</div>');
      $(".statiscDIV").append('<div>hello <button class="MakeHoldDetailLinkButton" onclick = "showMakeAndHold();">View</button>  </div>');


    //lijo
    function showMakeAndHold() 
    {

        alert("HIIIIIII");

    }


    });

 </script>

</head>

<body>

 <div class="statiscDIV">

A

 </div>

</body>
Community
  • 1
  • 1
LCJ
  • 22,196
  • 67
  • 260
  • 418

4 Answers4

16

When you inject code into the DOM, the jQuery event handlers are not attached/bound to the new elements. (jQuery already did the bindings to DOM elements before the new code was injected). Therefore, when you click a button, no jQuery click event is trapped.

To attach event handlers (and thereby grab events from) injected elements, you must use jQuery .on(), as follows:

jsFiddle Demo

$(".statiscDIV").append('<div>FIRST</div>');
$(".statiscDIV").append('<div>hello <button class="MakeHoldDetailLinkButton">View</button>  </div>');

$(document).on('click','.MakeHoldDetailLinkButton',function(){
    showMakeAndHold();    
});

function showMakeAndHold() {

    alert("HIIIIIII");

}

The .on() method was added in jQuery 1.7 to replace bind(), .delegate(), and .live() -- it does the same thing as all of these. (To unbind event handlers from ANY DOM elements, use .off())

Source: http://api.jquery.com/on/

cssyphus
  • 37,875
  • 18
  • 96
  • 111
  • 1
    Note this approach has worse performance, because it detects the click events of the whole document. Instead of `document`, use the smallest wrapper possible, or add the event handler only to the target elements (after creating them). – Oriol Jun 09 '14 at 15:05
  • 1
    @Oriol speaks true -- you should bind the event handler to the lowest element (usually the one into which the injected code is injected: `$(".statiscDIV").on(...)` ), but in most situations (at least the modest sites on which *I* have worked) the performance hit of using `$(document).on(...` is not significant. Further, document.on will *always* work, whereas finding the *BEST* element to use could require experimentation. That said, however, **Oriol is correct**. Whether it's a big deal or not depends on your site. – cssyphus Jun 09 '14 at 17:11
  • @lijo - Unless I am missing something, your use of quotes in the original question was/is correct. It **rarely** matters whether you use single quotes or double quotes (JSON Is one of the exceptions - you must always use double quotes for strings in JSON, and there may be one or two other instances)... But *usually* it does not matter -- so long as (1) you start/end a string using the same type of quotes, and (2) use the other type of quotes (or escape the quotes) if you require additional quotes inside a quoted string. But it is a good habit to be consistent (so any errors leap out at you). – cssyphus Jun 09 '14 at 18:18
3

You must escape your quotes with \, or mix single and double quotes:

"<div>hello <button class=\"MakeHoldDetailLinkButton\" onclick=\"showMakeAndHold();\">View</button>  </div>"
'<div>hello <button class=\'MakeHoldDetailLinkButton\' onclick=\'showMakeAndHold();\'>View</button>  </div>'
'<div>hello <button class="MakeHoldDetailLinkButton" onclick="showMakeAndHold();">View</button>  </div>'
"<div>hello <button class='MakeHoldDetailLinkButton' onclick='showMakeAndHold();'>View</button>  </div>"

The other problem is that you use inline event listeners. Those run in global context, so can't run functions declared inside a closure.

Either make showMakeAndHold a global function, or better add the event listeners in a better way:

$(".statiscDIV")
    .append('<div>FIRST</div>')
    .append('<div>hello <button class="MakeHoldDetailLinkButton">View</button></div>')
    .find('button').on('click', showMakeAndHold);

Demo

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    Or use single quotes. – martin.code Jun 07 '14 at 17:43
  • What you say is true, but am I missing something here? Were quotes not used correctly in the OP? – cssyphus Jun 09 '14 at 18:21
  • Oriol again speaks true about inline event listeners (e.g. ``) - don't use them. Always break out your js/jQuery into `` tags or, better yet, into a separate `my_page_name.js` document. +1 Mr. O. – cssyphus Jun 09 '14 at 18:24
  • @gibberish OP was edited, fixing the quotes. Now I don't know if it was a typo when asking the question and I should remove that part of my answer. – Oriol Jun 09 '14 at 18:47
  • @Oriol Perhaps yes, since even reviewing the OP revision history has the quotes correct. OP must have fixed it right away. :) – cssyphus Jun 09 '14 at 18:53
0
 $(document).ready(function (){
    $(".statiscDIV").append('<div>FIRST</div>');
      $(".statiscDIV").append('<div>hello <button class="MakeHoldDetailLinkButton" onclick = "showMakeAndHold();">View</button>  </div>');

});
//lijo
function showMakeAndHold(){
    alert("HIIIIIII");

}
colinyyj
  • 11
  • 2
0

Though its late, it may help someone in future.

When an element/ class/ Id is dynamically added, you need to add the event listeners too. Similarly if it is removed, then the event listeners attached to it are also removed.

So either add event listeners also when adding a new element (which will not be a good approach), or use jQuery's on method like so:

$(document).on('click','class or id', function);
artenson.art98
  • 1,543
  • 15
  • 15