views:

1230

answers:

3

Hi

I am trying to stop some events but stopPropagation does not work with "live" so I am not sure what to do. I found this on their site.

Live events do not bubble in the traditional manner and cannot be stopped using stopPropagation or stopImmediatePropagation. For example, take the case of two click events - one bound to "li" and another "li a". Should a click occur on the inner anchor BOTH events will be triggered. This is because when a $("li").bind("click", fn); is bound you're actually saying "Whenever a click event occurs on an LI element - or inside an LI element - trigger this click event." To stop further processing for a live event, fn must return false

It says that fn must return false so what I tried to do

 $('.MoreAppointments').live('click', function(e) {
   alert("Hi");
   return false;
 });

but that did not work so I am not sure how to make it return false.

Update

Here is some more information.

I have a table cell and I bind a click event to it.

 $('#CalendarBody .DateBox').click(function(e)
    {
        AddApointment(this);
    });

So the AddApointment just makes some ui dialog box.

Now the live code(MoreAppointments) sits in this table cell and is basically an anchor tag. So when I click on the anchor tag it first goes to the above code(addApointment - so runs that event first) runs that but does not launch my dialog box instead it goes straight to the (MoreAppointment) event and runs that code. Once that code has run it launches the dialog box from "addApointment".

Update 2

Here is some of the html. I did not copy the whole table since it is kinda big and all the cells repeat itself with the same data. If needed I will post it.

 <td id="c_12012009" class="DateBox">
        <div class="DateLabel">
            1</div>
        <div class="appointmentContainer">
            <a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a>
        </div>
        <div class="appointmentOverflowContainer">
            <div>
                <a class="MoreAppointments">+1 More</a></div>
        </div>
    </td>
+2  A: 

Maybe you could check that the click event didn't occur on an a element:

$('#CalendarBody .DateBox').click(function(e) {
  // if the event target is an <a> don't process:
  if ($(e.target).is('a')) return;

  AddApointment(this);
});

Might Work?

gnarf
This seems to work just got to do some more testing on it. However I wonder if there could be a situation that the click event is an anchor tag it self and it would stop its self from calling the rest of the code. But then again I don't know anything about this target so this might not be a problem at all.
chobo2
A: 

I use

e.stopPropagation(); // to prevent event from bubbling up
e.preventDefault(); // then cancel the event (if it's cancelable)
shinkou
These don't work with "live" query though.
chobo2
+17  A: 

The short answer is simply, you can't.

The problem

Normally, you can stop an event from "bubbling up" to event handlers on outer elements because the handlers for inner elements are called first. However, jQuery's "live events" work by attaching a proxy handler for the desired event to the document element, and then calling the appropriate user-defined handler(s) after the event bubbles up the document.

Bubbling illustration

This generally makes "live" binding a rather efficient means of binding events, but it has two big side-effects: first, any event handler attached to an inner element can prevent "live" events from firing for itself or any of its children; second, a "live" event handler cannot prevent any event handlers attached directly to children of the document from firing. You can stop further processing, but you can't do anything about processing that has already occurred... And by the time your live event fires, the handler attached directly to the child has already been called.

Solution

Your best option here (so far as I can tell from what you've posted) is to use live binding for both click handlers. Once that's done, you should be able to return false from the .MoreAppointments handler to prevent the .DateBox handler from being called.

Example:

$('.MoreAppointments').live('click', function(e) 
{
  alert("Hi");
  return false; // prevent additional live handlers from firing
});

// use live binding to allow the above handler to preempt
$('#CalendarBody .DateBox').live('click', function(e)
{
   AddApointment(this);
});
Shog9
What do you mean handler? Is that the MoreAppointments one?
chobo2
Yes - I've added an example.
Shog9
Wow that makes so much sense. Now I have to choose what the best answer your answer explains how live works with event bubbling and gives a solution. Or gnarf solution that takes no modifications to my code and works as well but in future cases might now work.
chobo2