-1

I've just read some threads about using on() to attach events to dynamically created html elements. I came up with this example (FIDDLE) to try to bind the click event to elements div.clicktitle returned via AJAX. The div elements have data attributes from which the click event should get the values and then display them. But It doesn't seem to be working.

What is working for me is to define the click event function and put it in the Ajax success callback. (FIDDLE) Is that the only way to make the click event to work with AJAX returned elements? Can anyone tell me why .on() isn't attaching the event to div.clicktitle?

HTML before Ajax

<div class="main"></div>
<div class="second"></div>

After Ajax it should be

<div class="main"><div data-source="Hello" class="clicktitle"><h6>Title1</h6></div></div>
<div class="second"><div data-source="Hello" class="clicktitle"><h6>Title2</h6></div></div>

JS Code:

 $.ajax({
    url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20rss%20where%20url%3D%22https%3A%2F%2Fnews.google.com%2F%3Foutput%3Drss%22&format=json&diagnostics=true&callback=",
    success: function (data) {
        var length = 0;
        var items = data.query.results.item;
        items = items.map(function(item){

        return '<div data-source="Hello" class="clicktitle"><h6 style="background:beige;">'+item.title+'</h6></div>';
        });
        var half = items.length/2;
        for(var i = 0; i < items.length; i++)
            if(i < half)
                $('.main').append(items[i]);
            else
                $('.second').append(items[i]); 
            length++;
        },

    error: function () {}        
});


    $('.clicktitle').on("click",function(){
      var datasource = $(this).data('source');
      $(this).text(datasource); 
    });
RedGiant
  • 4,444
  • 11
  • 59
  • 146
  • Please provide your "attempts" directly in the question. You are misusing .on. I'm sure at least one of the previous questions you read covered that issue. – Kevin B May 05 '14 at 20:43
  • I believe this will work: $(document).on("click", ".clicktitle", function(){...}) – Alen May 05 '14 at 20:45

3 Answers3

2

This should do it for you:

$('div').on("click",'.clicktitle',function(){
      var datasource = $(this).data('source');
      $(this).text(datasource); 
 });
Steven Britton
  • 197
  • 2
  • 5
1

the problem is that you try to add the listener directly to the generated element.

You have to add it to the parent element and use the filter in the on function like this :

    $.ajax({
    url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20rss%20where%20url%3D%22https%3A%2F%2Fnews.google.com%2F%3Foutput%3Drss%22&format=json&diagnostics=true&callback=",
    success: function (data) {
        var length = 0;
        var items = data.query.results.item;
        items = items.map(function(item){

        return '<div data-source="Hello" class="clicktitle"><h6 style="background:beige;">'+item.title+'</h6></div>';
        });
        var half = items.length/2;
        for(var i = 0; i < items.length; i++)
            if(i < half)
                $('.main').append(items[i]);
            else
                $('.second').append(items[i]); 
            length++;
        },

    error: function () {}        
});

   $('.main, .second').on("click",".clicktitle",function(){ 
    var datasource = $(this).data('source');
    $(this).text(datasource); 
   });

JSFIDDLE

hope this cut help you

Timo Jungblut
  • 662
  • 6
  • 16
1

Your binding won't work because your element doesn't exist yet, if you take @Alen's suggestion, that should do it for you, but you'll evaluate the handler EVERYTIME a click is made anywhere.

What you could do is attach the handler to the element before you write it to the DOM.

// Reusable event bheaviour
function clickBinding = function( event ){
    var $elem = $(event.target),
        datasource = $(this).data('source');
    $elem.text(datasource); 
}

// format item
function formatItem (item){
//setup elems
    var h6 = document.createElement('h6'),
        clickTitle = document.createElement('div');
    // config h6
    h6.style.background = 'beige';
    h6.innerHTML = item.title;
    clickTitle.appendChild(h6);
    // config clickTitle
    clickTitle.className = 'clicktitle';
    clicktitle.setAttribute('data-source', 'Hello');
    // Add event listeners
    if (clicktitle.addEventListener) {
        clicktitle.addEventListener ('click', clickBinding, false);
    } else if (clicktitle.attachEvent) {
        clicktitle.attachEvent ('onclick', clickBinding);
    }
    // return elem
    return clicktitle;
}

$.ajax({
    url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20rss%20where%20url%3D%22https%3A%2F%2Fnews.google.com%2F%3Foutput%3Drss%22&format=json&diagnostics=true&callback=",
    success: function (data) {
        var length = 0;
        var items = data.query.results.item;
        items = items.map(function(item){
            return formatItem(item);
        });
        var half = items.length/2;
        for(var i = 0; i < items.length; i++)
            if(i < half)
                $('.main').append(items[i]);
            else
                $('.second').append(items[i]); 
            length++;
        },

    error: function () {}        
});
Thierry Blais
  • 2,848
  • 22
  • 41
  • Thank you. Here's the working [fiddle](http://jsfiddle.net/4XmUu/51/). I find that using `$(document).on("click", ".clicktitle", function(){...})` would fire up the function everytime I click anywhere on the page. And the click function I'm working on is retrieving a JSON file! – RedGiant May 05 '14 at 21:21