Creating a Plugin Using the Alsup Pattern - Exercise

Contact Us or call 1-877-932-8228
Creating a Plugin Using the Alsup Pattern - Exercise

Creating a Plugin Using the Alsup Pattern

Duration: 5 to 15 minutes.
  1. The exercise file jqy-plugins/Exercises/js/stripe.js contains a table-striping function Globals.stripe that will only stripe one level of table rows -- it will not descend into child tables. The file table.html contains a table with nested tables, and invokes the striping function separately for the outer and inner tables.
  2. Your job is to turn the stripe function into a plugin, $.fn.stripe, using the Alsup pattern (don't bother with the data support, though).
  3. The odd and even colors should now be options.
  4. Change the call to css after the second striping operation to be chained on after the striping, since our plugin should allow this.
  5. Right now, the plugin stripes all rows, regardless of what type of table section they are in. As a challenge, see if you can modify the plugin to have a default option of striping only the tbody, which can be overridden by the options object passed to the plugin to stripe all rows instead. Hint: the children function can take a query string, which can be used to filter the set of tags it returns.

Solution:

jqy-plugins/Solutions/tables.html
---- C O D E   O M I T T E D ----
<script>
$('.mostTables').stripe({ evenColor:'#ccddff', oddColor:'#aaaaaa' });

$('.innerfruits')
	.stripe({ evenColor:'#ffdd77' })
	.css( 'fontStyle', 'italic' );

$.fn.stripe.defaults = {
	evenColor:'#ffddff',
	oddColor:'#aaffaa'
};
$('table.little').stripe();
</script>
</body>
</html>

This is how we invoke the plugin.

Solution:

jqy-plugins/Solutions/js/stripe.js
(function($){
		
    $.fn.stripe = function(options) {	

		// override defaults with options
		var opts = $.extend({}, $.fn.stripe.defaults, options);

		// start with empty set
		var $tables = $()
			// add any tables that are direct entries in current collection
			.add(this.filter('table').get())
			// add ones that are descendants of entries in current collection
			.add(this.find('table').get());
		// now find any tables that are descendants of the tables we found
		var $omit = $tables.find('table');
		// and omit them from the collection
		$tables = $tables.not($omit);

		var oddColor = opts.oddColor ? opts.oddColor : null;
		var evenColor = opts.evenColor ? opts.evenColor : null;

		$tables.each(function() {
				// this finds only grandchildren (table -> table section -> tr)
				var $sections = $(this).children();
				if (oddColor) $sections.children('tr:odd')
					.css('backgroundColor', oddColor);
				if (evenColor) $sections.children('tr:even')
					.css('backgroundColor', evenColor);
		});
		return this;
	};

	$.fn.stripe.defaults = {
		evenColor: '#ddddff'
	}

}(jQuery));

The function has been stored in $.fn now, instead of our Globals object. Similarly, near the end, we store our default color in $.fn.stripe.

The first parameter has been removed, since that will now be the query upon which our plugin acts. Because of that, within the code, the $(query) has been replaced with this.

Before we start finding tables, we override the defaults with any incoming options.

To properly behave as a jQuery collection method, we return this at the end.

Challenge Solution:

jqy-plugins/Solutions/tables-challenge.html
---- C O D E   O M I T T E D ----
<script>
$('.mostTables')
	.stripe(
		{ evenColor:'#ccddff', oddColor:'#aaaaaa', tbodyOnly: false }
	);

$('.innerfruits')
	.stripe({ evenColor:'#ffdd77' })
	.css( 'fontStyle', 'italic' );

$.fn.stripe.defaults = {
	evenColor:'#ffddff',
	oddColor:'#aaffaa'
};
$('table.little').stripe();
</script>
</body>
</html>

This is how we invoke the plugin.

Challenge Solution:

jqy-plugins/Solutions/js/stripe-challenge.js
(function($){
	$.fn.stripe = function(options) {

		// override defaults with options
		var opts = $.extend({}, $.fn.stripe.defaults, options);

		// start with empty set
		var $tables = $()
			// add any tables that are direct entries in current collection
			.add(this.filter('table').get())
			// add ones that are descendants of entries in current collection
			.add(this.find('table').get());
		// now find any tables that are descendants of the tables we found
		var $omit = $tables.find('table');
		// and omit them from the collection
		$tables = $tables.not($omit);

		var oddColor = opts.oddColor ? opts.oddColor : null;
		var evenColor = opts.evenColor ? opts.evenColor : null;

		$tables.each(function() {
				// this finds only grandchildren (table -> table section -> tr)
				if (opts.tbodyOnly) var $sections = $(this).children('tbody');
				else var $sections = $(this).children();
				if (oddColor) $sections.children('tr:odd')
					.css('backgroundColor', oddColor);
				if (evenColor) $sections.children('tr:even')
					.css('backgroundColor', evenColor);
		});
		return this;
	};

	$.fn.stripe.defaults = {
		evenColor: '#ddddff',
		tbodyOnly: true
	}
}(jQuery));

We have added a tbodyOnly property to the defaults object. The code to find the tables' children has been split with a conditional to either filter with 'tbody' or not.

Next