diff --git a/js/jquery.mobile.controlGroup.js b/js/jquery.mobile.controlGroup.js
index 6a819c94cac..ac009a11e9b 100644
--- a/js/jquery.mobile.controlGroup.js
+++ b/js/jquery.mobile.controlGroup.js
@@ -5,38 +5,77 @@
* http://jquery.org/license
*/
(function($, undefined ) {
-$.fn.controlgroup = function(options){
-
- return this.each(function(){
- var o = $.extend({
- direction: $( this ).data( "type" ) || "vertical",
- shadow: false
- },options);
- var groupheading = $(this).find('>legend'),
- flCorners = o.direction == 'horizontal' ? ['ui-corner-left', 'ui-corner-right'] : ['ui-corner-top', 'ui-corner-bottom'],
- type = $(this).find('input:eq(0)').attr('type');
-
- //replace legend with more stylable replacement div
- if( groupheading.length ){
- $(this).wrapInner('
');
- $(''+ groupheading.html() +'
').insertBefore( $(this).children(0) );
- groupheading.remove();
- }
+ var corners = {
+ horizontal: ['ui-corner-left', 'ui-corner-right'],
+ vertical: ['ui-corner-top', 'ui-corner-bottom'],
+ };
+
+ var methods = {
+ init: function(options) {
+ return this.each(function(){
+ var el=$(this),
+ o = $.extend({
+ direction: el.data( "type" ) || "vertical",
+ shadow: false
+ },options),
+ flCorners = corners[o.direction],
+ groupheading = el.find('>legend');
+
+ //replace legend with more stylable replacement div
+ if( groupheading.length ){
+ // save this off for teardown so we can put back the original legend
+ el.data('groupheading',groupheading.clone())
+ .wrapInner('');
+ $(''+ groupheading.html() +'
').insertBefore(el.children(0));
+ groupheading.remove();
+ }
- $(this).addClass('ui-corner-all ui-controlgroup ui-controlgroup-'+o.direction);
-
- function flipClasses(els){
- els
- .removeClass('ui-btn-corner-all ui-shadow')
- .eq(0).addClass(flCorners[0])
- .end()
- .filter(':last').addClass(flCorners[1]).addClass('ui-controlgroup-last');
- }
- flipClasses($(this).find('.ui-btn'));
- flipClasses($(this).find('.ui-btn-inner'));
- if(o.shadow){
- $(this).addClass('ui-shadow');
- }
- });
-};
-})(jQuery);
\ No newline at end of file
+ el.addClass('ui-corner-all ui-controlgroup ui-controlgroup-'+o.direction);
+
+ flipClasses(el.find('.ui-btn'),flCorners);
+ flipClasses(el.find('.ui-btn-inner'),flCorners);
+ if(o.shadow){
+ el.addClass('ui-shadow');
+ }
+ });
+ },
+
+ refresh: function() {
+ methods.teardown.call(this);
+ return methods.init.call(this);
+ },
+
+ teardown: function() {
+ return this.each(function(){
+ var el=$(this);
+ el.removeClass('ui-controlgroup ui-controlgroup-horizontal ui-controlgroup-vertical');
+ el.find('.ui-btn,.ui-btn-inner').removeClass('ui-controlgroup-last ui-corner-left ui-corner-right ui-corner-top ui-corner-bottom');
+ var groupheading = el.data('groupheading');
+ if(groupheading){
+ var currControls = el.children().get(0);
+ groupheading.insertBefore(currControls);
+ $('.ui-controlgroup-label').remove();
+ $('.ui-controlgroup-controls').children().unwrap();
+ }
+ });
+ }
+ };
+
+ function flipClasses(els,flCorners){
+ els
+ .removeClass('ui-btn-corner-all ui-shadow')
+ .eq(0).addClass(flCorners[0])
+ .end()
+ .filter(':last').addClass(flCorners[1]).addClass('ui-controlgroup-last');
+ }
+
+ $.fn.controlgroup = function(method){
+ if ( methods[method] ) {
+ return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
+ } else if ( typeof method === 'object' || ! method ) {
+ return methods.init.apply( this, arguments );
+ } else {
+ $.error( 'Method ' + method + ' does not exist on jQuery.controlgroup' );
+ }
+ };
+})(jQuery);
diff --git a/tests/unit/controlgroup/controlgroup.js b/tests/unit/controlgroup/controlgroup.js
new file mode 100644
index 00000000000..c198553d432
--- /dev/null
+++ b/tests/unit/controlgroup/controlgroup.js
@@ -0,0 +1,151 @@
+/*
+ * mobile controlgroup unit tests
+ */
+(function($){
+ module('jquery.mobile.controlGroup.js');
+
+ var itemtemplate = 'Button
';
+
+ function createAppendItem(id) {
+ var item = $(itemtemplate);
+ if(id) {
+ item.attr('id',id);
+ }
+ item.appendTo($('[data-role=controlgroup]'));
+ return item;
+ }
+
+ test('controlgroup with no options creates vertical control group', function(){
+ var controlgroup = $('[data-role=controlgroup]');
+ controlgroup.controlgroup();
+
+ ok(controlgroup.hasClass('ui-controlgroup'), 'ui-controlgroup added');
+ ok(controlgroup.hasClass('ui-controlgroup-vertical'), 'ui-controlgroup-vertical added');
+ ok(!controlgroup.hasClass('ui-controlgroup-horizontal'), 'ui-controlgroup-horizontal not added');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('controlgroup.init with vertical direction', function(){
+ var controlgroup = $('[data-role=controlgroup]');
+ controlgroup.controlgroup({
+ direction: 'vertical'
+ });
+
+ ok(controlgroup.hasClass('ui-controlgroup'), 'ui-controlgroup added');
+ ok(controlgroup.hasClass('ui-controlgroup-vertical'), 'ui-controlgroup-vertical added');
+ ok(!controlgroup.hasClass('ui-controlgroup-horizontal'), 'ui-controlgroup-horizontal not added');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('controlgroup.init with horizontal direction', function(){
+ var controlgroup = $('[data-role=controlgroup]');
+ controlgroup.controlgroup({
+ direction: 'horizontal'
+ });
+
+ ok(controlgroup.hasClass('ui-controlgroup'), 'ui-controlgroup added');
+ ok(!controlgroup.hasClass('ui-controlgroup-vertical'), 'ui-controlgroup-vertical not added');
+ ok(controlgroup.hasClass('ui-controlgroup-horizontal'), 'ui-controlgroup-horizontal added');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('legend gets replaced', function(){
+ var controlgroup = $('[data-role=controlgroup]').empty().append($(''));
+ controlgroup.controlgroup();
+
+ equal(controlgroup.find('legend').length, 0, 'legend no longer there');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('controlgroup with one item', function(){
+ var controlgroup = $('[data-role=controlgroup]').empty();
+ var firstItem = createAppendItem();
+
+ controlgroup.controlgroup();
+
+ ok(firstItem.hasClass('ui-corner-top'), 'one item gets ui-corner-top');
+ ok(firstItem.hasClass('ui-corner-bottom'), 'one item gets ui-corner-bottom');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('controlgroup with multiple items', function(){
+ var controlgroup = $('[data-role=controlgroup]').empty();
+ var firstItem = createAppendItem();
+ var secondItem = createAppendItem()
+
+ controlgroup.controlgroup();
+
+ ok(firstItem.hasClass('ui-corner-top'), 'top item gets ui-corner-top');
+ ok(!firstItem.hasClass('ui-corner-bottom'), 'top item does not get ui-corner-bottom');
+
+ ok(!secondItem.hasClass('ui-corner-top'), 'bottom item gets ui-corner-top');
+ ok(secondItem.hasClass('ui-corner-bottom'), 'bottom item does not get ui-corner-bottom');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('controlgroup refresh', function(){
+ var controlgroup = $('[data-role=controlgroup]').empty();
+ var firstItem = createAppendItem();
+
+ var secondItem = createAppendItem();
+
+ controlgroup.controlgroup();
+
+ var thirdItem = createAppendItem();
+
+ // cause a refresh of everything.
+ controlgroup.controlgroup('refresh');
+
+ ok(firstItem.hasClass('ui-corner-top'), 'top item gets ui-corner-top');
+ ok(!secondItem.hasClass('ui-corner-top'), 'second item does not get ui-corner-top');
+ ok(!secondItem.hasClass('ui-corner-bottom'), 'third item does not get ui-corner-bottom');
+ ok(thirdItem.hasClass('ui-corner-bottom'), 'third item gets ui-corner-bottom');
+
+ controlgroup.controlgroup('teardown');
+ });
+
+ test('teardown removes all controlgroup stuff from vertical group', function(){
+ var controlgroup = $('[data-role=controlgroup]');
+
+ controlgroup.controlgroup();
+ controlgroup.controlgroup('teardown');
+
+ ok(!controlgroup.hasClass('ui-controlgroup'), 'teardown removes ui-controlgroup');
+ ok(!controlgroup.hasClass('ui-controlgroup-vertical'), 'teardown removes ui-controlgroup-vertical');
+ });
+
+ test('teardown puts the legend back in its place', function(){
+ var controlgroup = $('[data-role=controlgroup]').empty().append('');
+ createAppendItem('first');
+ createAppendItem('second');
+ createAppendItem('third');
+
+ controlgroup.controlgroup();
+ controlgroup.controlgroup('teardown');
+
+ equal(controlgroup.find('.ui-controlgroup-label').length, 0, 'ui-controlgroup-label is removed');
+ equal(controlgroup.find('.ui-controlgroup-controls').length, 0, 'ui-controlgroup-controls is removed');
+ equal(controlgroup.find('legend').length, 1, 'legend is put back');
+ equal(controlgroup.find('.ui-btn').length, 3, '3 buttons still exist');
+
+ });
+
+ test('teardown removes all controlgroup stuff from horizontal group', function(){
+ var controlgroup = $('[data-role=controlgroup]');
+ controlgroup.controlgroup({
+ direction: 'horizontal'
+ });
+
+ controlgroup.controlgroup('teardown');
+ ok(!controlgroup.hasClass('ui-controlgroup-horizontal'), 'teardown removes ui-controlgroup-horizontal');
+ });
+
+
+
+})(jQuery);
diff --git a/tests/unit/controlgroup/index.html b/tests/unit/controlgroup/index.html
new file mode 100644
index 00000000000..358fc2f5aad
--- /dev/null
+++ b/tests/unit/controlgroup/index.html
@@ -0,0 +1,32 @@
+
+
+
+
+ jQuery Mobile Navigation Test Suite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+