Posted 11.29.2009

Leveraging Your Life via Social Media



Three weeks ago, I went on the YOUNG ADULT fall retreat (not to be confused with the Singles Retreat *GRIN*) at church. The theme for the weekend was “Trust + Obey = Leverage.” Aaron Bryant asked me to lead a break out group on Saturday morning about practical ways to leverage your life using Social Media.

I had a lot of fun reading up and learned quite a bit in the process. — Thought I would share:

A quick side note:
I tried posting these slides via Slideshare. However, there isn’t a way (at least I don’t know of one) to share some of my notes.


This was the description that I wrote to describe the breakout. At the end, I wanted people to be able to say “this is what I learned.”

If technology is an extension of who we are, and we are made in God’s image, then technology is also an extension of who God is, as well. We will dig into what this means for us and for the church, how it shapes our beliefs, how we should respond appropriately, and how we can be good stewards.




When I’m going through Social Media stuff. I think of a couple of verses. Matthew 10:16 is one of them. I believe it is a calling to step out of ignorance and be knowledgeable of the world around us. Social media is no exception.




John 17:6-9 is another passage. Here, Jesus is praying in the Garden of Gethsemane for his disciples. He prays that they would be in the world but not of the world.

What does that even mean? –Well, a few years ago, I read a good called Too Christian, Too Pagan.. In it, the author talks about how Jesus hung out with sinners and tax collectors, a.k.a. the untouchables of society. He was too Christian for them. On the flip side, he was too pagan for the Pharisees, the religious leaders of the day. He walked a fine line.

That verse is a call for us to step off our high horses, as believers, and get our hands dirty. We are far from perfect! But, it’s also about rising above the crap that pollutes our world. We were meant for more…so much more!

*jumping off that soap box*







The hard part about preparing for this breakout group was the audience. Usually when I’m talking about Facebook or Twitter, I’m teaching people that don’t have a clue what the tools are or how to use them. OR I’m talking to geeks like me, that love all the bells and whistles, features, tips, and tricks. This audience doesn’t fit into either category. Most of them, they know what Facebook is. I’m friends with most of them! Twitter might be a little harder, but they have a basic understanding…



So, diving in.

Historically, websites provide us with information. That’s been their primary purpose. Take CNN.com. It’s one news source telling thousands information: one to many.

However, with blogs and other sources, the lines of communication have been opened. All the sudden, we, as users can respond. We can share our thoughts, feelings, feedback: many to one. We’ve been given a voice.

But, let’s take that a step further. It’s not just about us talking back to, say CNN.com. Suddenly, we can talk to other people about what we’re reading: many to many. It’s now a conversation.

Then, viral comes into play. We can turn around and share with our friends, that don’t have a clue, what news we’re reading (still many to many).

With social media, we’ve expanding the conversation 3 more times!

So what do we do with all this information? By itself, it is strength without coordination. That’s where understanding comes into play. Understanding is the ability to coordinate that information in meaningful ways. Then, wisdom is becoming comfortable in that understanding. — knowing how, when, and why we use understanding.





OK so: What does this means for us and for the church and how does it shapes our beliefs?



Well…. when I was in college and taking mass communication classes. We studied a guy named, Marshall McCluhan. It’s cool, now, to see his name resurface and to have a better understanding of how he fits into this overall picture. His big thing was “The message is the medium.”

I don’t know about you, but that statement is makes my brain short circuit. How does a movie tell one message in the movie theater and a completely different one on a DVD in the comfort of my own home? It’s the same content!

The best example I can think of is a thank you note. You do something and I want to express my appreciation. I could sit down at my computer and type a quick email. OR I could pull out a card. Old fashioned, I know. Write out the same message that I would have emailed you, stick a stamp on it, and a few days later, you’ll get it. It’s the same content, but the message is different. With an email, you’d probably say, “Oh, that was nice.” But, a card… You’d say, “That was really thoughtful of her. It was nice of her to take the time to do that.” Nobody sends cards anymore. So, when someone does, it carries a lot more weight. The medium is the message.





Here’s another example. The words “Sad Child.” OK. Sad child.



BUT, if I show you a picture of a sad child. Well, that carries a lot more weight. We respond emotionally. Our left brain processes the words, “sad child.” It is analytical, logical. Our right brain, processes images and emotion. Suddenly, we feel something for this sad child; we feel compassion.





So, when we look at how the medium effects us, as Christians, it’s not really any different.

In the Old Testament, there are pages of specifications for how the Ark of the Covenant should be built, how it should be carried, etc. It might be boring to us. But, it’s part of God’s message. It’s tells us that this was incredibly important, because it carried His Word (the 10 Commandments).

Look at how God chose to demonstrate His love to us: by sending His only Son as an infant. Not only that, but He died for us! To me, that’s more than anything I could ask. It’s the ultimate demonstration of love.

Let’s keep taking this a step further. The message changes with time and culture. I know that makes a lot of people feel uncomfortable when it comes to the Bible. If God is unchanging, if He is the same yesterday, today, and tomorrow, how can His Word change?

In Exodus, in the Old Testament, when they were getting ready to cross the Red Sea, it was a message of calling His people to the Promised the Land.

In Jeremiah (still Old Testament), when the people were in captivity, it was a message of, “I have a plan for you. Plans to prosper and not to harm you. Plans to give you a hope and a future.”

Even today, the message changes. If I went to a 3rd world country, full of corruption and hunger, and told them that Jesus can rescue them from their poverty and oppression. That’s Good News! But, if I go to my neighbors, who live in one of the 10th wealthiest counties in the country and told them that God can rescue them from their poverty and oppression…well…they would look at me like I was crazy. I’d probably get a door or two slammed in my face and small children would be told to cross the street when they saw me coming. On the flip side, if I told my neighbors that God wants to save them from their personal affliction, from their struggles and failures with relationships, etc. –well, that carries a lot more weight. Same God. Different message.

Let’s keep pushing this. In Paul’s letters, he talks about how we are the Body of Christ. Most of the time, we read this and immediately think about unity. We’re all supposed to work together. Yes, that’s true. But, there’s more. As believers, we partner with God to share with others. That’s His expansion plan. Us. I’ll be the first to admit, the church doesn’t always do a good job. A lot of us, that have reached that conclusion will back away from the Church, ashamed by it’s flaws. I’ll apologize, but I won’t back down. This is the medium that God chose to communicate his message. Mistakes and all. I don’t know about you, but it makes me think about the Body of Christ differently.





How should we respond appropriately?




Understand that virtual community is….virtual.

I attend Kairos. However, on a busy week, I might tell myself, “It’s OK, I can skip and just catch it on the podcast.” The thing is, it’s not the same. I miss the the conversations that happen. I miss the community. There’s a lot to be said for just showing up and being there in person. However, this isn’t the only thing that we allow a virtual community, the perception of community, to replace the real deal. This is just one example.





A study was done that showed negotiations done via email were far more likely to break down than those that were handled over the phone or in person.

I think we avoid face-to-face because we fear confrontation. I know I do! But the problem is there is so much more room left for misinterpretation. We miss body language, voice intonation, and facial expressions. We’re just asking for a miscommunication!

I’m learning to accept conflict. To be human is to be in conflict. People are messy! But, if we recognize that and understand that the way we disagree sends a message.

So how do we respond appropriately? Take some initiative! Go directly to the other person. Have an attitude of humility. Be quick to listen. Slow to speak. (Hmmm…sounds a lot like the Sermon on the Mount in Matthew…)





The next question, then: how can we be good stewards?




I’m learning more and more, consistency is the key. I want to be the same person online as I am in real life. I want to be the same person at work that I am at home. I want the things that I say to line up with my behavior.



There are 4 people that I blog / twitter for. Whenever, I post something, I always try to think about how they will respond.

The first two are co-workers from my previous job. One’s a graphic designer and the other is a branding guru. When I write, I wonder, will they be annoyed by this Twitter or will it make them chuckle. Is this post going to get under their skin? And if so, am I OK what that?

Third, my current boss. I’m never going to write anything negative about the work I’m currently doing or my company.

Fourth, my Dad. I want to make sure that my posts honor my family and the way I’ve been raised. Knowing that he pays attention to what I do online comes with a level of accountability.





One of the things that I think we’ll become a growing issue for my / our generation is privacy. I remember when I was 13 and AOL chat rooms were popular. grin Everyone made a big deal about what you shared. I was told, “NEVER share personal information!” Whatever happened to that? Just look at Facebook!
Recently, Google released Google Dashboard. It tells you all the information that they have collected on you. It’s kind of scary, actually.

  • Google Calendar – They know what I’m doing, when I’m doing it.
  • Contacts – They know who my friends are and how to get in touch with them
  • Google Docs – they know what I’m working on
  • Gmail – they know who I’m Emailing, what I’m talking about, what I’m interested in.
  • Google Reader – they know what I’m paying attention to, who I’m listening to
  • Web History – they know what sites I’m visiting
  • YouTube – they know what I’m watching.

And I don’t even use all the products that Google offers. What about Orkout? — It’s a site similar to Facebook, popular in other countries. Or Picassa? Blogger? Tasks? Google Voice?

It’s easy for me to look at these things and think, “You know, I have nothing to hide. What difference does it make whether they have this information on me?” What we forget is that yes, big brother might be watching us, but little brother, the marketer is also watching. I wonder when the day will come when we’ll pay just to be left alone. Give us some peace and quiet!








Something else we forget? Once it’s posted, it may never go away.

If you go to Google.com and search “cache:name_a_site.com. In my example, I searched for my site: cache:amyhaywood.com. What comes up is an older version of my site. Google will periodically crawl through the web taking snapshots (cache) of sites. My site doesn’t look like this now. I’ve updated it since then.

Before we go and get our underwear in a knot, let me explain why: it speeds up performance on their end. Eventually, their cache will update. But, still… I could delete something and it would still be available through Google Cache for weeks.









Archive.org is another example. A quick search, (again) for amyhaywood.com, reveals the history of my site, dating back to 2001!




This screenshot was taken from one of the 2003 links. My site looks drastically different now. I’ve grown a lot as a designer and developer since then. However, the information is still available.




I teach and host a Bible Study at my apartment on Thursday nights. Recently, I created a Facebook group. I’ve posted what we’ll be doing each week so that if someone has to miss a week, they won’t get behind. The group is still in it’s infancy stages, however, I’m hoping that it will challenge people to share throughout the week. When Thursdsay nights come around, we can go even deeper.

The cool thing about this group is that it really is an extension of a greater conversation that’s already happening. It was never meant to replace the community we have on Thursday nights, only make it richer.





You Version is some website/software that came out of LifeChurch.tv. On their site, you can read and post your thoughts on a particular Scripture passage, create groups, and events. They’ve also got an iPhone app. When you’re at an event, you can pull up the Scripture passage the speaker is using, along with their notes. You can also submit prayer requests or Twitter what you’re learning, directly from the app.

One of the first events they used it at was Catalyst, this past October. However, my connection was terrible within the arena, so, I never saw it actually work.





This is a screenshot of the website for Mars Hill Church in Seattle, Washington. It’s interesting to see some of the stuff that they’re doing since a lot of their members work for Microsoft or Amazon.

In fact, this church created their own Social Networking solution, called The City. Recently, they sold it to Zondervan.

On their site, you can see links to download the sermons, share with friends, find resources, etc.



Conclusions

I expected to come out on the other side with a list of do-s and don’t-s or a 10 step process to understanding social networking. What I found, surprised me. Nothing can replace the conversations and relationships that we have in real life.

Social networking should never replace what we have in real life. It should only extend what’s already there, building off of it.


Books I Read / Am Reading

As I mentioned in my jQuery post (part 1), I’m a bit old fashioned in that I like books. (If I can get some coolness points back–or maybe just geek points–I read books on my Kindle. grin ) These are the books that I read in preparation.




Stay Tuned :: the week of jQuery

STAY TUNED...
I feel like this section has the “Up Next…” commercial feel to it. For me, announcing the line up comes with a level of accountability; I’ve found that I need that.

After writing about creating your own jQuery plugins last week (Part 1 and 2), I thought I’d share a few tricks that I keep in my back pocket. I’ve been creating a lot of blogs for work and so I keep these code snippets close.



Posted 11.27.2009

Posted 11.27.2009

Writing jQuery Plugins (Part 2 – A More in Depth Discussion)

Tuesday, we looked at the BASICS of writing a jQuery plugin.

A Quick Note:

I’m still going to assume that you already have a basic understanding of jQuery. If not, head over to jQuery’s site. There’s some wonderful documentation there to help you get started. When I first decided to learn this library, I was pleasantly pleased with how easy it was.—particularly after having attempted JavaScript (multiple times) and having to write code for multiple browsers… I digress.

A quick review:

Every plugin will contain 3 things:

Your file name will be jquery.your_plugin_name.js.

Comments at the top of your plugin containing information about plugin

/* ==================================================================
*
*    ROLLOVERS PLUGIN
* 
*    DATE:                 AUGUST 22, 2009
*    AUTHOR:             AMY HAYWOOD
*     URL:                 WWW.AMYHAYWOOD.COM
*
*    REQUIREMENTS:         jQuery
*                        Be sure to include the jQuery library before including this script
*     IMPLEMENTATION:
*        Within the $(document).ready(); all that you really need to include is:
*        |    $('.CLASS_NAME_FOR_ROLLOVER').rollover();
*        
*        Within your HTML, be sure to give the image, use the same classname that you used to call .rollover()
*        Within the rel attribute, include the path to the rollover image
*        |    <img src="MY_IMAGE_NAME.jpg" class="CLASS_NAME_FOR_ROLLOVER" rel="MY_ROLLOVER_IMAGE.jpg" />
*
===================================================================== */ 

The actual code will always follow the same format

 (function($) {
        $.fn.rollover = function(options){
            // DEFINE OPTIONS
            var defaults = {};

            var settings = $.extend(defaults, options);

            return this.each(function() {

            });
        };
    })(jQuery);

So far so good?


GOING TO THE NEXT LEVEL :: A ROTATOR

Today, we’re going to use another “real world” example. Hopefully, by walking through the code, you’ll get a feel for setting up preferences—making your code even more reusable.

Here’s the HTML we’re dealing with:

 <div id="DIV_THAT_WRAPS_ALL_ROTATING_ITEMS">
    <div>My Rotator Item #1</div>
    <div>My Rotator Item #2</div>
    <div>My Rotator Item #3</div>
</div> 

Note:

The cool thing about this particular plugin is that you can put whatever you want in your div containers: Text, images, or a mix of both.


THE LOGIC:

  • Hide all the elements within the rotator
  • Show the first element
  • Set up a timer. Every time the timer goes off, hide the current item and show the next element in line.
  • If we’re at the end of the rotator, start over and show the first element

Easy enough?


Start Building

Let’s start plugging in the pieces.

I’m going to create a new file called jquery.rotator.js. Done! Next!.

I’m going to create a comment block at the top of my file that tells me what date I wrote the plugin, the author is me, my web site, the plugin requirements, and how to implement it.

In this particular instance, I’ll hold off writing out the implementation until the end, after the code is written.

 /* ==================================================================
*
*    ROTATOR PLUGIN
* 
*    DATE:                 NOVEMBER 27, 2009
*    AUTHOR:             AMY HAYWOOD
*     URL:                 WWW.AMYHAYWOOD.COM
*
*    REQUIREMENTS:         jQuery
*                        Be sure to include the jQuery library before including this script
*     IMPLEMENTATION:
*/ 

Nothing scary…yet. :-)

Now for the code. One of the things I like to do is actually write the code, as if I’m writing for one site. It’s easier for me to think that way, and then abstract (Abstract is just a fancy computer word for reducing the details to focus on the core concepts so that it can be reused as much as possible) it later.

Let’s just walk through the logic that we outlined.

Hide all the elements within the rotator.
I want my entire rotator to be wrapped in a div with an ID, so that I can find it easily. In the HTML I showed you earlier, I had an ID of DIV_THAT_WRAPS_ALL_ROTATING_ITEMS. You can name it whatever you want, just make sure you call it the same thing in your javascript.

$('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').children('div').hide();

Show the first element.
This code is simple enough:

$('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS).children('div:first).fadeIn();

However, I know that I need to call this multiple times. Every time that I get to the end of my rotator, I’ll need to go back to the first element. Why not put this code in a function? Then, I don’t have to write out the code every time this happens, I can just call the function. But, Amy, it’s only one line of code. Is putting one line of code in it’s own function really the easiest thing? Glad you asked (pardon my cheesiness). Actually, yes! If I wanted to get crazy and make my rotator due something special every time it goes back to the beginning, I only have to change it in one place, inside the function.

Let’s call our function DisplayTheFirstProduct. (It could be an ad for a Store rotator).

DisplayTheFirstProduct = function($element) {
    $element.children('div:first').fadeIn();
    return;
};

DisplayTheFirstProduct($(#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS)); 

You’ll notice that I already jumped ahead and did a little abstraction. I’m passing an $element to my function DisplayTheFirstProduct. Then, it uses the element that I passed in to find the first div nested inside and fades it in.

If we were to publish our code right now, all we’d see is the first item in our rotator. Nothing more, nothing less.

Moving along.

Set up a timer. Every time the timer goes off, hide the current item and show the next element in line.
This is going to require a little bit of Javascript. Nothing scary. A quick look at w3schools documentation shows that

var t=setTimeout("javascript statement",milliseconds); 

The setTimeout() method returns a value – In the statement above, the value is stored in a variable called t. If you want to cancel this setTimeout(), you can refer to it using the variable name.

The first parameter of setTimeout() is a string that contains a JavaScript statement. This statement could be a statement like “alert(‘5 seconds!’)” or a call to a function, like “alertMsg()”.

The second parameter indicates how many milliseconds from now you want to execute the first parameter.

Don’t freak out. All it’s saying is that the first parameter, the javascript statement, is what we want to happen every time the timer goes off. The second parameter is how often we want the timer to go off. In this case, it’s measured in milliseconds. There are 1000 milliseconds in 1 second. So 5000 means that the rotator will change every 5 seconds.

var myTimer = setInterval(ChangeProduct, 5000); 

I want it to run the function ChangeProduct every 5 seconds. Well, I need to define that function:

First, it will need to find the current item. We know that the current item will be visible to the user. So, let’s use the :visible selector in the jQuery library.

var currentlyVisible = $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').children('div:visible');

Then, we want to it fade out the current item.

currentlyVisible.fadeOut();

The cool thing about jQuery’s fadeOut() function is that you can pass in a callback function. This means it won’t run until the item is completely faded out. Then, we want it to display the next item in line.

currentlyVisible.fadeOut(function() {
    currentlyVisible.next().fadeIn();
});

If we’re at the end of the rotator, start over and show the first element
Let’s add a condition within our callback function to make sure we’re fading in the right element. If they’re no more elements, call our DisplayFirstProduct function, otherwise, show the next item.

currentlyVisible.fadeOut(function() {
    if (currentlyVisible.next().length < 1) {
        DisplayTheFirstProduct($('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS'));
    } else {
        currentlyVisible.next().fadeIn();
    }
});

Not too bad. Now, our entire ChangeProduct function looks like this:

ChangeProduct = function() {
    // FIND THE CURRENT PRODUCT
    var currentlyVisible = $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').children('div:visible');
    
    // FADE OUT THE CURRENT PRODUCT AND FADE IN AND SHOW THE NEXT ITEM
    currentlyVisible.fadeOut(function() {
        if (currentlyVisible.next().length < 1) {
            DisplayTheFirstProduct($('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS'));
        } else {
            currentlyVisible.next().fadeIn();
        }

    });

    return;
};

Awesome! If we never needed this code again, we’d be done…. but, we do want to reuse this code. So, let’s plug in our code to the structure:

(function($) {
    $.fn.rollover = function(options){
        // DEFINE OPTIONS
        var defaults = {};

        var settings = $.extend(defaults, options);

        return this.each(function() {

        });
    };
})(jQuery);

All of our content is going to go into the return this.each(function() {});. Now, it looks like this:

return this.each(function() {
    // CHANGES THE PRODUCT
    ChangeProduct = function() {                
        // FIND THE CURRENT PRODUCT
        var currentlyVisible = $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').children('div:visible');
        
        // FADE OUT THE CURRENT PRODUCT AND FADE IN AND SHOW THE NEXT ITEM
        currentlyVisible.fadeOut(function() {

            if (currentlyVisible.next().length < 1) {
                DisplayTheFirstProduct($('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS'));
            } else {
                currentlyVisible.next().fadeIn();
            }

        });

        return;
    };

    // DISPLAYS THE FIRST PRODUCT LISTED
    DisplayTheFirstProduct = function($element) {
        $element.children('div:first').fadeIn();
        return;
    };
    
    // INITIALIZE THE ROTATOR
    $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').children('div').hide();        // HIDE ALL THE PRODUCTS
    DisplayTheFirstProduct($('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS'));        // SET THE CURRENT PRODUCT
    
    var myTimer = setInterval(ChangeProduct, 5000);        
        
}); 

This would be great if our div always had the ID of DIV_THAT_WRAPS_ALL_ROTATING_ITEMS. Regardless, every time you call the plugin, you are actually going to pass in that element, that main div container with the ID of DIV_THAT_WRAPS_ALL_ROTATING_ITEMS.

Let me show you. In, the header, in $(document).ready(); There will be a line $(’#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS’).rotator(); that applies the plugin to whatever div item we want.

Note:

That .rotator(); call matches up with the first part of our plugin structure $.fn.rollover = function(options){


If we’re passing in that element #DIV_THAT_WRAPS_ALL_ROTATING_ITEMS, then, we change everywhere in our plugin where it says #DIV_THAT_WRAPS_ALL_ROTATING_ITEMS to $element. Next, we just have to tell jQuery what that $element is.

$element = $(this); In our main code, when we call $(’#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS’).rotator();, $(this) references $(’#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS).

In our plugin structure return this.each(function() { cycles through every instance of $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS) or $(this).

So, now our block of code within our plugin looks like:


return this.each(function() {
    var $element = $(this);
    
    // CHANGES THE PRODUCT
    // SHOULD BE THE NEXT ITEM LISTED, UNLESS IT IS THE LAST ITEM, IN WHICH CASE IT GOES BACK TO THE FIRST ITEM
    ChangeProduct = function() {                
        // FIND THE CURRENT PRODUCT
        var currentlyVisible = $element.children('div:visible');
        
        // FADE OUT THE CURRENT PRODUCT AND FADE IN AND SHOW THE NEXT ITEM
        currentlyVisible.fadeOut(function() {
            if (currentlyVisible.next().length < 1) {
                DisplayTheFirstProduct($element);
            } else {
                currentlyVisible.next().fadeIn();
            }

        });

        return;
    };

    // DISPLAYS THE FIRST PRODUCT LISTED
    DisplayTheFirstProduct = function($element) {
        $element.children('div:first').fadeIn();
        return;
    };
        
        
    // INITIALIZE THE ROTATOR
    $element.children('div').hide();        // HIDE ALL THE PRODUCTS
    DisplayTheFirstProduct($element);        // SET THE CURRENT PRODUCT
    
    var myTimer = setInterval(ChangeProduct, 5000);        
};

The only thing we have left to do is pass in our preferences.—Let our timer of 5000 milliseconds be configured.

That’s what the defaults section of our structure is for:

// DEFINE OPTIONS
    var defaults = {
        amount_of_time: 5000                    // AMOUNT OF TIME BEFORE CHANGING IN MILLISECONDS
    };

We leave 5000 listed here. If I don’t set any preference, it will automatically default to 5 seconds.

Then, we change our interval in our timer, where 5000 is hard coded in, to look at our preferences.

var myTimer = setInterval(ChangeProduct, settings.amount_of_time);

Also, I just picked a variable name, amount_of_time there’s nothing special about. You just need to make sure that the reference within the code matches.

NOTE:

You might be asking why we’re referencing settings.amount_of_time when we defined amount_of_time in defaults={}. Well, if you look at our plugin structure, we actually pass in our defaults to settings: var settings = $.extend(defaults, options);. The $.extend() comes straight out of the jQuery library.

That’s it! Our full plugin code:


(function($) {
    $.fn.rotator = function(options){
        // DEFINE OPTIONS
        var defaults = {

            amount_of_time: 1000                    // AMOUNT OF TIME BEFORE CHANGING IN MILLISECONDS
        };
    
        var settings = $.extend(defaults, options);
    
        return this.each(function() {
            var $element = $(this);
        
            // CHANGES THE PRODUCT
            // SHOULD BE THE NEXT ITEM LISTED, UNLESS IT IS THE LAST ITEM, IN WHICH CASE IT GOES BACK TO THE FIRST ITEM
            ChangeProduct = function() {                
                // FIND THE CURRENT PRODUCT
                var currentlyVisible = $element.children('div:visible');
                
                // FADE OUT THE CURRENT PRODUCT AND FADE IN AND SHOW THE NEXT ITEM
                currentlyVisible.fadeOut(function() {

                    if (currentlyVisible.next().length < 1) {
                        DisplayTheFirstProduct($element);
                    } else {
                        currentlyVisible.next().addClass(settings.currentAdClass).fadeIn();
                    }

                });

                return;
            };

            // DISPLAYS THE FIRST PRODUCT LISTED
            DisplayTheFirstProduct = function($element) {
                $element.children('div:first').fadeIn();
                return;
            };
            
 &
nbsp;          
            // INITIALIZE THE ROTATOR
            $element.children('div').hide();        // HIDE ALL THE PRODUCTS
            DisplayTheFirstProduct($element);        // SET THE CURRENT PRODUCT
            
            var myTimer = setInterval(ChangeProduct, settings.amount_of_time);        
            
        });
    };
})(jQuery); 

In our HTML head, it would look like this:

 <header>
    <title>JQUERY ROLLOVER TEST</title>
    
    <!-- LINK JAVASCRIPT FILES -->
    <script src="js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/jquery.rotator.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            // INITIALIZE PLUGIN
            $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').rotator(); 
        });
    </script>
</header> 

If we wanted to change the amount of time it took to rotator, we would change that one line to read:

$('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').rotator({
    amount_of_time: 5000;
});

Before we throw our hands in the air in triumph, let’s go back and add that last block of documentation to the top of our jQuery file, our implementation. I know it’s tedious, but it will be worth it when you get ready to reuse your code and can’t remember how you’re supposed to implement it. Did you notice? I speak from experience!

/*
    *     IMPLEMENTATION:
    *        Within the $(document).ready(); all that you really need to include is:
    *        |    $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').rotator();
    *    
    *        However, you can change the amount of time that it takes ot rotate:
    *        |    $('#DIV_THAT_WRAPS_ALL_ROTATING_ITEMS').rotator({
    *        |        amount_of_time: 5000;
    *        |    });
    *
    *        Within your HTML, you must have a div that wraps all rotator items with a unique id.
    *        Each individual rotator item must be wrapped in a div
    *        |    <div id="DIV_THAT_WRAPS_ALL_ROTATING_ITEMS">
    *        |        <div>My Rotator Item #1</div>
    *        |        <div>My Rotator Item #2</div>
    *        |        <div>My Rotator Item #3</div>
    *        |    </div>
*/

 

Download My Code

jquery.rotator.js (4 kB)


What’s next?

Almost three weeks ago, I spoke at the Young Adult fall retreat about “Leveraging Your Life via Social Media”.—A lot of it focused on how to use social media responsibly and how to get the most out of it. Even I learned something while preparing. I’ll post my notes + slides on Sunday.



Posted 11.25.2009

Updated 02.28.2015

Writing jQuery Plugins (Part 1)

The more I write code, the more I realize how repetitive it is. It’s more cost effective (and brain-thawing), if you can figure out ways to be reuse your code. A few weeks ago, I started trying to figure out how to write my own jQuery plugins. Granted, you can probably find an existing plugin for anything that catches your fancy, however, a lot of times, the footprints are larger than necessary to accommodate more people. Besides, I’ll usually find one effect and stick to it (personal preference), rendering most of the customization in the plugin useless. At this point, it becomes easier to write my own code.


EXISTING JQUERY PLUGIN TUTORIALS

Here are a few sites that I looked at to help me get a grasp on structure. As most things, some are better than others. The hard part is some people assume you know more or less, leaving you to put the pieces together. My goal, in this post, is to the heavy lifting for you.


First things First

I’m gonna assume that you’ve at least heard of jQuery. If not, the elevator pitch? It’s a framework for JavaScript. In my humble opinion, it’s far easier to understand and much easier to write than JavaScript. If you’re a web developer, it’s definitely something worth checking out. I’d start by visiting the jQuery site or I’ve listed a few books (yes, you read that correctly, books) at the bottom of this post.


Captain Obvious

The first thing you’ll need to do is download the jQuery library. This has to be included on your page before any jQuery code can be written.

<script src="js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script> 

Update February 28, 2015

One of the things I prefer to do is use Google’s CDN version of jQuery. Several reasons:

  • It prevents me from having to download the code and store it on my server.
  • If your user has visited another site that is using Google’s CDN version of jQuery, then their computer will cache the code on their computer. Then, when that same user visits your site, the code is already cached and it’s one less thing they will need to download to get your site to load.

Instead of using the above line, you can use this instead:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Digging In

File Naming Structure

Your file should always be called jquery.your_plugin_name.js. Obviously, your_plugin_name will be unique to your plugin.


Documentation

Yes, documenting your code is a pain. However, I promise, when you come back to your code, months later, it more than pays off. The code that you say (and wish) you will never come back to will inevitably haunt you. (can you hear the agony of experience in my voice?) :-) Besides, plugins are meant to be reused.

At the top of my file, I list out the name of the plugin, the date that I wrote it, the author (me!), my url, requirements, and implementation.

/* ==================================================================
*
*    ROLLOVERS PLUGIN
* 
*    DATE:                 FEBRUARY 28, 2015
*    AUTHOR:             AMY HAYWOOD
*     URL:                 WWW.AMYHAYWOOD.COM
*
*    REQUIREMENTS:         jQuery
*                        Be sure to include the jQuery library before including this script
*     IMPLEMENTATION:
*        Within the $(document).ready(); all that you really need to include is:
*        |    $('.CLASS_NAME_FOR_ROLLOVER').rollover();
*        
*        Within your HTML, be sure to give the image, use the same classname that you used to call .rollover()
*        Within the rel attribute, include the path to the rollover image
*        |    
*
===================================================================== */

Code within your plugin

Basically, every plugin that you will write, will have the following code in it.


(function($) {
    $.fn.rollover = function(options){
        // DEFINE OPTIONS
        var defaults = {};

        var settings = $.extend(defaults, options);

        return this.each(function() {

        });
    };
})(jQuery); 

Let’s take a step back…


A QUICK EXAMPLE :: ROLLOVERS

THE LOGIC

  • I want to have an image with the file path of the rollover in the rel attribute.
  • When the user rolls over the image, it is swapped out with the value provided in the rel attribute.
  • When the user rolls off the image, it is swapped back to the original image.

Easy enough?


IF I WAS WRITING THE CODE FOR 1 SITE

If I didn’t plan on using this code again, I would simply put the following code in the $(document).ready(); code in my header.


$(document).ready(function() {
    
    $('img[rel]').each(function() {
        var curImg = $(this);
        
        // GET THE VALUES
        var defaultImage = $(curImg).attr('src');
        var rolloverImage = $(curImg).attr('rel');
        
        // SET UP THE ROLLOVER BEHAVIOR
        $(curImg).hover(function() {
            $(curImg).attr('src', defaultImage);
        }, function() {
            $(curImg).attr('src', rolloverImage);
        });
    });
});

Too much too fast? No worries. I’ll break it down.

When you write jQuery code, most of it will appear within $(document).ready();. Basically, it waits until all the pieces on your web page have loaded and are available.

In this example, if we tried to find all the images before they had even loaded, it would return nothing!


$('img[rel]'.each(function() { 

This line of code looks for every image with a rel attribute. For EACH item, it will grab the current image src $(curImg).attr(‘src’) and save it as defaultImage. Then, it will grab the path for the rollover image $(curImg).attr(‘rel’) and save that as rolloverImage.

Lastly, it will set up the behavior. The hover function takes two parameters. The first, will determine what happens when you rollover the item and the second parameter will determine what happens when you roll off. In this case, it’s just a matter of setting the img src based on the defaultImage and rolloverImage.


MAKING THE CODE RESUABLE

Basically, we take the code that we would have made for 1 site and plug it into our jQuery plugin structure. The hardest part is just making sure we abstract everything (a.k.a. make it generic enough so that we can use it over and over).


(function($) {
    $.fn.rollover = function(options){
        // DEFINE OPTIONS
        var defaults = {};

        var settings = $.extend(defaults, options);

        return this.each(function() {
            var $element = $(this);
            var defaultImage = $element.attr('src');

            $element.hover(function() {
                $element.attr('src',  $element.attr('rel'));
            }, function() {
                $element.attr('src', defaultImage);
            });

        });
    };
})(jQuery); 

The only thing that I changed was I took out the code that was in the .each() function (from my 1 site code) and placed it within the this.each(function() { }); of the plugin. Now, when I call the plugin, it will run the loop on all the items I pass to it.

So, in the header of my HTML file, it will look like this:


<header>
    <title>JQUERY ROLLOVER TEST</title>
    
    <!-- LINK JAVASCRIPT FILES -->
    <script src="js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/jquery.rollovers.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            // INITIALIZE PLUGIN
            $('.CLASS_NAME_FOR_ROLLOVER').rollover(); 
        });
    </script>
</header> 

Now, for every item in the body that has a class name of .CLASS_NAME_FOR_ROLLOVER it will try and create a rollover.


Stay Tuned

This post would probably fit into the “assuming you know less” category. On Friday, I’ll take a more in depth look at plugins, demonstrating their extensibility (i.e. setting preferences). Just to whet your appetite, we’ll be building an image rotator where you can pass in the speed.

Download My Code

jquery.rollovers.js (kB)


CALL ME OLD FASHIONED

Call me old fashioned, but I still enjoy reading programming books. I know, ancient. I love my Kindle, but there is still something to be said for flipping pages, laying out multiple books, and cross-referencing. With that said, my favorite jQuery resources are books. That’s how I taught myself.


Learning jQuery
This is the book that I used to teach myself jQuery.


jQuery Reference
This book is also published by Pakt Publishing. This is the book that I go to for reference.


jQuery in Action
Yes, the cover looks a little hokey, but some of the content in the appendixes is worth the book’s weight in gold.