diff --git a/docs/content/content-collapsible-set.html b/docs/content/content-collapsible-set.html index ad2e7513..c0c5da6c 100644 --- a/docs/content/content-collapsible-set.html +++ b/docs/content/content-collapsible-set.html @@ -72,6 +72,25 @@ + +

Here is an example of a collapsible with 3 sections and data-content-theme set

+ +
+
+

Section F

+

I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I have the "collapsed" state; you need to expand the header to see me.

+
+
+

Section G

+

I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I have the "collapsed" state; you need to expand the header to see me.

+ +
+
+

Section H

+

I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I have the "collapsed" state; you need to expand the header to see me.

+ +
+
diff --git a/docs/content/content-collapsible.html b/docs/content/content-collapsible.html index 4fce248b..4cb9ecd4 100755 --- a/docs/content/content-collapsible.html +++ b/docs/content/content-collapsible.html @@ -25,7 +25,9 @@

Collapsible content markup

To create a collapsible blocks of content, create a container and add the data-role="collapsible" attribute.

- + +

Using data-content-theme attribute allows you to set a theme for the content of the collapsible.

+

Directly inside this container, add any header element (H1-H6). The framework will style the header to look like a clickable button and add a "+" icon to the left to indicate it's expandable.

After the header, add any HTML markup you want to be collapsible. The framework will wrap this markup in a container that will be hidden/shown when the heading is clicked.

@@ -63,9 +65,9 @@

Collapsible example

This page has 4 collapsible containers with different types of content inside.

-
+

Section 1: Collapsed text block

-

I'm closed when the page loads because I have the data-collapsed="true" attribute on my container.

+

I'm closed when the page loads because that's the default state of a collapsible.

I'm the collapsible content. I'm the collapsible content. I'm the collapsible content. I'm the collapsible content. I'm the collapsible content. I'm the collapsible content. I'm the collapsible content.

@@ -106,6 +108,11 @@
  • Ford
  • + +
    +

    Section 5: themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +

    Nested Collapsibles

    diff --git a/docs/content/content-themes.html b/docs/content/content-themes.html index 7ce05325..f3a5e6c3 100755 --- a/docs/content/content-themes.html +++ b/docs/content/content-themes.html @@ -24,10 +24,12 @@

    Theming the content area

    The main content area of a page (container with the data-role="content" attribute) should be themed by adding the data-theme attribute to the data-role="page" container to ensure that the background colors are applied to the full page, regardless of the content length. (If you add to the data-theme to the content container, the background color will stop after the content so there may be a gap in color between the content and fixed footer.)

    - +

    Additionally, the content area can be themed to match the theme of the collapsible header using the data-content-theme attribute.

    + -<div data-role="page" data-theme="a"> - +<div data-role="page" data-theme="a" data-content-theme="a"> + +

    Theming collapsible blocks

    To set the color of the collapsible header, add the data-theme attribute to the collapsible container. The icon and body are not currently themable through data attributes, but can be styled directly with custom css.

    @@ -44,6 +46,10 @@

    I'm an themed collapsible

    I have data-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    +

    I'm a themed collapsible with a themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +

    B theme swatch on content & collapsible

    @@ -54,6 +60,10 @@

    I'm an themed collapsible

    I have data-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    +

    I'm a themed collapsible with a themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +

    C theme swatch on content & collapsible

    @@ -64,6 +74,10 @@

    I'm an themed collapsible

    I have data-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    +

    I'm a themed collapsible with a themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +

    D theme swatch on content & collapsible

    @@ -74,6 +88,10 @@

    I'm an themed collapsible

    I have data-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    +

    I'm a themed collapsible with a themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +

    E theme swatch on content & collapsible

    @@ -84,6 +102,10 @@

    I'm an themed collapsible

    I have data-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    +

    I'm a themed collapsible with a themed content

    +

    I have data-content-theme attribute set manually on my container to set the color to match the content block I'm in.

    +
    diff --git a/js/jquery.mobile.collapsible.js b/js/jquery.mobile.collapsible.js index 0acc0c63..33e8fd18 100644 --- a/js/jquery.mobile.collapsible.js +++ b/js/jquery.mobile.collapsible.js @@ -13,6 +13,7 @@ $.widget( "mobile.collapsible", $.mobile.widget, { collapsed: true, heading: ">:header,>legend", theme: null, + contentTheme: null, iconTheme: "d", initSelector: ":jqmData(role='collapsible')" }, @@ -20,11 +21,11 @@ $.widget( "mobile.collapsible", $.mobile.widget, { var $el = this.element, o = this.options, - expandedCls = "ui-btn-up-" + (o.theme || "c"), collapsible = $el.addClass( "ui-collapsible" ), collapsibleHeading = $el.find( o.heading ).eq( 0 ), collapsibleContent = collapsible.wrapInner( "
    " ).find( ".ui-collapsible-content" ), - collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ); + collapsibleSet = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ), + colllapsiblesInSet = collapsibleSet.children( ":jqmData(role='collapsible')" ); // Replace collapsibleHeading if it's a legend if ( collapsibleHeading.is( "legend" ) ) { @@ -32,6 +33,20 @@ $.widget( "mobile.collapsible", $.mobile.widget, { collapsibleHeading.next().remove(); } + // If we are in a collapsible set + if ( collapsibleSet.length ) { + // Inherit the theme from collapsible-set + if ( !o.theme ) { + o.theme = collapsibleSet.jqmData( "theme" ); + } + // Inherit the content-theme from collapsible-set + if ( !o.contentTheme ) { + o.contentTheme = collapsibleSet.jqmData( "content-theme" ); + } + } + + collapsibleContent.addClass( ( o.contentTheme ) ? ( "ui-btn-up-" + o.contentTheme ) : ""); + collapsibleHeading //drop heading in before content .insertBefore( collapsibleContent ) @@ -47,21 +62,43 @@ $.widget( "mobile.collapsible", $.mobile.widget, { icon: "plus", theme: o.theme }) - .find( ".ui-icon" ) - .removeAttr( "class" ) - .buttonMarkup({ - shadow: true, - corners: true, - iconPos: "notext", - icon: "plus", - theme: o.iconTheme - }); - if ( !collapsibleParent.length ) { + if ( !collapsibleSet.length ) { collapsibleHeading .find( "a:eq(0), .ui-btn-inner" ) .addClass( "ui-corner-top ui-corner-bottom" ); } else { + // If we are in a collapsible set + + // Initialize the collapsible set if it's not already initialized + if ( !collapsibleSet.jqmData( "collapsiblebound" ) ) { + + collapsibleSet + .jqmData( "collapsiblebound", true ) + .bind( "expand", function( event ) { + + $( event.target ) + .closest( ".ui-collapsible" ) + .siblings( ".ui-collapsible" ) + .trigger( "collapse" ); + + }); + } + + colllapsiblesInSet.first() + .find( "a:eq(0)" ) + .addClass( "ui-corner-top" ) + .find( ".ui-btn-inner" ) + .addClass( "ui-corner-top" ); + + colllapsiblesInSet.last() + .jqmData( "collapsible-last", true ) + .find( "a:eq(0)" ) + .addClass( "ui-corner-bottom" ) + .find( ".ui-btn-inner" ) + .addClass( "ui-corner-bottom" ); + + if ( collapsible.jqmData( "collapsible-last" ) ) { collapsibleHeading .find( "a:eq(0), .ui-btn-inner" ) @@ -76,7 +113,9 @@ $.widget( "mobile.collapsible", $.mobile.widget, { event.preventDefault(); - var isCollapse = ( event.type === "collapse" ); + var $this = $( this ), + isCollapse = ( event.type === "collapse" ), + contentTheme = o.contentTheme; collapsibleHeading .toggleClass( "ui-collapsible-heading-collapsed", isCollapse) @@ -87,11 +126,10 @@ $.widget( "mobile.collapsible", $.mobile.widget, { .toggleClass( "ui-icon-minus", !isCollapse ) .toggleClass( "ui-icon-plus", isCollapse ); - collapsible.toggleClass( "ui-collapsible-collapsed", isCollapse ); + $this.toggleClass( "ui-collapsible-collapsed", isCollapse ); collapsibleContent.toggleClass( "ui-collapsible-content-collapsed", isCollapse ).attr( "aria-hidden", isCollapse ); - collapsibleContent.toggleClass( expandedCls, !isCollapse ); - if ( !collapsibleParent.length || collapsible.jqmData( "collapsible-last" ) ) { + if ( contentTheme && ( !collapsibleSet.length || collapsible.jqmData( "collapsible-last" ) ) ) { collapsibleHeading .find( "a:eq(0), .ui-btn-inner" ) .toggleClass( "ui-corner-bottom", isCollapse ); @@ -101,36 +139,6 @@ $.widget( "mobile.collapsible", $.mobile.widget, { }) .trigger( o.collapsed ? "collapse" : "expand" ); - // Close others in a set - if ( collapsibleParent.length && !collapsibleParent.jqmData( "collapsiblebound" ) ) { - - collapsibleParent - .jqmData( "collapsiblebound", true ) - .bind( "expand", function( event ) { - - $( event.target ) - .closest( ".ui-collapsible" ) - .siblings( ".ui-collapsible" ) - .trigger( "collapse" ); - - }); - - var set = collapsibleParent.children( ":jqmData(role='collapsible')" ); - - set.first() - .find( "a:eq(0)" ) - .addClass( "ui-corner-top" ) - .find( ".ui-btn-inner" ) - .addClass( "ui-corner-top" ); - - set.last() - .jqmData( "collapsible-last", true ) - .find( "a:eq(0)" ) - .addClass( "ui-corner-bottom" ) - .find( ".ui-btn-inner" ) - .addClass( "ui-corner-bottom" ); - } - collapsibleHeading .bind( "vclick", function( event ) { diff --git a/tests/unit/collapsible/collapsible_core.js b/tests/unit/collapsible/collapsible_core.js index 40db47fe..48907752 100644 --- a/tests/unit/collapsible/collapsible_core.js +++ b/tests/unit/collapsible/collapsible_core.js @@ -116,5 +116,50 @@ ]); }); + module( "Theming", {}); + + asyncTest( "Collapsible", 6, function(){ + $.testHelper.pageSequence([ + function(){ + $.testHelper.openPage( "#collapsible-with-theming" ); + }, + + function() { + var collapsibles = $.mobile.activePage.find( ".ui-collapsible" ); + ok( collapsibles.eq(0).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-a" ), "Heading of first collapsible should have class ui-btn-up-a"); + ok( !collapsibles.eq(0).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-a" ), "Content of first collapsible should NOT have class ui-btn-up-a"); + ok( collapsibles.eq(1).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-b" ), "Heading of second collapsible should have class ui-btn-up-b"); + ok( collapsibles.eq(1).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-b" ), "Content of second collapsible should have class ui-btn-up-b"); + ok( collapsibles.eq(2).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-c" ), "Heading of third collapsible should have class ui-btn-up-c"); + ok( collapsibles.eq(2).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-c" ), "Content of third collapsible should have class ui-btn-up-c"); + start(); + } + ]); + }); + + + asyncTest( "Collapsible Set", function(){ + $.testHelper.pageSequence([ + function(){ + $.testHelper.openPage( "#collapsible-set-with-theming" ); + }, + + function() { + var collapsibles = $.mobile.activePage.find( ".ui-collapsible" ); + ok( collapsibles.eq(0).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-a" ), "Heading of first collapsible should have class ui-btn-up-a"); + ok( !collapsibles.eq(0).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-a" ), "Content of first collapsible should NOT have class ui-btn-up-a"); + ok( collapsibles.eq(0).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-d" ), "Content of first collapsible should NOT have class ui-btn-up-d"); + ok( collapsibles.eq(1).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-b" ), "Heading of second collapsible should have class ui-btn-up-b"); + ok( collapsibles.eq(1).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-b" ), "Content of second collapsible should have class ui-btn-up-b"); + ok( collapsibles.eq(2).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-d" ), "Heading of third collapsible should have class ui-btn-up-d"); + ok( collapsibles.eq(2).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-d" ), "Content of third collapsible should have class ui-btn-up-d"); + ok( !collapsibles.eq(2).find( ".ui-collapsible-content" ).hasClass( "ui-collapsible-content-collapsed" ), "Content of third collapsible should NOT have class ui-collapsible-content-collapsed"); + ok( collapsibles.eq(3).find( ".ui-collapsible-heading-toggle" ).hasClass( "ui-btn-up-d" ), "Heading of fourth collapsible should have class ui-btn-up-d"); + ok( collapsibles.eq(3).find( ".ui-collapsible-content" ).hasClass( "ui-btn-up-d" ), "Content of fourth collapsible should have class ui-btn-up-d"); + start(); + } + ]); + }); + })( jQuery ); diff --git a/tests/unit/collapsible/index.html b/tests/unit/collapsible/index.html index 579b73b7..dbb46640 100644 --- a/tests/unit/collapsible/index.html +++ b/tests/unit/collapsible/index.html @@ -89,6 +89,75 @@ have the "collapsed" state; you need to expand the header to see me.

    + +
    +

    Section E

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    + + + +
    +
    +

    Themed collapsibles

    +
    +
    +
    +

    Section A

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +

    Section B

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +

    Section B

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    + +
    +
    + +
    +
    +

    Themed collapsibles

    +
    +
    +
    +
    +

    Section A

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +

    Section B

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +

    Section C

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +

    Section D

    + +

    I'm the collapsible content in a set so this feels like an accordion. I'm hidden by default because I + have the "collapsed" state; you need to expand the header to see me.

    +
    +
    +