+1  A: 

In your Ajax success handler try the following:

//make collapsible
        $("h1.handle:not(.open)").click(function() {
            var object = $(this);
            $(this).next().toggle("fast", colapsible_class(object));
            return false;
        }).addClass("open");
Keith Rousseau
+1  A: 

Use jQuery 1.3 live events instead.

//make colapsible
$("h1.handle").live("click", function() {
    var object = $(this);
    v$(this).next().toggle("fast", colapsible_class(object));
    vreturn false;
}).addClass("open");

and then eliminate the click declaration in the second block of code, changing it to $("h1.handle").addClass("open");

Live events bind all current and future matching elements with an event.

R. Bemrose
Along with the live event that you set up you should scope that (in jQuery 1.4) to the the surrounding element. Otherwise the click event will be attached to your page - which is clearly less efficient.
Keith Rousseau
+1  A: 

The best way to solve your problem is, instead of using $("h1.handle") on the AJAX callback, go for $(data).find("h1.handle"). Something like,

var x = $(data);
x.insertBefore(...);
/* your other code */
x.find('h1.handle').click(...).addClass(...);

Like that, only the newly added items will have the event bounded. The already present ones will not be touched.

If we want to answer your question instead of just solving your problem, then we have several alternatives, such as:

  • store, in your objects, that the onclick event handler has been set so that you don't set it twice
  • always bind the onclick event, but always unbind it first
  • use jQuery's live events and the addClass open only on the newly created items.

IMO, the first one is the easiest. You can accomplish it by using jQuery's data(). Then you could do something like:

$("h1.handle").each(function() {
  var me = $(this);

  // if already has click handler, don't do anything
  if (me.data('click_set') != null) { return true; }
  // otherwise, store the data and bind the click event
  me.data('click_set', true).click(function() {
   /* the code you already have on the click handler */
  }).addClass('open');
}

The second alternative involves storing the function that you pass inline to the click event binder in a variable, and then using jQuery's unbind to disable it.

Miguel Ventura
You don't have to store that the click is set. You know that because he has also appended the open class to those elements. Also, performing jQuery selectors against elements not in the DOM is ridiculously slow in ie6 and I would recommend against doing that.
Keith Rousseau