1

Is it possible to raise a jquery event when an element with a certain class is created dynamically? This is what I mean. I have the following;

...
<div id="lotoContent"></div>
...

Using jquery ajax, I'm retrieving several rows from the server and appending them to the "lotoContent" div. Each row has an empty span element that looks like this

<span class="lotoDateTime" data-date="123456"></span>

The value of the data-date attribute is a unix time-stamp retrived from the database. Once the rows are added, the following javascript function is called;

function processDateTimes() {
   //process dates
    $('.lotoDateTime').each(function () {
        var timeStamp = $(this).data('date');
        $(this).text(getDateTimeFromServerUnixTimeStamp(timeStamp));
    });

}

function getDateTimeFromServerUnixTimeStamp(timeStamp) {
  //this function takes the unix time-stamp and converts it to Date and Time 
  // like 08/09/2013 12:09 based on the browser time
}

This works fine, but I was wondering if there is a way to automatically call processDateTimes() when the date spans are created instead of manually calling the function after they are created. Something like this is what I have in mind;

$('#lotoContent').on('SomeEvent', '.lotoDateTime', function() {
  processDateTimes();
});

Thanks.

Moses Machua
  • 11,245
  • 3
  • 36
  • 50

2 Answers2

2

The word you may be looking for is observables. In essence, when the DOM (or in this situation a span element) is updated you'd like to trigger an event.

For that answer I'd like to direct your attention to this response,

https://stackoverflow.com/a/240663/191006

Ken illustrates that capturing all DOM changes at the top will allow you to pick and choose what do to on certain inner elements.

$('body').change(function(event){

    if( $(event.target).hasClass("lotoDateTime") )
        processDateTimes();

 });

You could certainly clean this up... you don't need to check for the class like I am... but I hope that helps you get going in the right direction.

Community
  • 1
  • 1
Erik5388
  • 2,171
  • 2
  • 20
  • 29
  • Nice I'll give it a try. – Moses Machua Aug 10 '13 at 13:49
  • I'd like to note: The DOM already raises events for when objects change. When you add a listener to the body element you're not "adding" any events or taking up any additional memory. Simsey is incorrect to assume that it was cause browser grief. Listening exposes the events for you "see". – Erik5388 Aug 13 '13 at 18:50
  • `Erik5388`, I'm using your solution above, and so far I haven't experienced any glitches. Unless something changes, I'll leave the code as it is. Thanks. – Moses Machua Aug 14 '13 at 21:58
1

can you not give the new rows a class of "new" when the ajax populates them and change the function processDateTimes() to run on items with the class of "new" and then remove the class once it's done its thing.

finally invoke the function at the end of your ajax call (complete) ?

$.ajax( ... ,
  success: function() {
    // add your element and give it a class of "new"
  },
  complete: function() {
    // then run your process function:
    processDateTimes();
  }
);

// this will only run on "new" items added
function processDateTimes() {

  $('.lotoDateTime.new').each(function() {
    var timeStamp = $(this).data('date');
    $(this)
      .text(getDateTimeFromServerUnixTimeStamp(timeStamp))
      .removeClass('new');

  });

}
simey.me
  • 2,147
  • 1
  • 19
  • 21
  • I am doing it similarly to your solution where I call processDateTimes() inside the ajax Done() event. I was tryng to avoid having to call the function manually but have an event trigger the function automatically only when an element with class="lotoDateTime" is created. Erik5388's solution does that – Moses Machua Aug 10 '13 at 13:55
  • 1
    Ok, Not sure how big your app is, but monitoring changes to the `body` could get quite strenuous if you have a lot of DOM manipulation occuring elsewhere :) – simey.me Aug 10 '13 at 15:45
  • `Simney.me` I was afraid of that. The app is purely ajax driven so a lot of Dom changes happen which concerns me too. I may have have to stick to my old solution if `Erik5388's` solutions proves too strenuous to the browser. – Moses Machua Aug 10 '13 at 18:25
  • You should reference [jquery.com](http://api.jquery.com/change/) as well, since I'm not even certain the `change` event will work. However you can always create your own [custom events and triggers](http://api.jquery.com/trigger/) – simey.me Aug 10 '13 at 19:28