views:

51

answers:

4

I have some tabs which have been created using Javascript and Mootools, my client wants the 'next button' at the bottom of the page to be disabled, until the tabs have been read(clicked). The page is dynamic (created with PHP and MySQL) and there could be two tabs or three, depending on the set-up. I am struggling today to think of the best solution.

Any help more than welcome...

A: 

You should disable the button where you send the request to load the content, and enable it from the callback that handles the returned content.

baloo
+1  A: 

Since the number of tabs is dynamic, I'd probably use an attribute on the tab's header/label/whatever indicating that it has not been read, and then when the tab's header/label/whatever is clicked, I'd change that attribute to indicate that it had been read and then trigger a function that may enable the button depending on whether all the other tabs had been read.

I'm not a MooTools person, but IIRC it's a fork of Prototype (although it's been a while and they've probably diverged). The click handler could look something like this in Prototype:

$$('.tabClass').invoke('observe', 'click', function(event) {
    this.setAttribute("data-read", "Y");
    if ($$('.tabClass[data-read=N]').length == 0) {
        $('buttonId').disabled = false;
    }
});

...where $$ is Prototype's "search the DOM for elements matching this CSS selector" function and $ is Prototype's "get me the element with this ID". The invoke there just calls observe for each matching element (you could do this with event delegation instead), and I think observe is fairly self-evident. :-)

The code above makes these assumptions:

  1. Your tab header or whatever has the class "tabClass".
  2. You've created the tables with the attribute "data-read" set to "N" (e.g., <div class="tabClass" data=read="N"> or similar). The data- prefix is to be HTML5-friendly. (Yes, we're finally allowed to put any old arbitrary attribute name on elements if we want to! We just have to prefix them with data-.)
  3. The button has an ID, "buttonId"
  4. The button starts off disabled

Edit Or use a marker class if you prefer, all tabs start out with class="tabClass unread":

$$('.tabClass').invoke('observe', 'click', function(event) {
    this.removeClassName("unread");
    if ($$('.tabClass.unread').length == 0) {
        $('buttonId').disabled = false;
    }
});

Double-check that MooTools supports the ".tabClass.unread" selector (it really should, I'm just saying, check). Some implementations may work more quickly with class-based selectors than attribute-based ones.

T.J. Crowder
I am liking this idea, I am going to give it a go and see how I get on...
jimbo
@jimbo: Actually, it might be even simpler to start out with two classes on the tab header/label/whatever, and then remove one on click. Much the same as the above, just changes the selectors a bit and you'd use the MooTools equivalent of Prototype's `Element#removeClassName` to remove the "unread" class.
T.J. Crowder
A: 

I would add a class to the tab when it's clicked - like "clicked". Also, check if the 'click' is the last tab, so..

$('myElement').set('class', 'clicked');

then get all of the tab elements (a elements i assume) and count them. Then get all of the tab elements with class "clicked"

If they match, they were all 'clicked'.

Dan Heberden
+1  A: 

view example working on jsfiddle: http://www.jsfiddle.net/dimitar/THMxa/

it can work with some classes and logic added to tab clicks and next click.

// fade out next button and set it to disabled, then define the event to check state.
document.id("next").store("disabled", true).set("opacity", .5).addEvent("click", function() {
    if (this.retrieve("disabled")) {
        alert("please view all tabs first!");
        // console.log(document.getElement("div.notclicked"));
        return;
    }
    // insert code here that goes next.
    alert("allowed to run");
});

// this is pseudo - you probably already have a function that assigns events on your tabs to change
document.getElements("div.tabs").each(function(tab) {
    // first tab may already be open so no click needed
    if (!tab.hasClass("clicked"))
        tab.addClass("notclicked");

    // add click event
    tab.addEvent("click", function() {
        if (document.getElement("div.notclicked"))
            this.addClass("clicked").removeClass("notclicked");
        // check again if that was the last one, if so, enable next button...
        if (!document.getElement("div.notclicked"))
            document.id("next").store("disabled", false).fade("in"); // or whatever

        // regular code for tabs here...
    });
});
Dimitar Christoff
I had to change document.id("next") to document.getElementById but apart from that great job :)
jimbo
document.id is an alias for $ (or vice versa) since mootools 1.2.3 (the no conflict mode).do NOT use document.getElementById() as it does not extend elements. chances are, you're on an older version of mootools, so just use $("next") etc.
Dimitar Christoff