1

In my HTML I have a div, in which I dynamically insert a collapsible with an extra button.

Here is the original HTML:

<div data-role="main" class="ui-content">
    <a id="btnSearch" data-role="button" data-icon="search" data-inline="true" data-iconpos="notext"></a>
    <div id='resultList'></div>
</div>

And here is the injected HTML:

<div class='resultItem' data-role='collapsible' data-id='3537' data-content-theme='c'>
    <h5>Biatorbagy(65 - 312)<div><a data-role='button' class='resultZoomButton ui-btn ui-btn-icon-notext ui-icon-search ui-mini ui-corner-all ui-btn-right'></a></div ></h5>
    <p class='attribution'>Year</p>
    <p class='value' style='white-space:pre-wrap'>1997</p>
    <p class='attribution'>Path</p>
</div>

For the extra button I would like to bind an event handler, and as there will be multple collapsible inserted, I decided to attach a delegated event handler (based on JQuery help). I added this in $(document).ready(function()) as below with JQuery's on method:

$(document).ready(function () {    
    $('#resultList').on('click','a.resultZoomButton',function(e){
        alert(e.type + 'event fired!')
    });
});

But the event handler is not called. Why?

I would think that if the div with resultList id already exists when the event handler is defined, then in the bubbling phase of the event it should filter for a elements with resultZoomButton class. (I also tried e.preventDefault() with no success.)

jsfiddle attached: http://jsfiddle.net/bsimo/5LwLmu2s/4/

JQuery: 1.9.1. JQM: 1.4.0

Benedek Simo
  • 504
  • 5
  • 15
  • Might be an issue with single instead of double quotes on your attribute values – Johan Sep 19 '14 at 12:00
  • I don't yet what your real problem is, but it has to do something with `enhanceWithin`. When I change this to `append` the event will fire. ps. I've also changed the selector to 'document'. See temp fiddle http://jsfiddle.net/5LwLmu2s/18/ – GuyT Sep 19 '14 at 12:27
  • @Johan It doesn't seems to be the problem: http://stackoverflow.com/questions/2373074/single-vs-double-quotes-vs – Benedek Simo Sep 19 '14 at 12:27
  • @BenedekSimo Hmm.. after some further investigation it looks like that's a combination of `data-role='collapsible'` and `.enhanceWithin`. When you remove one of them, it works. Looks like an event delegation issue. – GuyT Sep 19 '14 at 12:44
  • I have found the problem. You are putting a div in a h5 tag. This is prohibited. Please see my fiddle: http://jsfiddle.net/5LwLmu2s/19/ – GuyT Sep 19 '14 at 13:19
  • Thanks, it looks promising, but I want the button to be clickable without opening the collapsible. Which means it has to be in the h tag. – Benedek Simo Sep 19 '14 at 16:42

1 Answers1

1

This is happening because the events are not bubbling properly.

I am not sure what about the jQuery Mobile event handling is causing the events to be stopped.

A solution is to bind a click handler to the objects right after they are created.

$(document).ready(function () {

    $('#btnSearch').on('click', function () {      
        $('#resultList').html( "<div class='resultItem' data-role='collapsible' data-id='3537' data-content-theme='c'><h5>Biatorbagy(65 - 312)<div><a data-role='button' class='resultZoomButton ui-btn ui-btn-icon-notext ui-icon-search ui-mini ui-corner-all ui-btn-right'></a></div ></h5><p class='attribution'>Year</p ><p class='value' style='white-space:pre-wrap'>1997</p><p class='attribution'>Path</p></div>").enhanceWithin();
        $('#resultList').find('a.resultZoomButton').click(function(e){
            console.debug('Fire');
        });

    });
});

It is not ideal but the best way to do this is to add the handler after the item is created. It would appear also that you are going to be making multiple results. You do not want to bind an event to each one every time.

I would suggest after you add the click handler, also add a special 'bound' class to the object so that each result is only bound once.

$(document).ready(function () {

    $('#btnSearch').on('click', function () {      
        $('#resultList').html( "<div class='resultItem' data-role='collapsible' data-id='3537' data-content-theme='c'><h5>Biatorbagy(65 - 312)<div><a data-role='button' class='resultZoomButton ui-btn ui-btn-icon-notext ui-icon-search ui-mini ui-corner-all ui-btn-right'></a></div ></h5><p class='attribution'>Year</p ><p class='value' style='white-space:pre-wrap'>1997</p><p class='attribution'>Path</p></div>").enhanceWithin();

        var zoomButtons = $('#resultList').find('a.resultZoomButton');

        zoomButtons.each(function(){
            if(!$(this).hasClass('bound')){
                $(this).click(function(e){
                    console.debug('Fire');
                }).addClass('bound');
            }
        });

    });
});

Here is an updated fiddle.

Pow-Ian
  • 3,607
  • 1
  • 22
  • 31
  • I added e.stopPropagation() to your solution and now it works as expected. (Here is an updated fiddle [link](http://jsfiddle.net/5LwLmu2s/21/)) Still not understand though why and how event propagation is stopped or how to investigate these problems with Firebug or sg else. – Benedek Simo Sep 22 '14 at 09:57
  • I think GuyT is probably right. The DOM is malformed when the div is in the H5 tag and thus the events are probably not bubbling properly. jQuery does not usually destroy event handlers with it's added functionality. – Pow-Ian Sep 22 '14 at 11:09