From d3348596a77f9e34b80f72b300ced4d5650eb159 Mon Sep 17 00:00:00 2001 From: Shane Tomlinson Date: Thu, 10 Feb 2011 12:13:13 +0000 Subject: [PATCH 1/2] Adding the ability to refresh a control group - useful for when new buttons are added after initial render --- js/jquery.mobile.controlGroup.js | 88 ++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/js/jquery.mobile.controlGroup.js b/js/jquery.mobile.controlGroup.js index 6a819c94cac..26b0d9ee5c5 100644 --- a/js/jquery.mobile.controlGroup.js +++ b/js/jquery.mobile.controlGroup.js @@ -5,38 +5,58 @@ * 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 methods = { + init: function() { + 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(); + } - $(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 + $(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'); + } + }); + }, + + refresh: function() { + this.each(function(){ + $(this).removeClass('ui-controlgroup-horizontal ui-controlgroup-vertical'); + $(this).find('.ui-btn,.ui-btn-inner').removeClass('ui-controlgroup-last ui-corner-left ui-corner-right ui-corner-top ui-corner-bottom'); + }); + + return methods.init.call(this); + } + }; + + $.fn.controlgroup = function(options){ + 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); From 05fe3d2c8c690935decd1b2fe30e84d305518309 Mon Sep 17 00:00:00 2001 From: Shane Tomlinson Date: Thu, 10 Feb 2011 15:21:19 +0000 Subject: [PATCH 2/2] Updating controlgroup so that it can be refreshed when new items are added and torndown. Adding unit tests. --- js/jquery.mobile.controlGroup.js | 73 +++++++----- tests/unit/controlgroup/controlgroup.js | 151 ++++++++++++++++++++++++ tests/unit/controlgroup/index.html | 32 +++++ 3 files changed, 229 insertions(+), 27 deletions(-) create mode 100644 tests/unit/controlgroup/controlgroup.js create mode 100644 tests/unit/controlgroup/index.html diff --git a/js/jquery.mobile.controlGroup.js b/js/jquery.mobile.controlGroup.js index 26b0d9ee5c5..ac009a11e9b 100644 --- a/js/jquery.mobile.controlGroup.js +++ b/js/jquery.mobile.controlGroup.js @@ -5,52 +5,71 @@ * http://jquery.org/license */ (function($, undefined ) { + var corners = { + horizontal: ['ui-corner-left', 'ui-corner-right'], + vertical: ['ui-corner-top', 'ui-corner-bottom'], + }; + var methods = { - init: function() { + init: function(options) { return this.each(function(){ - var o = $.extend({ - direction: $( this ).data( "type" ) || "vertical", + var el=$(this), + o = $.extend({ + direction: el.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'); + },options), + flCorners = corners[o.direction], + groupheading = el.find('>legend'); //replace legend with more stylable replacement div if( groupheading.length ){ - $(this).wrapInner('
'); - $('
'+ groupheading.html() +'
').insertBefore( $(this).children(0) ); - groupheading.remove(); + // 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); + el.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')); + flipClasses(el.find('.ui-btn'),flCorners); + flipClasses(el.find('.ui-btn-inner'),flCorners); if(o.shadow){ - $(this).addClass('ui-shadow'); + el.addClass('ui-shadow'); } }); }, refresh: function() { - this.each(function(){ - $(this).removeClass('ui-controlgroup-horizontal ui-controlgroup-vertical'); - $(this).find('.ui-btn,.ui-btn-inner').removeClass('ui-controlgroup-last ui-corner-left ui-corner-right ui-corner-top ui-corner-bottom'); - }); - + 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(options){ + $.fn.controlgroup = function(method){ if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { 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($('A Legend')); + 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('A Legend'); + 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 + + + + + + + + + + + + + + + +

jQuery Mobile Controlgroup Test Suite

+

+

+
    +
+ +
+ My Legend +
+ + +