Question

I have a page of dynamically created JQuery 1.3.1 collapsible items (not in an accordion set), and I am trying to save the expanded or collapsed state of each item. The collapsible items work fine without attaching any handlers. My code to attach the handlers is here, which I'm calling in pagebeforeshow (I tried in pageshow as well):

function bindCollapsibleHistoryHandlers(){
    function getHandler(field, value){
        var handler = function(event, ui){
            var element = event.target.id;
            var id = (element.split('-'))[1];
            var status = window.mam_history.status('meetings', id);
            if (null == status){
                status = { "open": false, "note_open": false, "dist_open": false };
            }
            status[field] = value;
            var new_status = null;
            window.mam_history.status('meetings', id, status);
                        return true;
        }
        return handler;
    }

    $('.mtg_item').off('collapsiblecollapse');
    $('.mtg_item').on('collapsible', getHandler('open', false));
    $('.mtg_item').off('collapsibleexpand');
    $('.mtg_item').on('collapsibleexpand', getHandler('open', true));

    $('.dist_info').off('collapsiblecollapse');
    $('.dist_info').on('collapsiblecollapse', getHandler('dist_open', false));
    $('.dist_info').off('collapsibleexpand');
    $('.dist_info').on('collapsibleexpand', getHandler('dist_open', true));
}

One of the HTML elements looks like this in the Chrome inspector:

enter image description here

According to the JQuery Mobile 1.3.1 documentation, the events to trap are collapsiblecollapse and collapsibleexpand. When I try using these, the event handlers never get called. Looking on the web I replaced these events with collapse and expand. With these, the event handler would be called when the collapsible was clicked, but the collapsible widget would not collapse or expand either before or after the handler ran. It's not just a visual issue, because the state of the collapsible as read with .collapsible('option', 'collapsed') did not change either.

Inside the handler I tried various combinations of adding or removing the ui-collapsible-collapsed class or setting the collapsible option before a .trigger('create'), and even triggering the collapsiblecollapse and collapsibleexpand inside the handler (when it was bound to collapse and expand, of course). Removing the .off() lines made no difference (I can't imagine why it would). Nothing I've tried so far will cause the collapsible to collapse or expand when clicked on when the handler actually runs while bound to collapse or expand. It doesn't matter what code is actually in the handler, or whether I have a data-collapsed attribute in the <div> tag to begin with or not.

So it seems there's something I'm missing, and I would appreciate any help in seeing the error in my ways.

Was it helpful?

Solution

Solution

Working example: http://jsfiddle.net/Gajotres/3pCQh/

As you have notices proper way to detect collapsible state is to use collapse and expand event (information provided in official documentation is wrong). Also when binding events in jQuery Mobile, specially with dynamically created objects it is important to use delegated binding, like this:

$(document).on( "collapse", "#test-collapsible", function( event, ui ){
    alert('Close');
});

$(document).on( "expand", "#test-collapsible", function( event, ui ){
    alert('Open');
});  

This example doesn't care if object exist or don't exist. Event is going to be bound to document object and it will propagate to the correct destination only if/when object becomes available inside the DOM.

Few notes

If you use correct page event (like pageinit) you don't need to use off to unbind an event. Pageinit will trigger only once, just like document ready when used with classic jQuery.

There's one more thing. If you are using several HTML pages you need to be careful with your javascript. When jQuery Mobile loads additional HTML pages it loads only BODY content so everything inside a HEAD will be discarded. This could also be the reason why your code example is not executing. Solutions to this problem can be fond HERE.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top