Posts Tagged 'Plugin'

February 14, 2013

Tips and Tricks – Building a jQuery Plugin (Part 2)

jQuery plugins don't have to be complicated to create. If you've stumbled upon this blog in pursuit of a guide to show you how to make a jQuery plugin, you might not believe me ... It seems like there's a chasm between the "haves" of jQuery plugin developers and the "have nots" of future jQuery developers, and there aren't very many bridges to get from one side to the other. In Part 1 of our "Building a jQuery Plugin" series, we broke down how to build the basic structure of a plugin, and in this installment, we'll be adding some usable functionality to our plugin.

Let's start with the jQuery code block we created in Part 1:

(function($) {
    $.fn.slPlugin = function(options) {
            var defaults = {
                myVar: "This is", // this will be the default value of this var
                anotherVar: "our awesome",
                coolVar: "plugin!",
            };
            var options = $.extend(defaults, options);
            this.each(function() {
                ourString = myVar + " " + anotherVar + " " + coolVar;
            });
            return ourString;
    };
}) (jQuery);

We want our plugin to do a little more than return, "This is our awesome plugin!" so let's come up with some functionality to build. For this exercise, let's create a simple plugin that allows truncates a blob of text to a specified length while providing the user an option show/hide the rest of the text. Since the most common character length limitation on the Internet these days is Twitter's 140 characters, we'll use that mark in our example.

Taking what we know about the basic jQuery plugin structure, let's create the foundation for our new plugin — slPlugin2:

(function($) {
    $.fn.slPlugin2 = function(options) {
 
        var defaults = {
            length: 140,
            moreLink: "read more",
            lessLink: "collapse",
            trailingText: "..."
        };
 
        var options = $.extend(defaults, options);
    };
})(jQuery);

As you can see, we've established four default variables:

  • length: The length of the paragraph we want before we truncate the rest.
  • moreLength: What we append to the paragraph when it is truncated. This will be the link the user clicks to expand the rest of the text.
  • lessLink: What we append to the paragraph when it is expanded. This will be the link the user clicks to collapse the rest of the text.
  • trailingText: The typical ellipses to append to the truncation.

In our jQuery plugin example from Part 1, we started our function with this.each(function() {, and for this example, we're going to add a return for this to maintain chainability. By doing so, we're able to manipulate the segment with methods. For example, if we started our function with this.each(function() {, we'd call it with this line:

$('#ourParagraph').slPlugin2();

If we start the function with return this.each(function() {, we have the freedom to add further manipulation:

$('#ourParagraph').slPlugin2().bind();

With such a simple change, we're able to add method calls to make one massive dynamic function.

Let's flesh out the actual function a little more. We'll add a substantial bit of code in this step, but you should be able to follow along with the changes via the comments:

(function($) {
    $.fn.slPlugin2 = function(options) {
 
        var defaults = {
            length: 140, 
            moreLink: "read more",
            lessLink: "collapse",
            trailingText: "..."
        };
 
        var options = $.extend(defaults, options);
 
        // return this keyword for chainability
        return this.each(function() {
            var ourText = $(this);  // the element we want to manipulate
            var ourHtml = ourText.html(); //get the contents of ourText!
            // let's check if the contents are longer than we want
            if (ourHtml.length > options.length) {
                var truncSpot = ourHtml.indexOf(' ', options.length); // the location of the first space (so we don't truncate mid-word) where we will end our truncation.
 
   // make sure to ignore the first space IF the text starts with a space
   if (truncSpot != -1){
       // the part of the text that will not be truncated, starting from the beginning
       var firstText = ourHtml.substring(0, truncSpot);
 
       // the part of the text that will be truncated, minus the trailing space
       var secondText = ourHtml.substring(truncSpot, ourHtml.legnth -1);
                }
            }
        })
    };
})(jQuery);

Are you still with us? I know it seems like a lot to take in, but each piece is very straightforward. The firstText is the chunk of text that will be shown: The first 140 characters (or whatever length you define). The secondText is what will be truncated. We have two blobs of text, and now we need to make them work together:

(function($) {
    $.fn.slPlugin2 = function(options) {
 
        var defaults = {
            length: 140, 
            moreLink: "read more",
            lessLink: "read less",
            trailingText: "..."
        };
 
        var options = $.extend(defaults, options);
 
        // return this keyword for chainability
        return this.each(function() {
            var ourText = $(this);  // the element we want to manipulate
            var ourHtml = ourText.html(); //get the contents of ourText!
            // let's check if the contents are longer than we want
            if (ourHtml.length > options.length) {
                var truncSpot = ourHtml.indexOf(' ', options.length); // the location of the first space (so we don't truncate mid-word) where we will end our truncation.
 
   // make sure to ignore the first space IF the text starts with a space
   if (truncSpot != -1){
       // the part of the text that will not be truncated, starting from the beginning
       var firstText = ourHtml.substring(0, truncSpot);
 
       // the part of the text that will be truncated, minus the trailing space
       var secondText = ourHtml.substring(truncSpot, ourHtml.legnth -1);
 
       // perform our truncation on our container ourText, which is technically more of a "rewrite" of our paragraph, to our liking so we can modify how we please. It's basically saying: display the first blob then add our trailing text, then add our truncated part wrapped in span tags (to further modify)
       ourText.html(firstText + options.trailingText + '<span class="slPlugin2">' + secondText + '</span>');
 
       // but wait! The secondText isn't supposed to show until the user clicks "read more", right? Right! Hide it using the span tags we wrapped it in above.
       ourText.find('.slPlugin2').css("display", "none");
                }
            }
        })
    };
})(jQuery);

Our function now truncates text to the specified length, and we can call it from our page simply:

<script src="jquery.min.js"></script>
<script src="jquery.slPlugin2.js"></script>
<script type="text/javascript">
$(document).ready(function() {  
    $('#slText').slPlugin2();  
});
</script>

Out of all the ways to truncate text via jQuery, this has to be my favorite. It's feature-rich while still being fairly easy to understand. As you might have noticed, we haven't touched on the "read more" and "read less" links or the expanding/collapsing animations yet, but we'll be covering those in Part 3 of this series. Between now and when Part 3 is published, I challenge you to think up how you'd add those features to this plugin as homework.

-Cassandra

November 27, 2012

Tips and Tricks - Building a jQuery Plugin (Part 1)

I've written several blogs detailing the use of different jQuery plugins (like Select2, LazyLoad and equalHeights), and in the process, I've noticed an increasing frustration among the development community when it comes to building jQuery plugins. The resources and documentation I've found online have not as clear and easy as they could be, so in my next few posts, I'll break down the process to make jQuery plugin creation simple and straightforward. In this post, we'll cover the basic structure of a plugin and where to insert your own functionality, and in Part 2, we'll pick a simple task and add on to our already-made structure.

Before I go any further, it's probably important to address a question you might be asking yourself: "Why would I want to make my own plugin?" The best reason that comes to my mind is portability. If you've ever created a large-scale project, take a look back into your source code and note how many of the hundreds of lines of jQuery code you could put into a plugin to reuse on a different project. You probably invested a lot of time and energy into that code, so it doesn't make sense to reinvent the wheel if you ever need that functionality again. If that's not enough of a reason for you, I can also tell you that if you develop your own jQuery plugin, you'll level-up in cool points, and the jQuery community will love you.

For this post, let's create a jQuery plugin that simply returns, "This is our awesome plugin!" Our first step involves putting together the basic skeleton used by every plugin:

(function($) {
    $.fn.slPlugin = function() {
 
            // Awesome plugin stuff goes here
    };
}) (jQuery);

This is your template — your starting point. Practice it. Remember it. Love it. The "slPlugin" piece is what I chose to name this plugin. It's best to name your plugin something unique ... I always run a quick Google search to ensure I don't duplicate the name of a plugin I (or someone else) might need to use in a project alongside my plugin. In this case, we're calling the example plugin slPlugin because SoftLayer is awesome, and I like naming my plugins after awesome things. I'll save this code in a file called jquery.slPlugin.js.

Now that we have our plugin's skeleton, let's add some default values for variables:

(function($) {
    $.fn.slPlugin = function(options) {
            var defaults = {
                myVar: "default", // this will be the default value of this var
                anotherVar: 0,
                coolVar: "this is cool",                
            };
            var options = $.extend(defaults, options);
    };
}) (jQuery);

Let's look at the changes we made between the first example and this one. You'll notice that in our second line we added "options" to become $.fn.slPlugin = function(options) {. We do this because our function is now accepting arguments, and we need to let the function know that. The next difference you come across is the var defaults blurb. In this section, we're providing default values for our variables. If you don't define values for a given variable when you call the plugin, these default values will be used.

Now let's have our plugin return the message we want to send:

(function($) {
    $.fn.slPlugin = function(options) {
            var defaults = {
                myVar: "This is", // this will be the default value of this var
                anotherVar: "our awesome",
                coolVar: "plugin!",
            };
            var options = $.extend(defaults, options);
            this.each(function() {
                ourString = myVar + " " + anotherVar + " " + coolVar;
            });
            return ourString;
    };
}) (jQuery);

We've defined our default values for our variables, concatenated our variables and we've added a return under our variable declaration. If our jQuery plugin is included in a project and no values are provided for our variables, slPlugin will return, "This is our awesome plugin!"

It seems rather rudimentary at this point, but we have to crawl before we walk. This introductory post is laying the groundwork of coding a jQuery plugin, and we'll continue building on this example in the next installment of this series. As you've seen with the LazyLoad, equalHeights and Select2, there are much more complicated things we can do with our plugin, and we'll get there. Sneak Preview: In the next installment, we'll be creating and implementing a truncation function for our plugin ... Get excited!

-Cassandra

October 17, 2012

Tips and Tricks - jQuery Select2 Plugin

Web developers have the unique challenge of marrying coding logic and visual presentation to create an amazing user experience. Trying to find a balance between those two is pretty difficult, and it's easy to follow one or the other down the rabbit hole. What's a web developer to do?

I've always tried to go the "work smarter, not harder" route, and when it comes to balancing functionality and aesthetics, that usually means that I look around for plugins and open source projects that meet my needs. In the process of sprucing up an form, I came across jQuery Select2, and it quickly became one of my favorite plugins for form formatting. With minimal scripting and little modification, you get some pretty phenomenal results.

We've all encountered drop-down selection menus on web forms, and they usually look like this:

Option Select

Those basic drop-downs meet a developer's need for functionality, but they aren't winning any beauty pageants. Beyond the pure aesthetic concerns, when a menu contains dozens (or hundreds) of selectable options, it becomes a little unwieldy. That's why I was so excited to find Select2.

With Select2, you can turn the old, plain, boring-looking select boxes into beautiful, graceful and more-than-functional select widgets:

Pretty Option Select

Not only is the overall presentation of the data improved, Select2 also includes an auto-complete box. A user can narrow down the results quickly ad easily, and if you've got some of those endlessly scrolling select boxes of country names or currencies, your users will absolutely notice the change (and love you for it).

What's even sexier than the form facelift is that you can add the plugin to your form in a matter of minutes.

After we download Select2 and upload it to our box, we add our the jQuery library and scripts to the <head> of our document:

<script src="jquery.js" type="text/javascript"></script> 
<script src="select2.js" type="text/javascript"></script>

For the gorgeous styling, we'll also add Select2's included style sheet:

<link href="select2.css" rel="stylesheet"/>

Before we close our <head> tag, we invoke the Select2 function:

<script>
$(document).ready(function() { $("#selectPretty").select2(); });
</script>

At this point, Select2 is locked and load, and we just have to add the #selectPretty ID to the select element we want to improve:

<select id="selectPretty">
<option value="Option1">Option 1</option>
<option value="Option2">Option 2</option>
<option value="Option3">Option 3</option>
<option value="Option4">Option 4</option>
</select>

Notice: the selectPretty ID is what we defined when we invoked the Select2 function in our <head> tag.

With miniscule coding effort, we've made huge improvements to the presentation of our usually-boring select menu. It's so easy to implement that even the most black-and-white coding-minded web developers can add some pizzazz to their next form without having to get wrapped up in styling!

-Cassandra

September 26, 2012

Tips and Tricks - jQuery Lazy Load Plugin

In the late 90's, web pages presented their information in a relatively structured fashion, with little concern on how "pretty" the content looked. To a certain extent, that was a result of available technology and resources being a little more limited, but much of the reason was probably because we had no idea what was possible. We've come a long way, my friend. These days, it's tough to spend an hour online without coming across a gorgeous web site with huge animations, a pallet of every color possible, full-width backgrounds and high definition detail.

Those sites may be aesthetically pleasing, but they can be a big pain from a developer's perspective.

How much load does all of that stuff put on the server every time that web page is visited? As developers, it's our job to think about both what the visitor sees AND the visitor's experience in seeing it. Even the most beautiful sites will be ignored if a page takes too long to load. We spend hours optimizing every detail so users can fluidly browse without having to wait. It was in one of these optimization sessions that I discovered "lazy load."

To be honest, I wasn't too fond of the word "lazy" in the name, and I especially wasn't fond of having to explain to my boss that *I* wasn't being lazy ... The jQuery plugin is *named* "Lazy Load." Lazy Load effectively allows large pieces of content to stay in the backlog until they're needed. To give you an example of what that looks like, let's say you have a website with three humungous images, but they're all in different locations. Instead of pushing the entire load onto the user when they first land on your page, we can break them up and have them load only when the user goes to view them. We're not reducing the size of the web page; we're merely helping it work smarter.

Without Lazy Load, a normal web page loads each item when its page is visited. If a website has videos, music, images and some neat user interactivity applications, each of those items will load at the same time:

Lazy Load Illustration

If you take into consideration how large each of those items are, you can sense the problem. The user only has so much bandwidth to load these items, and something's gotta give. Usually, it means long loading times. We can't control how fast each user's ISP is, but we can reorder our items and let Lazy Load help us prioritize items and load the page more efficiently.

After we snag Lazy Load on Github (jquery.lazyload.js), we put our jQuery scripts in the <head> of our page:

<script src="jquery.js" type="text/javascript"></script> 
<script src="jquery.lazyload.js" type="text/javascript"></script>

Now that the plugin is available to us, we need to determine what we want to load lazily. Images are probably one of the most bothersome page elements, so let's apply Lazy Load to the images we load in the belazy class. In the <head> of your page (or in the footer if you prefer your JavaScript entries there), you'll add:

<script type="text/javascript">$("img.belazy").lazyload();</script>

As a result of that function, all image tags with a class of belazy will have Lazy Load run on them. This helps us ensure that we're not loading ALL of our images lazily. Now we need to choose which images we want to apply Lazy Load to.

Let's say the image tag of the largest image on one of our page looks like this:

<img src="bighonkingimage.png"/>

To have the lazyload function apply to it, we just have to make a couple tweaks:

<img class="belazy" src="bighonkingimage.png" data-original="bighonkingimage.png"/>

We added class="belazy" to trigger the lazyload function, and we added data-original="bighonkingimage.png" to line up with the formatting required by the newest version of Lazy Load (it's simply a repeat of the source).

When a user visits our page, bighonkingimage.png will load only when it's needed!

Pretty neat, eh?

-Cassandra

September 6, 2012

Tips and Tricks - jQuery equalHeights Plugin

Last month, I posted a blog about dynamically resizing divs with jQuery, and we received a lot of positive feedback about it. My quest to avoid iframes proved to be helpful, so I thought I'd share a few more esoteric jQuery tips and tricks that may be of use to the developers and designers in the audience. As I thought back about other challenges I've faced as a coder, a great example came to mind: Making divs equal height, regardless of the amount of content inside.

I haven't seen many elegant div-based solutions for that relatively simple (and common) task, so I've noticed that many people struggle with it. Often, developers will turn back to the "Dark Side" of using tables to format the content since all columns would have the same height as the tallest column by default:

JQuery Tutorial

It was easy theme table columns and to achieve the coveted 100% height that many designers seek, but emulating that functionality with divs proves to be much more difficult. A div is like the Superman of HTML elements (faster-loading, more flexible, more dynamic, etc.), and while it has super powers, it also has its own Kryptonite-like weaknesses ... The one relevant to this blog post being that floating three div elements next to each other isn't going to give you the look of a table:

JQuery Tutorial

Each of the three divs has its own height, so if you're doing something as simple as applying background colors, you're going to wind up with an aesthetically unpleasing result: It's going to look funky.

You could get into some nifty HTML/CSS workarounds, but many frustrated theme creators and designers will tell you that if your parent elements don't have a height of a 100%, you're just wasting coding lines. Some complex solutions create the illusion of all three divs being the same height (which is arguably better than setting fixed heights), but that complexity can be difficult to scale and repeat if you need to perform similar tasks throughout your site or your application. The easiest way to get the functionality you want and the simplicity you need: The jQuery equalHeights plugin!

With a few class declarations in your existing HTML, you get the results you want, and with equalHeights, you can also specify the minimum and maximum parameters so it will create scrollable divs if the tallest element happens to be higher than your specified maximum.

How to Use jQuery equalHeights

First and foremost, include your JQuery lirbraries in the <HEAD> of your document:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="jquery.equalheights.js"></script>

The equalHeights plugin is not a hosted library, so you have to host the file on your server (here's the link again).

With the required libraries called in our document, it's time to make the magic happen in your HTML.

Create Your Divs

<div class="divHeight">This DIV is medium sized, not too big and not too small, but just right.</div>
<div class="divHeight">This DIV has a lot of useful content and media that the user can interact with, thus it's very tall.</div>
<div class="divHeight">This DIV is tiny. Period.</div>

To have them line up next to each other, you'd have them float:left; in your CSS, and now you need to apply the equalHeights function.

Call the equalHeights Plugin
In order for the script to recognize the height of the tallest element, you'd need to call $(document).ready just before the </body> tag on your page. This will ensure that the page loads before the function runs.

The call looks like this:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights();
});</script>

If you want to specify a minimum and maximum (i.e. The div should be at least this tall and should be no taller than [adds scrollbar if the div size exceeds] the maximum), just add the parameters:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights(300, 600);
});</script>

The initial call does not change the appearance of the divs, but the time it takes to do the resizing is so miniscule that users will never notice. After that call is made and the height is returned, each div with the class of divHeight will inherit the the same height, and your divs will be nice and pretty:

JQuery Tutorial

This trick saved me a lot of headache and frustration, so hopefully it will do the same for you too!

-Cassandra

Subscribe to plugin