1 (function( $, undefined ) {
3 $.widget( "mobile.collapsible", $.mobile.widget, {
5 expandCueText: " Expandable list, tap to open list",
6 collapseCueText: " Expandable list, tap to close list",
8 heading: "h1,h2,h3,h4,h5,h6,legend",
13 initSelector: ":jqmData(role='collapsible')"
17 var $el = this.element,
19 collapsible = $el.addClass( "ui-collapsible" ),
20 collapsibleHeading = $el.children( o.heading ).first(),
21 collapsedIcon = $.mobile.getAttrFixed( $el[0], "data-" + $.mobile.ns + "collapsed-icon" ) || o.collapsedIcon,
22 expandedIcon = $.mobile.getAttrFixed( $el[0], "data-" + $.mobile.ns + "expanded-icon" ) || o.expandedIcon,
23 collapsibleContent = collapsible.wrapInner( "<div class='ui-collapsible-content'></div>" ).children( ".ui-collapsible-content" ),
24 collapsibleSet = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" );
26 // Replace collapsibleHeading if it's a legend
27 if ( collapsibleHeading.is( "legend" ) ) {
28 collapsibleHeading = $( "<div role='heading'>"+ collapsibleHeading.html() +"</div>" ).insertBefore( collapsibleHeading );
29 collapsibleHeading.next().remove();
32 // If we are in a collapsible set
33 if ( collapsibleSet.length ) {
34 // Inherit the theme from collapsible-set
36 o.theme = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "theme" ) || $.mobile.getInheritedTheme( collapsibleSet, "c" );
38 // Inherit the content-theme from collapsible-set
39 if ( !o.contentTheme ) {
40 o.contentTheme = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "content-theme" );
43 // Get the preference for collapsed icon in the set
44 if ( !o.collapsedIcon ) {
45 o.collapsedIcon = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "collapsed-icon" );
47 // Get the preference for expanded icon in the set
48 if ( !o.expandedIcon ) {
49 o.expandedIcon = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "expanded-icon" );
51 // Gets the preference icon position in the set
53 o.iconPos = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "iconpos" );
55 // Inherit the preference for inset from collapsible-set or set the default value to ensure equalty within a set
56 if ( $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "inset" ) !== undefined ) {
57 o.inset = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "inset" );
61 // Gets the preference for mini in the set
63 o.mini = $.mobile.getAttrFixed( collapsibleSet[0], "data-" + $.mobile.ns + "mini" );
66 // get inherited theme if not a set and no theme has been set
68 o.theme = $.mobile.getInheritedTheme( $el, "c" );
73 collapsible.addClass( "ui-collapsible-inset" );
76 collapsibleContent.addClass( ( o.contentTheme ) ? ( "ui-body-" + o.contentTheme ) : "");
78 collapsedIcon = $.mobile.getAttrFixed( $el[0], "data-" + $.mobile.ns + "collapsed-icon" ) || o.collapsedIcon || "plus";
79 expandedIcon = $.mobile.getAttrFixed( $el[0], "data-" + $.mobile.ns + "expanded-icon" ) || o.expandedIcon || "minus";
82 //drop heading in before content
83 .insertBefore( collapsibleContent )
84 //modify markup & attributes
85 .addClass( "ui-collapsible-heading" )
86 .append( "<span class='ui-collapsible-heading-status'></span>" )
87 .wrapInner( "<a href='#' class='ui-collapsible-heading-toggle'></a>" )
93 iconpos: $.mobile.getAttrFixed( $el[0], "data-" + $.mobile.ns + "iconpos" ) || o.iconPos || "left",
102 .find( "a" ).first().add( ".ui-btn-inner", $el )
103 .addClass( "ui-corner-top ui-corner-bottom" );
108 .bind( "expand collapse", function( event ) {
109 if ( !event.isDefaultPrevented() ) {
110 var $this = $( this ),
111 isCollapse = ( event.type === "collapse" ),
112 contentTheme = o.contentTheme;
114 event.preventDefault();
116 // Custom event callback
117 if ( o.customEventHandler ) { o.customEventHandler.call( this, isCollapse ) };
120 .toggleClass( "ui-collapsible-heading-collapsed", isCollapse )
121 .find( ".ui-collapsible-heading-status" )
122 .text( isCollapse ? o.expandCueText : o.collapseCueText )
125 .toggleClass( "ui-icon-" + expandedIcon, !isCollapse )
126 // logic or cause same icon for expanded/collapsed state would remove the ui-icon-class
127 .toggleClass( "ui-icon-" + collapsedIcon, ( isCollapse || expandedIcon === collapsedIcon ) )
129 .find( "a" ).first().removeClass( $.mobile.activeBtnClass );
131 $this.toggleClass( "ui-collapsible-collapsed", isCollapse );
132 collapsibleContent.toggleClass( "ui-collapsible-content-collapsed", isCollapse ).attr( "aria-hidden", isCollapse );
133 collapsibleContent.children( "li" ).not( "ui-collapsible-content" ).attr( "tabindex", isCollapse ? "" : "0" );
135 if ( contentTheme && !!o.inset && ( !collapsibleSet.length || collapsible.jqmData( "collapsible-last" ) ) ) {
137 .find( "a" ).first().add( collapsibleHeading.find( ".ui-btn-inner" ) )
138 .toggleClass( "ui-corner-bottom", isCollapse );
139 collapsibleContent.toggleClass( "ui-corner-bottom", !isCollapse );
141 collapsibleContent.trigger( "updatelayout" );
144 .trigger( o.collapsed ? "collapse" : "expand" );
147 .bind( "tap", function( event ) {
148 collapsibleHeading.find( "a" ).first().addClass( $.mobile.activeBtnClass );
150 .bind( "click", function( event ) {
152 var type = collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ? "expand" : "collapse";
154 collapsible.trigger( type );
156 event.preventDefault();
157 event.stopPropagation();
162 //delegate auto self-init widgets
163 $.delegateSelfInitWithSingleSelector( $.mobile.collapsible );