Maher4Ever
Maher4Ever

Reputation: 1280

How to trigger focusout event on a ul element?

I have a plugin that changes the look of select html tag on all browser.

I'm trying to make the new styled set of elements behave like a normal select tag. I'm almost there, but I only need to figure one thing out and that's how to hide a ul on focus out.

First off, here is a demo of the new select element (not in English, but you can find it easily ^^) : http://mahersalam.co.cc/projects/n-beta/

If you click the toggle button of the select element, and then click away, the ul element that has the options won't disappear. That's because I can't fire a focusout event on that ul.

Here is the code that controls how the events are handled:

// Make a div which will be used offline and then inserted to the DOM
$namodgSelect = $('<div class="namodg-select"></div>');

/* other stuff ... */

$namodgSelect // Handle all needed events from the wrapper
    .delegate('a', 'click focus blur', function(e) {

        // Type of the event
        var type = e.type,

        // Declare other vars
            id,
            $this;

        e.preventDefault(); // Stop default action

        // Make an id ot the element using it's tag name and it's class name
        // Note: Because we add a class on the active toggler, it's easier to remove it from here and the logic will still work
        id = e.target.tagName.toLowerCase() + '.' + e.target.className.replace(' toggler-active', '');

        switch (id) {

            case 'p.selected': case 'div.toggle-button':

                // Only accept 'click'  on p and div
                if ( type != 'click') {
                    return;
                }

                // Show and hide the options holder
                if ( $optionsHolder.data('hidden') ) {

                    $selectElem.focus();

                    // This needs to run fast to give feedback to the user
                    $toggler.addClass('toggler-active').data('active', true);

                    // Show the options div
                    $optionsHolder.stop(true, true).slideDown('fast', function() {

                        // Sometimes fast clicking makes the toggler deavtive, so show it in that case
                        if ( ! $toggler.data('active') ) {
                           $toggler.addClass('toggler-active').data('active', true);
                        }

                    }).data('hidden', false);

                } else {

                    $selectElem.blur();

                    // Hide the options div
                    $optionsHolder.stop(true, true).slideUp(function() {

                        // Only hide the toggler if it's active
                        if ( $toggler.data('active') ) {
                           $toggler.removeClass('toggler-active').data('active', false);
                        }

                    }).data('hidden', true);

                }
                break;

            case 'a.toggler':
                switch (type) {
                    case 'focusin':
                        $selectElem.focus();
                        break;
                    case 'focusout':
                        // Only blur when the options div is deactive
                        if ( $optionsHolder.data('hidden') ) {
                            $selectElem.blur();
                        }
                        break;
                    case 'click':
                        $selectedHolder.click();
                        $selectElem.focus();
                }
                break;

           case 'a.option':
               // Stop accept click events
               if ( type != 'click') {
                    return;
                }

                // cache this element
                $this = $(this);

                // Change the value of the selected option and trigger a change event
                $selectedOption.val( $this.data('value') ).change();

                // Change the text of the fake select and trigger a click on it
                $selectedHolder.text( $this.text() ).click();
                break;
        }
    })

The whole code can be seen from the demo. As you can see, I already use the focusout event on the toggler and the options, so I can't hide the ul when that happens (that will disable the tab functionality).

If anyone can help me with this , it will be appreciated. Thanks.

Upvotes: 3

Views: 4432

Answers (2)

Maher4Ever
Maher4Ever

Reputation: 1280

I was able to hide the options panel using this code:

$(document).click(function() {
    if ( $optionsHolder.data('hidden') || $optionsHolder.is(':animated') ) {
        return;
    }
   $selectedHolder.click();
})

This works because focusing on another input is like a click on the document.

Upvotes: 0

PetersenDidIt
PetersenDidIt

Reputation: 25620

Try out the jQuery outside events plugin Will let you do something like:

$(this).bind( "clickoutside", function(event){
  $(this).hide();
});

Upvotes: 2

Related Questions