Keith Power
Keith Power

Reputation: 14151

jQuery mobile accordion

I have a jQuery listview and the following code to change it into an accordion. Within the <li> I have a div with the class "ui-li-accordion" which hides the content and then reveals with a click.

The problem I am having is that I want to put drop-downs in the div but when I click the drop-down the div slides back up again.

What I need is if anywhere in the div is clicked no slide action is taken. Only outside of that.

/*
 * jQuery Mobile Framework : listview accordion extension
 * Copyright (c) Boris Smus, Christopher Liu
 * Note: Code is in draft form and is subject to change
 */
(function($, undefined ) {

    $( "[data-role='listview']" ).live( "listviewcreate", function() {
        var list = $( this ),
        listview = list.data( "listview" );

        var accordionExpandOne = function(accordion) {
            // Close all other accordion flaps
            list.find('.ui-li-accordion').slideUp();
            // Open this flap
            accordion.slideToggle();
        }
        var accordionDecorator = function() {
            list.find('.ui-li-accordion').each(function(index, accordion) {
                // Format the accordion accordingly:
                // <li>...normal stuff in a jQM li
                // <div class="ui-li-accordion">...contents of this</div>
                // </li>
                // If we find an accordion element, make the li action be to open the accordion element
                // console.log('accordion found ' + accordion);
                // Get the li
                var $accordion = $(accordion);
                $li = $accordion.closest('li');
                // Move the contents of the accordion element to the end of the <li>
                $li.append($accordion.clone());
                $accordion.remove();
                // Unbind all click events
                $li.unbind('click');
                // Remove all a elements
                $li.find('a').remove();
                // Bind click handler to show the accordion
                $li.bind('click', function() {
                    var $accordion = $(this).find('.ui-li-accordion');
                    // Check that the current flap isn't already open
                    if ($accordion.hasClass('ui-li-accordion-open')) {
                        $accordion.slideUp();
                        $accordion.removeClass('ui-li-accordion-open');
                        return;
                    }
                    console.log('continue');
                    // If not, clear old classes
                    list.find('.ui-li-accordion-open').removeClass('ui-li-accordion-open');
                    $accordion.toggleClass('ui-li-accordion-open');
                    accordionExpandOne($accordion);
                });
            });
        };
        var accordionExpandInitial = function() {
            //Expand anything already marked with -open.
            accordionExpandOne(list.find('.ui-li-accordion-open'));
        };

        accordionDecorator();
        accordionExpandInitial();

        // Make sure that the decorator gets called on listview refresh too
        var orig = listview.refresh;
        listview.refresh = function() {
            orig.apply(listview, arguments[0]);
            accordionDecorator();
        };
    });
})( jQuery );

Upvotes: 2

Views: 1144

Answers (1)

Jasper
Jasper

Reputation: 76003

How about using event.stopPropagation(); in an event handler for the select menus:

$('#container-element').find('select').bind('click', function (event) {
    event.stopPropagation();
});

event.stopPropagation()

Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.

Here the documentation for event.stopPropagation(): http://api.jquery.com/event.stopPropagation/

Upvotes: 2

Related Questions