You Still Can't Create a jQuery Plugin
videos

You Still Can’t Create a jQuery Plugin?

It’s tough. You read tutorial after tutorial, but they all assume that you know more than you actually do. By the time you’re finished, you’re left feeling more confused than you initially were. Why did he create an empty object? What does it mean when you pass “options” as a parameter? What do “defaultsettings” actually do?

Never fear; I’m going to show you exactly how to build your own “tooltip” plugin, at the request of one of our loyal readers.

Why Would I Create a Plugin in the First Place?

It might help to think of plugins in the same way as you would functions. Have you ever found yourself repeating the same procedures
for site after site? Perhaps you’ve created your own tabbing system that you like to use. Rather than writing the same code time and
time again, wouldn’t it be easier if we could turn your long code block into one line? That’s essentially what a plugin does for us.
It allows for reusability, which is paramount – if you want to keep your hourly wage high!

Step 1: The Markup

Create a new project in your favorite code editor, and paste in the following html.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<link rel="stylesheet" href="css/default.css" />
	<title>You Still Can't Create a jQuery Plugin?</title>
</head>
<body>

<div id="container">
	<p>
		The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable <a href="#" class="tooltip" title="This is my title">English</a>. Many desktop publishing packages and web 
		page <a href="#">editors</a> now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. <a href="#">Various</a> versions have evolved <a href="#" class="tooltip" title="The other day, I bla bla with WordPress.">over the years</a>, sometimes by accident, sometimes on purpose (injected humour and the like).
	</p>	
</div><!--end container-->

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jQuery.tooltip.js"></script>

<script type="text/javascript">
	$('a.tooltip').tooltip({
		rounded: true
	});
</script>		

</body>
</html>

Explanation

This code is fairly simple; so it doesn’t require too much of an overview.

  • Reference a CSS file which we’ll create shortly. This will allow us to style our tooltip.
  • Add some generic text that contains a few anchor tags. Notice that some of them contain a class of “tooltip”.
    This is important!
  • Import jQuery from Google’s CDN.
  • Call our tooltip with jQuery. Don’t worry about this yet. I’ll explain it shortly.

Step 2: Calling the Plugin

I typically find that it’s easier to build my plugin if I first determine how I’m going to call it. Consider the following code.

<script type="text/javascript">
	$('a.tooltip').tooltip({
		rounded: true
	});
</script>

I’ve decided that I want the name of my plugin to simply be called “tooltip”. I’ve also determined that I want to be able to pass in a few
parameters in order to customize my tooltip slightly. This will purely be optional for the user though. If preferred, he or she could just type:

<script type="text/javascript">
	$('a.tooltip').tooltip();
</script>

In this instance, the default options will be used.

image

Step 3: Building the Plugin

image

So now that we know how the plugin will be called, let’s go ahead and build it! Create a new file in your project, and name it “jQuery.tooltip.js”. There are certain naming conventions when creating a plugin that will potentially be used by others. We begin by writing ‘jQuery’, followed by the name of our plugin. However, I’m sure that you realize that thousands of people have created their own tooltip plugin. You might determine that it’s necessary to preface “tooltip” with a unique string; perhaps your initials. In any event, it doesn’t matter too much. You’re free to name your plugin however you wish.

Passing jQuery as a Parameter

(function($){
  ...code
})(jQuery);

We must first ensure that the “$” symbol doesn’t get us into any trouble. What if we were also using other Javascript libraries in our application? Have you ever thought about that? In such cases, we would need to change every “$” in our document to “jQuery”. The only problem is that this is a rather sloppy solution. Instead, let’s create a self invoking anonymous function, and pass “$” as an alias. That way, we’re free to use “$” as much as we like without having to worry about any conflicts.

Naming the Plugin

$.fn.tooltip = function(options) {	

Within our wrap, we need to declare our new plugin and make it equal to the following function. We can accomplish this task by typing jQuery.fn (short for prototype).the name of our plugin.

Remember when I specified that the user should be able to make small modifications to the tooltip? Those modifications will be stored within the “options” parameter.

Setting the Defaults

var 
 defaults = {
	background : '#e3e3e3',
	color : 'black',
	rounded: false
},

It’s probable that the user might not specify any options. So, we’ll set our own “default” options. Because this is a tutorial for beginners, we won’t do too much here. Mostly, this is demonstrating what’s possible. We’re allowing the user to select a background color, color, and whether or not the tooltip is rounded.

Later in our code, when we wish to access these values, we can simply type: defaults.rounded.

Merging the Defaults With the Options

So how can we determine if the user adds his or her own options? The answer is that we must merge ‘defaults’ with ‘options’.

settings = $.extend({}, defaults, options);

We’ve created a new variable called “settings”, and have told jQuery to merge ‘defaults’, and ‘options’, and place the results into a new object. When merging, the user selected ‘options’ will take precedence over the defaults.
You might be wondering why I haven’t added “var” before settings. Technically, it’s not required, though it’s considered best practice. If you’ll scroll up a bit, you’ll see that after our defaults object, I added a comma. When doing so, we can continue creating more variables without the need for ‘var’ each time. For example…

var joe = {};
var is = {};
var good = {};

can become….

var joe = {},
    is = {},
	good = {};

For Each…

this.each(function() {
	var $this = $(this);
        var title = this.title;

It’s important to keep in mind that the wrapped set that the user passes to this plugin may contain many elements – not just one. We should make sure that we use a for each statement – or jQuery’s “each” method – to cycle through the code.

We begin our new function by caching $(this). Not only will it save us a few characters, but it will also speed things up, ever so slightly. It’s not required, but is considered to be good practice. Many people ask, “Why do you add the dollar sign in front of your variable?”. We do this to remind ourselves that we’re working with the jQuery object. By doing so, I remember that I can call things like: $this.click();. Next, I’m storing the value of the title attribute into a variable called “title”. You’ll see why we must do this in a moment.

Error Checking

if ($this.is('a') && $this.attr('title') != '') {
        this.title = '';
	$this.hover(function(e){

It’s easy to forget what $this is referring to. When you do forget, just go back to the way you’re calling the “tooltip” method.

$('a.tooltip').tooltip();

We can see here that $this is referring to each anchor tag that has a class of “tooltip”.

Back to the code; if the element in the wrapped set is, in fact, an anchor tag, AND its ‘title’ attribute is not empty, then run some code. This is rather self explanatory. I don’t want to run a bunch of code if the user accidentally passes in an image. Additionally, I don’t want to create my tooltip box if there isn’t anything to show!

Within my “if” statement, I’m setting the “title” attribute of the anchor tag equal to nothing. This will stop the browser’s default tooltip from loading. Next, I’m adding an event listener for when $this, or the anchor tag, is hovered over. When it is, we create a new function and pass the event object as a parameter. Don’t worry about this for now, I’ll explain later.

Creating Our Tooltip

image
var title = $this.attr('title');			
$('<div id="tooltip" />')
   .appendTo('body')
   .hide()
   .text(title)
   .css({
	 backgroundColor: settings.background,
	 color: settings.color,
	 top: e.pageY + 10,
	 left: e.pageX + 20
   })
   .fadeIn(350);

I’ve created a variable called ‘title’ and made it equal to whatever value is contained within the anchor tag’s ‘title’ attribute. This isn’t necessary really – but it helps me.

When we add html tags to our jQuery statement, we can actually create a new element, rather than retrieve one. We’re creating a new div tag with an id of ‘tooltip’. Next, we’ll use jQuery’s wonderful chaning abilities to perform a bunch of procedures with ease.

  • .appendTo(‘body’) : Take the element that we just created and append it to the body element, just before the closing ‘body’ tag.
  • .hide() : I want our tooltip to fade in. To achieve this effect, it must first have its display set to none.
  • .text(title) : We’ve created our div tag; but it’s still empty. Let’s add some text. We specify that whatever was contained in the title attribute should be placed into this div.
  • .css({..}) : We’re setting the background-color, color, top, and left positions of our tooltip with CSS. Remember earlier when we merged the default settings with the user’s selected options into a new ‘settings’ object? That will come into play now. The background-color is equal to ‘settings.background’; color is ‘settings.color’. Finally, we need to declare where on the page the tooltip should pop up. We can use the event object. It contains two properties called ‘pageY’, and ‘pageX’. These contain the values of the exact coordinates of where the anchor was hovered. To add a bit of padding, we’ll add 10px and 20px, respectively.
  • .fadeIn(350) : Over the course of about a third of a second, our tooltip will fade in.
if (defaults.rounded) {
	$('#tooltip').addClass('rounded');
}

By default, our ’rounded’ option is set to ‘false’. However, if ‘defaults.rounded’ returns true (meaning that the user added this parameter), we need to add a class of ’rounded’ to our CSS file. We’ll create that file soon.

Mouse Out

, function(){
	  // mouse out
	  $('#tooltip').hide();
  });

“Hover” accepts two functions: mouse over, and mouse out. We’ve added the appropriate code for when the user mouses over our selected anchor tag. But, we also need to write some code that removes the tooltip once the mouse has left the anchor tag.

Mouse Move

It would be nice to force the tooltip box to shift when our mouse moves. Let’s implement that quickly.

$this.mousemove(function(e) {
	$('#tooltip').css({
		top: e.pageY + 10,
		left: e.pageX + 20
	});		
});

When the mouse moves over the anchor tag, create a function and, once again, pass the event object as a parameter. Find the ‘tooltip’ element, and adjust its CSS. You should realize that it’s the exact code as we previously wrote. We’re simply resetting these values to the new ones. Nifty, eh?

Allow for Chaning

We must allow the user to continue chaining after he’s called “tooltip”. For example:

$('a.tooltip').tooltip().css(..).remove();

In order to allow for this chaining, we need to return ‘this’. Just before your closing curly brace, add “return this;”.

Plugin Complete!

You’ve just successfully created a fully working plugin. It’s not too advanced, but it allowed us to review some key features. Here is the final code.

Final jQuery

(function($){
	$.fn.tooltip = function(options) {
		
		var
		  defaults = {
		  	background: '#e3e3e3',
			color: 'black',
			rounded: false
		  },
		  settings = $.extend({}, defaults, options);
		  
		  this.each(function() {
		  	var $this = $(this);
			var title = this.title;
			
			if($this.is('a') && $this.attr('title') != '') {
				this.title = '';
				$this.hover(function(e) {
					// mouse over
					$('<div id="tooltip" />')
					  .appendTo('body')
					  .text(title)
					  .hide()
					  .css({
					  	backgroundColor: settings.background,
						color: settings.color,
						top: e.pageY + 10,
						left: e.pageX + 20
					  })
					  .fadeIn(350);
					  
				  if(settings.rounded) {
				  	$('#tooltip').addClass('rounded');
				  }
				}, function() {
					// mouse out
					$('#tooltip').remove();
				});	
			}
			
			$this.mousemove(function(e) {
				$('#tooltip').css({
					top: e.pageY + 10,
					left: e.pageX + 20
			     });
			});
		  });
		  // returns the jQuery object to allow for chainability.
		  return this;
	}
})(jQuery);
image

Step 4: CSS

image

The last step is to add just a bit of CSS to prettify our tooltip. Create a new CSS file called ‘default.css’, and paste the following in.

#tooltip {
	background: #e3e3e3 url(../images/search.png) no-repeat 5px 50%;
	border: 1px solid #BFBFBF;
	float: left;
	font-size: 12px;
	max-width: 160px;
	padding: 1em 1em 1em 3em;
	position: absolute;
}

.rounded {
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
}

Nothing too complicated here. I’m referencing a background image that contains the standard ‘search’ magnifying glass. You’re welcome to download the source code to use it. Additionally, I’ve added a bit of padding, a maximum width, and a font-size. Most of this comes down to preference. You’re free to edit it however you wish.

The only vital property is “position: absolute;”. Earlier, we set the “top” and “left” values with jQuery. In order for that positioning to take effect, we must set the position to absolute! This is important. If you don’t do so, it won’t work.

Thanks for Reading

To all those who have emailed me asking for this tutorial, I hope it’s helped in some way. If I didn’t explain myself well enough, be sure to view the associated screencast, and/or ask a comment. I’ll try to help you to the best of my ability. Until next time…

Ready For Level 2?

If you have a solid grasp of the techniques presented in this tutorial, you’re ready to move on! Consider signing up for a Net Plus membership to view an advanced tutorial, by Dan Wellman, that will teach you how to build a more complicated jQuery plugin. It also comes with an associated screencast. Be sure to sign up now!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Tags: Videos
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://blog.insicdesigns.com insic

    now i can create a jQuery Plugin Thanks for this tutorial. really helpful

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    I can always rely on insic.

  • Patrick

    Really, you can insic? For me – i can’t. But this tutorial helps a lot to understand and learn how jquery works :P

    thx, Jeffrey!

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Patrick – Was just a joke. :)

  • Patrick

    I know :D ;)

  • http://www.greeksgobald.com Brad

    Jeffery Way is my hero.

  • visual

    Nice tutorial. Now a days I really feel sorry for the Prototype+Scriptaculous frameworks. So many articles are coming out about jQuery, too few for the other frameworks. Of course jQuery rocks, but I still like prototype :-).

    And regarding the on going joke everybody can rely on a chick (sic)… Don’t mind people, again a joke only.

  • Meshach

    Hey, thanks very much Jeffrey!

  • http://www.instantshift.com DKumar M.

    Same and Same thing again again!!

  • Jonathan

    Rock on, Jeffrey! Very interesting tutorial.

  • http://www.boxxdesign.co.uk William Monk

    Great tutorial, easy to understand with a good outcome. Thanks a lot!

  • Phillip Raffnsøe

    Thanks for yet another brilliant screencast Jeff! After about a year of leeching these free tuts, I’ve decided to subscribe to plus. I know it’s worth it, especially now when all tuts+ are included.

    So you should see another subscriber in the following days! Thanks for convincing me! An thanks for learning me jQuery, I use it pretty much every day.

  • http://eduplessis.com Eduplessis

    nice tut….. gonna make a lot of plugin now…

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Phillip – Very happy to hear that. It’s 100% worth the investment. Just go out to lunch one less time every month. :)

  • http://www.brenelz.com/blog Brenelz

    Great screencast Jeffery… between the imgPreview, jPoll, and tooltip plugins I should know how to make one of my own.

    One question I have is could not do this:

    var title = $this.attr(‘title’);
    if($this.is(‘a’) && title != ”) { }

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Brenelz – What is your question again?

  • Pingback: You Still Can’t Create a jQuery Plugin? - NETTUTS - Illuminations

  • http://ivorpadilla.com iPad

    Thanks Jeffrey, I decided to subscribe to Plus too, this is quality partners…! Your tutorials are my favorites for sure.

  • http://www.brenelz.com/blog Brenelz

    Oops… What I meant to say was could you not do this:

    var title = $this.attr(’title’);
    if($this.is(’a’) && title != ”) { }

    instead of:

    var title = this.title;
    if($this.is(‘a’) && $this.attr(‘title’) != ”) {}

  • Doug

    Thanks for the tutorial!

    This should help me create stuff for my projects.

  • http://another-perfect-world.org/ Vasili

    This is very helpful. Do you mind telling me the difference between this and $this (ie $(this))? That’s what always confuses me.

    I loved the pizza reference. :P

  • Pingback: Howto: Create a jQuery Plugin | blog.paulgueller.com

  • Yosy

    Thank you Jeffrey,
    There is one problem on creating jQuery Plugin,I don’t have idea for which plugin to create.

    By The Way,How You changed the theme of the aptana?and what is the name of this theme?

    And how you’re deleting the tab?for example-
    from this-
    Yosy
    To This-
    Yosy

    And I think I will register to the plus membership for more awesome tutorials :)

  • http://www.patternhead.com Patternhead

    I guess this helps clear a few things up for some folks.

    Nice job.

  • http://shinokada.blogspot.com/ shin

    Here is another tut from IBM. “Working with jQuery, Part 1: Plug-ins to create/extend jQuery functions” Michael Abernethy. http://bit.ly/mEU82

  • http://jayj.dk Jay

    Thanks for this screencast?

    Can you tell a bit about that Dan Wellman will teach in the more advanced tutorial? Because I consider seriously becoming “Plus”

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Yosy – Email me at nettutsblog@gmail.com and I’ll send you the Aptana theme.

  • Erik Zettersten

    Price of a pizza (=

  • http://another-perfect-world.org/ Vasili

    Hey Jeff, I was recreated this (so see if I could do it without looking back), and realized something. In the screencast, you use .hide() instead of .remove(). When you do this, you’re adding div upon div upon div to the body and they just stay there, hidden. .remove() is the way to do. ;)

  • http://tapocol.com Craig

    Great Tutorial. If anyone is interested in a tutorial on extending already-made plugins in jQuery. Check out my tutorial: http://www.tapocol.com/2008/12/11/simple-add-on-to-the-jquery-ui-draggable-widget

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Vasili – Yeah. I realized that too after recording the screencast! To all those reading this, don’t use “hide()” when mousing off the anchor tag. I should have stuck with my gut. That’s why the source code doesn’t reflect it!

    Thanks for bringing this to everyone’s attention, Vasili! :)

  • http://chrisgunther.net Chris Gunther

    Nice tutorials. Covers all the basics and doesn’t leave anything unexplained.

  • http://www.altograu.eu/portfolio/ Sérgio Soares

    thanks jeffrey

  • http://www.weloveberlin.fr John

    Really useful tutorial, many thanks Jeffrey !

  • Steve Jobs

    That insic girl (or guy) just happened to find everything useful

  • Pingback: Daily Links | AndySowards.com :: Professional Web Design, Development, Programming, Hacks, Downloads, Math and being a Web 2.0 Hipster?

  • http://greenflipflops.com Gabe

    Man, you made it so a dummy like me could follow along. Many thanks, I can’t wait to build my own! For some reason the word “plugin” carries this mysticism that is completely irrational – like it’s magic or voodoo. If I just think of it as an “include” or an external file, I feel less intimidated. Great work, Jeff.

  • http://www.konspiredesign.com Vasily

    Fantastic, I did this and it works wonderfully! Thank you.
    Good point on the price of pizza, I’ve just ordered one and I think I am going to go ahead and sign up for the Tuts+.

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Gabe – Exactly. It sounds much harder than it really is.

    @Vasily – Really happy to hear that. You won’t regret it…and you’ll be helping us out a great deal. Thank you!

  • http://www.bradenkeith.com Braden Keith

    Thank you for this. Very helpful in clearing some things up.

  • http://yoosuf.awardspace.com/ M.A.Yoosuf

    thank you jeff, you continue without the Pro version, till i subscribe , because hopefully EOM i will.

  • http://www.zairabbas.com Zair Abbas

    cool! this will surely gonna help!
    thanks

  • Per Ulv

    This is great

  • http://67ideas.com Jack Hoge

    Hey Jeffrey,

    In your jQuery for Beginners tutorial on Themeforest, didn’t you say you hated Aptana’s habits? :-) What changed your mind?

    Good tutorial, should save people a solid chunk of time.

  • chris berthe

    Great, thank you!

  • http://clhmedia.com clhmedia

    awesome stuff, will have to review this over the weekend

  • jem

    Another great tutorial!

    I’m starting to wonder if Jon Resig isn’t slipping Nettuts a little money under the table! I can’t recall the last time anything got posted using another framework… or are people just not sending them in!

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Jack – Good memory! A few weeks ago, I gave it another chance. I quite like it now! It’s very powerful.

  • http://apertaholic.com aperta

    Simple and Evective … Thanks

  • http://themeforest.net/user/JeffreyWay Jeffrey Way
    Author

    @Jem – 95% of the framework tutorials we receive are jQuery. The other 5% are for Mootools. Nothing else.