jQuery / jQuery UI - $("a").live("click", ...) not working for tabs

1.8k views Asked by At

So I have some jQuery UI tabs. The source code is as follows:

HTML:

<div class="tabs">
    <ul>
        <li><a href="#ranges">Ranges</a></li>
        <li><a href="#collections">Collections</a></li>
        <li><a href="#designs">Designs</a></li>
    </ul>
    <div id="ranges"></div>
    <div id="collections"></div>
    <div id="designs"></div>
</div>

jQuery:

$(document).ready(function() {
    $(".tabs").tabs();
});

My problem is that I am trying to make each tab load a page into the content panel on click of the relevant link. To start with I am just trying to set the html of all the panels on clicking a link. From the code below, if I use method 1, it works for all links. However if I use method 2 it doesn't - but only for the links in the tabs (i.e. the labels you click to select a tab).

Method 1 (works for all links all the time, but would not be applied to links which are added after this is called):

$("a").click(function () {
    $("#ranges, #collections, #designs").html("clicked");
});

Method 2 (works for all links which are not "tabified"):

$("a").live("click", function () {
    $("#ranges, #collections, #designs").html("clicked");
});

Does anyone know why it is behaving like this? I would really like to get method 2 working properly as there may well be links which I need to add click events to which are added after the page is originally loaded.

Thanks in advance,

Richard

PS yes the function calls for .live and .click are both in the $(document).ready() function, before anyone says that that may be the problem - otherwise it wouldn't work at all..

Edit:

The solution I came up with involves an extra attribute in the anchors (data-url) and the following code (which outputs a 404 not found error if the page cannot be loaded). I aim to expand this over the next few weeks / months to be a lot more powerful.

$(".tabs").tabs({
    select: function (event, ui) {
       $(ui.panel).load($(ui.tab).attr("data-url"), function (responseText, textStatus, XMLHttpRequest) {
           switch (XMLHttpRequest.status) {
               case 200: break;
               case 404:
                   $(ui.panel).html("<p>The requested page (" + $(ui.tab).attr("data-url") + ") could not be found.</p>");
                   break;
               default:
                   $(ui.panel).html("<p title='Status: " + XMLHttpRequest.status + "; " + XMLHttpRequest.statusText + "'>An unknown error has occurred.</p>");
                   break;
           };
       });
   }
});
3

There are 3 answers

6
roflwaffle On BEST ANSWER

I don't know if I understand what you are going for but basically you want to do something once a tab is clicked? Here's the docs for setting up a callback function for selecting a tab.

EDIT: Don't know if that link is working correctly, you want to look at select under Events. But basically it is:

$("#tabs").tabs({
    select: function(event, ui) { ... }
});

Where ui has information on the tab that was clicked.

3
Betamos On

Maybe the tabs() plugin that you are using is calling event.preventDefault(); (Reference) once it has created it's tabs.

Then it captures the click event and the bubbling stops, so it doesn't invoke your click-function. In jQuery this is done with

$(element).click(function(){
    // Do stuff, then
    return false; // Cancels the event
});

You'd have to alter the tabs() plugin code and remove this return false; statement, OR if you are lucky, the plugin might have an option to disable that behavior.

EDIT: Now I see you're using jQuery UI. Then you should check the documentation there, since it is an awesome plugin, it will do anything you want if you do the html right and pass it the right options.

0
scurker On

jQuery UI tabs has an outstanding issue where return false; is used instead of event.preventDefault();. This effectively prevents event bubbling which live depends on. This is scheduled to be fixed with jQuery UI 1.9 but in the meantime the best approach is use the built in select event as suggested by @rolfwaffle.