Slide 1

Slide 1 text

WRITING JQUERY PLUGINS DOUG NEINER WRITING JQUERY PLUGINS BEGINNER ADVANCED TO

Slide 2

Slide 2 text

WRITING JQUERY PLUGINS DOUG NEINER dougneiner [email protected] dcneiner Doug Neiner Doug Neiner

Slide 3

Slide 3 text

WRITING JQUERY PLUGINS DOUG NEINER I

Slide 4

Slide 4 text

WRITING JQUERY PLUGINS DOUG NEINER Crystal Ruby, Olivia, Cody Not pictured: Ditto the cat Jasper the dog My Family

Slide 5

Slide 5 text

WRITING JQUERY PLUGINS DOUG NEINER BASIC PLUGINS Lecture #1

Slide 6

Slide 6 text

WRITING JQUERY PLUGINS DOUG NEINER WHAT IS A JQUERY PLUGIN? • An awesome library approved by the jQuery team and used by millions? • Code you found useful and decided to release to the public? • Something other people write, and you use?

Slide 7

Slide 7 text

WRITING JQUERY PLUGINS DOUG NEINER WHAT IS A JQUERY PLUGIN? • A jQuery plugin is any reusable piece of JavaScript code that depends on jQuery. • Many jQuery plugins extend $.fn to provide functionality to jQuery result sets. • It is simply another method of code organization. • You should be writing and using your plugins in your projects now!

Slide 8

Slide 8 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 1: PROTECT THE $ // Out here, $ may not be equal to jQuery ( function ( $ ) { ! // In here, $ is equal to jQuery }( jQuery )); IIFE: IMMEDIATELY INVOKING FUNCTION EXPRESSION

Slide 9

Slide 9 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 2: ADD THE PLUGIN METHOD ( function ( $ ) { $.fn.myPlugin = function () { }; }( jQuery )); BE SURE TO PICK A UNIQUE NAME TO AVOID CONFLICTS

Slide 10

Slide 10 text

WRITING JQUERY PLUGINS DOUG NEINER JQUERY MAGIC • In order to run this: $( "div.findSomething" ).doSomething(); • This method would be defined: $.fn.doSomething • Its not magic, its the prototype of jQuery • $.fn is just an alias for the prototype

Slide 11

Slide 11 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 3: RETURN THIS ( function ( $ ) { $.fn.myPlugin = function () { ! return this.each( function ( i, el ) { ! }); }; }( jQuery )); CHAINING DEPENDS ON YOU HONORING THE SYSTEM

Slide 12

Slide 12 text

WRITING JQUERY PLUGINS DOUG NEINER MORE MAGIC: CHAINING • this is already a jQuery object • End the plugin by returning this to support chaining • 90% of the time, you want to support chaining • $( "#el" ).show().yourPlugin().delay( 900 ).slideUp(); • For the other 10%, there is only one situation where you shouldn't support chaining: • If your plugin method needs to return a value, it cannot chain

Slide 13

Slide 13 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 3A: ADD CODE ( function ( $ ) { $.fn.myPlugin = function () { ! return this.each( function ( i, el ) { ! ! // Your code goes here ! ! // this == el, so $( el ) to use jQuery methods ! ! $( el ).addClass( "button" ) ! ! .append( "" ); ! }); }; }( jQuery ));

Slide 14

Slide 14 text

WRITING JQUERY PLUGINS DOUG NEINER WAIT! EACH ISN'T ALWAYS NEEDED ( function ( $ ) { $.fn.myPlugin = function () { ! return this.addClass( "button" ) ! ! .append( "" ); }; }( jQuery )); IMPLICIT ITERATION IS RESPONSIBLE FOR THIS

Slide 15

Slide 15 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 3B: ADD MORE CODE ( function ( $ ) { $.fn.myPlugin = function () { ! return this.each( function ( i, el ) { ! ! var $el = $( el ); ! ! if ( !$el.hasClass( "button" ) { ! ! ! $el.addClass( "button" ) ! ! ! .append( "" ); ! ! } ! }); }; }( jQuery ));

Slide 16

Slide 16 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 4A: ADDING OPTIONS ( function ( $ ) { $.fn.myPlugin = function () { ! return this.each( function ( i, el ) { ! ! var $el = $( el ); ! ! if ( !$el.hasClass( "button" ) { ! ! ! $el.addClass( "button" ) ! ! ! .append( "" ); ! ! } ! }); }; $.fn.myPlugin.defaults = { ! buttonClass: "button", ! iconMarkup: "" }; }( jQuery ));

Slide 17

Slide 17 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 4B: MERGING OPTIONS ( function ( $ ) { $.fn.myPlugin = function ( options ) { ! options = $.extend( {}, $.fn.myPlugin.defaults, options ); ! return this.each( function ( i, el ) { ! ! var $el = $( el ); ! ! if ( !$el.hasClass( "button" ) { ! ! ! $el.addClass( "button" ) ! ! ! .append( "" ); ! ! } ! }); }; $.fn.myPlugin.defaults = { ! buttonClass: "button", ! iconMarkup: "" };

Slide 18

Slide 18 text

WRITING JQUERY PLUGINS DOUG NEINER STEP 4C: USING OPTIONS ( function ( $ ) { $.fn.myPlugin = function ( options ) { ! options = $.extend( {}, $.fn.myPlugin.defaults, options ); ! return this.each( function ( i, el ) { ! ! var $el = $( el ); ! ! if ( !$el.hasClass( options.buttonClass ) { ! ! ! $el.addClass( options.buttonClass ) ! ! ! .append( options.iconMarkup ); ! ! } ! }); }; $.fn.myPlugin.defaults = { ! buttonClass: "button", ! iconMarkup: "" }; }( jQuery ));

Slide 19

Slide 19 text

WRITING JQUERY PLUGINS DOUG NEINER BASIC PLUGIN REVIEW 1. Protect $ by wrapping the plugin in an IIFE 2. Add your method to $.fn 3. Be sure to return this 4. Add options to further abstract the code

Slide 20

Slide 20 text

WRITING JQUERY PLUGINS DOUG NEINER WHAT ABOUT $.EXTEND… // Some plugins use this form of adding to $.fn $.extend( $.fn, { myPlugin: function () { return this; } }); 1. Good if you plan to add a ton of plugin methods 2. Don't add a ton of plugin methods

Slide 21

Slide 21 text

WRITING JQUERY PLUGINS DOUG NEINER CRAFTING AN API // Though less common, some times adding additional // parameters (in addition to options) is a smart decision $.fn.myPlugin = function ( required, options ) { … }); $.fn.option = function ( key, value ) { … }); .option(); // Returns all the options (Breaks the chain) .option( key ); // Returns just the key (Breaks the chain) .option( key, value ); // Sets the value .option( { "key": val, "key2": val }); // Sets multiple values IN THE END, ITS UP TO YOU: BUT FOLLOWING CONVENTIONS MAKES IT EASIER TO RELEASE LATER

Slide 22

Slide 22 text

WRITING JQUERY PLUGINS DOUG NEINER BASIC PLUGINS Code Assignment #1

Slide 23

Slide 23 text

WRITING JQUERY PLUGINS DOUG NEINER WRITE A SIMPLE JQUERY PLUGIN • Ideas • Abstract a complex animation • Make a plugin that enhances markup for a form • Make a plugin that checks if a form is valid

Slide 24

Slide 24 text

WRITING JQUERY PLUGINS DOUG NEINER ( function ( $ ) { $.fn.myPlugin = function ( options ) { ! options = $.extend( {}, $.fn.myPlugin.defaults, options ); ! ! return this.each( function ( i, el ) { ! ! var $el = $( el ); ! ! if ( !$el.hasClass( options.buttonClass ) { ! ! ! $el.addClass( options.buttonClass ) ! ! ! .append( options.iconMarkup ); ! ! } ! }); }; $.fn.myPlugin.defaults = { ! buttonClass: "button", ! iconMarkup: "" }; }( jQuery ));

Slide 25

Slide 25 text

WRITING JQUERY PLUGINS DOUG NEINER EFFECTIVE OPTIONS Lecture #2

Slide 26

Slide 26 text

WRITING JQUERY PLUGINS DOUG NEINER VALUE OF A PLUGIN • A plugin is only as powerful as its API, and the options your support. • More options != more power • Too many options can bloat your plugin, so add them carefully and with a lot of thought.

Slide 27

Slide 27 text

WRITING JQUERY PLUGINS DOUG NEINER TYPES OF OPTIONS • Plain value options • Strings and Numbers • DOM Selection options • String selector, DOM object, jQuery Object • Callbacks • Fire after certain events • Rich Callbacks • The plugin depends on the callback for functionality

Slide 28

Slide 28 text

WRITING JQUERY PLUGINS DOUG NEINER PLAIN VALUE options = { animSpeed: 5000, // Defaults to 5 seconds defaultText: "RIA Unleashed is awesome!" } DEFAULT USE IN PLUGIN $( el ).slideDown( options.animSpeed, function () { this.innerHTML = options.defaultText; });

Slide 29

Slide 29 text

WRITING JQUERY PLUGINS DOUG NEINER DOM SELECTION defaults = { listItems: "ul li", listItems: liObj, listItems: $( "ul li" ) }; DEFAULT USE IN PLUGIN var items = options.listItems; if ( items && !items.jquery ) { items = $( items ); }

Slide 30

Slide 30 text

WRITING JQUERY PLUGINS DOUG NEINER CALLBACKS defaults = { onClick: null }; DEFAULT USE IN PLUGIN $( el ).click( function ( e ) { e.preventDefault(); // Do something if ( $.isFunction( options.onClick ) ) { options.onClick.apply( this, arguments ); } });

Slide 31

Slide 31 text

WRITING JQUERY PLUGINS DOUG NEINER CALLBACKS (ALT) defaults = { onClick: $.noop // $.noop == function () { } }; DEFAULT USE IN PLUGIN $( el ).click( function ( e ) { e.preventDefault(); // Do something options.onClick.apply( this, arguments ); });

Slide 32

Slide 32 text

WRITING JQUERY PLUGINS DOUG NEINER RICH CALLBACKS defaults = { renderItem: function ( text, type ) { return "" + text + ""; } }; DEFAULT USE IN PLUGIN $.each( keys, function ( key, text ) { var html = options.renderItem( item, key ); // Do something });

Slide 33

Slide 33 text

WRITING JQUERY PLUGINS DOUG NEINER WIDGETS Lecture #3

Slide 34

Slide 34 text

WRITING JQUERY PLUGINS DOUG NEINER LIMITATIONS OF BASIC PLUGINS • They don't maintain state very well • Very difficult to influence after the plugin has run • They don't tend to be able to be destroyed • They cannot be 'inherited' to adjust function

Slide 35

Slide 35 text

WRITING JQUERY PLUGINS DOUG NEINER THE WIDGET FACTORY • Part of jQuery UI: jquery.ui.widget.js • If you are using jQuery UI, you already can use it • Can be included in your own plugins (only 1.14KB minified and gzipped) for projects not use jQuery UI • Provides a rich API for stateful plugins (widgets) • Provides a unified API – allows users to use your plugin easier

Slide 36

Slide 36 text

WRITING JQUERY PLUGINS DOUG NEINER DEFINING A WIDGET $.widget( "namespace.pluginName", { options: { key: "value" }, … methods go here … });

Slide 37

Slide 37 text

WRITING JQUERY PLUGINS DOUG NEINER WHAT WE GET FOR FREE // Our widget object: $.namespace.pluginName; // A jQuery plugin for creating/interacting with our widget $.fn.pluginName; // A custom selector (Though use sparingly) $( ":namespace-pluginName" );

Slide 38

Slide 38 text

WRITING JQUERY PLUGINS DOUG NEINER THE WIDGET API // First call, with options, creates the widget $( "div" ).pluginName( { key: "value" } ); // Subsequent calls modify or call methods on the widget // Set an option $( "div" ).pluginName( "option", "key", "newValue" ); // Get an option $( "div" ).pluginName( "option", "key" ); // Run a method $( "div" ).pluginName( "myMethod", "parameter1" ); // Destroy the widget $( "div" ).pluginName( "destroy" );

Slide 39

Slide 39 text

WRITING JQUERY PLUGINS DOUG NEINER BASIC LIFE CYCLE • _create() • _init() • _setOptions & _setOption called as options are changed • destroy() Called directly or when element is removed

Slide 40

Slide 40 text

WRITING JQUERY PLUGINS DOUG NEINER SPECIAL PROPERTIES • this.element the jQuery wrapped DOM element the widget was created on. • this.options Allows you to quickly access the options on the widget • this.widgetName The "pluginName" portion of your widget • this.widgetEventPrefix Also the "pluginName" portion of your widget • this.widgetBaseClass "namespace-pluginName" - just like the declaration but with a dash instead of a dot.

Slide 41

Slide 41 text

WRITING JQUERY PLUGINS DOUG NEINER SETUP AND TEARDOWN $.widget( "namespace.pluginName", { options: { key: "value" }, // No "super" version of this worth calling _create: function () { this.element.addClass( this.widgetBaseClass ); }, … methods go here … destroy: function () { this.element.removeClass( this.widgetBaseClass ); $.Widget.prototype.destroy.apply( this, arguments ); } });

Slide 42

Slide 42 text

WRITING JQUERY PLUGINS DOUG NEINER CALLING "SUPER" // In jQuery UI 1.8.x, this is how you call a "super" method methodName: function () { $.Widget.prototype.methodName.apply( this, arguments ); }

Slide 43

Slide 43 text

WRITING JQUERY PLUGINS DOUG NEINER OPTIONS $( "div" ).pluginName( "option", hash OR key, value ); EVERY OPTION SHOULD BE CHANGEABLE AT RUN TIME _setOptions: function ( values ) { $.Widget.prototype._setOptions.apply( this, arguments ); // Do something once after options are set }, _setOption: function ( key, value ) { $.Widget.prototype._setOption.apply( this, arguments ); if ( key === "visible" ) { // Do something specific } }

Slide 44

Slide 44 text

WRITING JQUERY PLUGINS DOUG NEINER PUBLIC AND "PRIVATE" METHODS • Any method starting with an `_` underscore, cannot be called using the .pluginName( "method") syntax • Methods without an underscore can be called using that syntax

Slide 45

Slide 45 text

WRITING JQUERY PLUGINS DOUG NEINER EVENT BINDING this.element.bind( "click." + this.widgetName, function () { // Do something }); this.element.delegate( "ul li", "click." + this.widgetName, function () { // Do something }); this.element.bind( "click." + this.widgetName, function () { // Do something });

Slide 46

Slide 46 text

WRITING JQUERY PLUGINS DOUG NEINER WIDGETS I Code Assignment #2

Slide 47

Slide 47 text

WRITING JQUERY PLUGINS DOUG NEINER 50% complete Submit Question text here Yes No Question text here Yes No Question text here Yes No Question text here Yes No Question text here Yes No Question text here Yes No Question text here Yes No Question text here Yes No

Slide 48

Slide 48 text

WRITING JQUERY PLUGINS DOUG NEINER $.widget( "namespace.pluginName", { options: { key: "value" }, // No "super" version of this worth calling _create: function () { this.element.addClass( this.widgetBaseClass ); }, … methods go here … destroy: function () { this.element.removeClass( this.widgetBaseClass ); $.Widget.prototype.destroy.apply( this, arguments ); } });

Slide 49

Slide 49 text

WRITING JQUERY PLUGINS DOUG NEINER dougneiner [email protected] dcneiner Doug Neiner Doug Neiner