jQuery – 9bit Studios https://9bitstudios.com Web Design, Themes, & Applications Fri, 29 Jul 2016 20:33:49 +0000 en-US hourly 1 https://wordpress.org/?v=4.5.3 Create Mobile Applications for iOS and Android with HTML5, JavaScript, and Apache Cordova https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/ https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/#respond Sat, 12 Dec 2015 22:49:53 +0000 https://9bitstudios.com/?p=1101 Obviously at the time of this writing in the 2nd decade of the 21st century, you are no doubt well acquainted with the immense proliferation and impact that mobile apps have had in and on our world. It was not long ago that we were all sitting at our computers at our desks for the large majority of the time we spent in our various avenues of technological communications over the Internet — complete with our with our giant monitors, whirring computer fans, buzzing drives, and the garbled noise of dial-up modems. Now, mobile phones and tablets probably make up as much, if not more, of our time spent working, playing, and communicating online. Everyone has a ~$100 to $600 smartphone (i.e. computer) in their pocket. And with this rise of mobile, apps found on the popular stores — like Apple’s iOS App Store, Google Play (Android), Amazon and a host of others — have completely transformed the way that we do anything and everything because well, there is an app for anything and everything. Every single facet of life probably has an app to manage some aspect of it. Need to remember to breathe? There is an app for that! Yeah, that is a joke (probably)… but there are plenty of “real” apps out there (e.g. iBeer) that are just as pointless. Fun and goofy, yes, but pointless. And they all post their pointlessness to Facebook and/or Twitter.

Whether you want to develop an app to manage some minute aspect of life or just create a fun game, or whatever else, you can download the SDK for the platform(s) that you want to release your app on, do some tutorials, and start building. That’s all well and good, but if you want to port your application to another platform (e.g. release an iOS app also for Android), you will essentially have to try rebuild the same app using the languages in tools of a different platform. For example, iOS apps for iPhone and iPad have traditionally been developed on a Mac in the Xcode IDE using the Objective-C programming language (though Apple has recently released a new language called Swift that can also be used to build iOS apps). Android apps, by contrast are built using Java and Eclipse or the more recently released Android Studio. Native Windows Phone apps are built using C# and XAML in Visual Studio. Other platforms have their own setups. If you want to take this approach you definitely can, but it should be fairly apparent that developing and maintaining a number of different codebases for multiple platforms quickly adds up to a lot of time, effort, and often money as the sizes and complexity of your apps increase.

At the same time as the rise of mobile in the past decade, something else has occurred: the rise of HTML5 and JavaScript web applications. Beginning at around 2009 – 2010 one of the more noticeable developments was the rise of websites and web applications making use of more open technologies such as HTML5 and JavaScript to bring interactivity and 2-way communication between clients (usually browsers) and servers. With Flash on the way out due its proprietary nature, resource hogging, security issues, poor SEO — along with its being snubbed by Apple for support on iPhones and iPads for basically all these reasons — meant that something had to fill the void. HTML5 and JavaScript moved into this space and developers started turning to it for creating interactive “app-like” experiences.

Wouldn’t it be awesome if there were a way to write a single application in HTML and JavaScript with a single codebase and have a way to port this application to all of the different mobile platforms? I am so glad you asked.

Apache Cordova — also commonly known as “PhoneGap” (the only difference between the two is propriety) — allows us combine combine these open technologies together with the SDKs of the various mobile application platforms to make native mobile applications using technologies such as HTML and JavaScript. You can basically create a small static HTML and JavaScript website or web application and this code will be imported into native iOS, Android, Windows Phone projects and configured specifically for the respective platforms. Thus, you *do* still have to have the SDK of the platform installed to build, run, and release the apps. So to create an iOS app you will still need a Mac and Xcode. To create Android apps you will need to install the Android SDK (which comes with the Android Studio IDE). But the important aspect of using Cordova is that the HTML and JavaScript that each project will pull in and build will be the same across all platforms. Want to release an update with some slick new features or fix some bugs that have been reported by your users? You need only change your code in your HTML and JavaScript. You don’t have to try and rewrite the same code and/or functionality in a different language on each platform. From there all you need to do is run a few simple commands from the command lines and your HTML and JavaScript will get built and converted into an application that can run on the platform(s) you are targeting.

In what follows we will explore what it looks like to use Cordova to create a mobile application in HTML and JavaScript that can run on a number of different platform. For our examples, we will build our app for iOS and Android, but the process is essentially the same for building for other platforms (e.g. Microsoft Windows Phone, Amazon Kindle Fire). You would just need to download the SDKs for those platforms if you wanted to run your app on those types of devices as well.

So let’s get to it…

Installing Node.js

The first thing that we will need to do before we do anything else is install Node.js. Apache Cordova runs on Node.js so it is a prerequisite. If you’re not entirely familiar with Node.js there is a primer on Node.js here. It has become a huge part of JavaScript development in the last half-decade and is only becoming more and more prominent.

To install Node.js all you have to do is head on over to their website and follow the directions for your operating system (Windows, Mac, or Linux).

Installing Apache Cordova

Once we have Node.js installed, next we will need to install Apache Cordova. We just do this over npm. npm comes with the Node.js installation, so you already have it on your machine from installing Node.

To install Cordova open up a command window or terminal and run the following…

$ npm install -g cordova

In case you are not familiar with it, the “-g” flag means “global.” You will want to do this so that you can run Cordova commands from any directory on your system.

Creating an Apache Cordova Project

Now you can go to a directory where you want to create your Cordova project and open a command window/terminal. We will be initializing a new Cordova application here with the Cordova “create” command. For more information on the configuration options you can choose when installing and setting up your project, please see the Apache Cordova documentation here. Run the following command from your command line…

$ cordova create ninebit com.ninebitstudios.ninebitapp NinebitApp

The command above will create a vanilla Cordova project called “NinebitApp” and ocnfiguring it with a unique ID that uses reverse domain name notation in a directory named “ninebit.” What you will want to do is change these values to what you want for your own application.

$ cordova create   

For example…

$ cordova create yourdirectory com.yourdomain.yourapp YourAppName

but just plug your own values that you want in there.

You should see the directory with the name you specified created with with a number of files and directories in there like “platforms,” “plugins,” “www”, and a “config.xml” file. The config.xml file will have some of the values that you specified in your mobile. The actual location where you will write your HTML and JavaScript is in the “www” directory. If you explore that directory and open the index.html file you will see a boilerplate web application which basically just displays an image on the page. Even though it does not do much, this is an app that can run on any of the platforms we want to specify. We will add these platforms next.

Adding Support for Android Devices to the Project

Now that we have our project created we need to “add” the platforms that we want to release on to our project. Open a command window in the root directory of the project (the one with the config.xml file).

To add Android to our project run the following…

$ cordova platform add android

You should see a directory called “android” in the platforms folder. This folder contains a native Android project that is preconfigured to take the HTML and JavaScript in the “www” folder and run it in an Android device. If you opened Android Studio and clicked on “Create New Android Project” you would see almost the same files and folders in the project that gets created when creating a native Android application. There will be few extra files and folders in the Cordova Android project specific to Apache Cordova.

Because we now have a native Android project, we can run it on the Android emulator. In the root directory we can now run following…

$ cordova emulate android

This should launch the Android emulator and automatically run your application after it boots up. Note that you might need to set up a device for Android project to use before you try to run the command above. To do this, you will need to launch the Android Virtual Device Manager (AVD Manager.exe). This application resides in the root folder of where you installed your Android Studio SDK. You can also launch AVD Manager in Android Studio under the “Tools” menu under “Android.” However you open this application, once you are in there just click “Create New” and pick whatever device you want. Once you get the device set up you can try to run the command above again.

Adding Support for iOS Devices to the Project

Similarly, if you want to add support for iOS

$ cordova platform add ios

As was the case with Android above, you should see an “ios” directory. This folder contains a native Xcode project that is preconfigured to take the HTML and JavaScript in the “www” folder and run it in an iOS device.

Remember that you *must* have the SDK of the platform you are trying to add installed on your system. If you do not the Cordova console should inform you of this error.

For iOS you will want to make sure that you have the proper folder permissions in all of the directories and folders you will be working in. I had some issues trying to emulate when running all the cordova commands with sudo. So make sure on your Cordova project directory you do something like the following…

$ sudo chmod -R 777 foldername

so that you can run all the commands without using sudo

The first thing that you’ll want to do is add the iOS platform to your project.

$ cordova platform add ios

You can then build for iOS by running the following command. If you are able to do so without errors, you’ll know that everything is all good.

$ cordova build ios

Note in /platforms/ios/cordova/lib there is a list-emulator-images tool that you can run to list out all of the emulator images that you have installed. These are the different devices that you can emulate your apps…

$ ./platforms/ios/cordova/lib/list-emulator-images 

You will see a list like the following…

  • iPhone-4s
  • iPhone-5
  • iPhone-5s
  • iPhone-6-Plus
  • iPhone-6
  • iPad-2
  • iPad-Retina
  • iPad-Air
  • Resizable-iPhone
  • Resizable-iPad

If you want to specify a target, you can run the simulator on a specific device by targeting a specific device. For example…

cordova emulate ios --target="iPhone-4s"
cordova emulate ios --target="iPad-Air"
cordova emulate ios --target="iPhone-6"
cordova emulate ios --target="iPhone-6-Plus"

Otherwise, the iOS development tools will just use what is set as the default device (usually the latest version of the iPhone that is currently in production).

And of course, if you want to emulate on an iOS device in Xcode you can run the following command in your project root…

$ cordova emulate iOS

This should launch the iOS simulator and run your application.

Summary

In the above discussion we looked at all of the steps, tools, and environments necessary to create an Apache Cordova project and get things set up such that you can begin developing cross-platform mobile applications. In a future discussions we will take a deeper look at how write the code for out apps as well as how to package everything in your application up once you are finished developing and submit it to the respective stores for iOS (App Store) and Android (Google Play). But those are other discussions for some other days. So until next time, happy mobile developing!

]]>
https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/feed/ 0
Local Search with RegEx https://9bitstudios.com/2015/06/local-search-with-regex/ https://9bitstudios.com/2015/06/local-search-with-regex/#respond Mon, 08 Jun 2015 14:42:11 +0000 https://9bitstudios.com/?p=1059 I was developing an HTML5 mobile app for an organization. The app was very simple and essentially consisted of a number of different chapters with a lot of text in each. So the homepage of the app was just a list of the chapters and each list item linked to a chapter page. All the text was in a single page (HTML document) and the app framework would just show/hide the relevant portions of it when needed. A lot of mobile HTML5 frameworks do this implementation and it essentially amounts to a simple single page application. None of the content for this app was stored on a server.

However, one of the features requested was search in that they wanted the ability to search for a term and link to the term from a search page. This is usually pretty easy if content is stored in a database because all the infrastructure to run queries against content in said database is there for you. However if all the text is in a single page application, how would you 1. find it and 2, link to it? What follows is essentially my approach in what amounts to essentially a local search functionality in a single page application.

For starters, say we had the following HTML document…

<!doctype html>
<html>
  <head>
    <title>App</title>
  </head>
<body>
    <div id="home" class="page">
        <ul id="menu" class="page">
            <li><a href="#search">Search</a></li>
            <li><a href="#chapter1">Chapter 1</a></li>
            <li><a href="#chapter2">Chapter 2</a></li>
            <li><a href="#chapter3">Chapter 3</a></li>
        </ul>
    </div>
    <div id="chapter1" class="page">
        <p>The quick brown fox jumped over the lazy dog.</p>
        <p>How now brown cow?</p>
        <p>Something else</p>
    </div>
    <div  id="chapter2" class="page">
        <p>Chapter 2 text here...</p>
        <p>More text here...</p>
    </div>    
    <div  id="chapter3" class="page">
        <p>Chapter 3 text here...</p>
        <p>More text here...</p>
    </div> 
    <div id="search" class="page">
        <input id="search-box" type="search" />
        <ul id="search-results"></ul>
    </div>   
</body>
</html>

Each div with the class “page” would be loaded into the main view when a user clicked on a link to the id of the <div> as can be seen in the menu page. For brevity, I’ve kept the content of each <div> really small but imagine that there were a number of chapters and each paragraph in each chapter had large amounts of text.

What I ended up doing is I added a class called “indexed” (to say that the content of this element is going to be indexed in the search functionality) and some “data-reference” attributes to each paragraph of text to be able to tell where in the application I was. If we were going to have for text *with links*, we’d need to have a way to tell “where we are” so that when we load that page we could scroll to the div that had the text that was searched for.

<!doctype html>
<html>
  <head>
    <title>App</title>
  </head>
<body>
    <div id="home" class="page">
        <ul id="menu" class="page">
            <li><a href="#search">Search</a></li>
            <li><a href="#chapter1">Chapter 1</a></li>
            <li><a href="#chapter2">Chapter 2</a></li>
            <li><a href="#chapter3">Chapter 3</a></li>
        </ul>
    </div>
    <div id="chapter1" class="page">
        <p class="indexed" data-reference="1-1">The quick brown fox jumped over the lazy dog.</p>
        <p class="indexed" data-reference="1-2">How now brown cow?</p>
        <p class="indexed" data-reference="1-3">Something else</p>
    </div>
    <div  id="chapter2" class="page">
        <p class="indexed" data-reference="2-1">Chapter 2 text here...</p>
        <p class="indexed" data-reference="2-2">More text here...</p>
    </div>    
    <div  id="chapter3" class="page">
        <p class="indexed" data-reference="3-1">Chapter 3 text here...</p>
        <p class="indexed" data-reference="3-2">More text here...</p>
    </div> 
    <div id="search" class="page">
        <input id="search-box" type="search" />
        <ul id="search-results"></ul>
    </div>   
</body>
</html>

So as the user types into the search box if we use some jQuery and some RegEx we can 1. search through every “indexed” element for the text that was searched for and 2. populate the search results <div> with links to the various elements. It would look a little bit like this…

jQuery(document).ready(function(){

    function search(searchedText) {
        if(searchedText.trim() === ""){
            jQuery('#search-results').empty().text('No results...');
            return;
        }

        var res = jQuery(".indexed:contains('"+searchedText+"')").each( function() {
            var current = jQuery(this).closest('div[class="page"]');
            var regex = new RegExp(".{0,20}" + searchedText + ".{0,20}", "i");
            var str = jQuery(this).text().match(regex);
            var ref = jQuery(this).closest('[data-reference]');
            jQuery('#search-results').append('<li><a href="#'+ current.attr('id') +'?reference='+ ref.attr('data-reference') +'">... '+ str +' ...</a> - '+ current.find('h1').text() +'</li>');
            return; 
        });

        if(res.length === 0) {
            jQuery('#search-results').empty().text('No results...');
        }
    }

    var searchResults = jQuery('#search-results'), searchTimeout;

    jQuery('#search-box').on('keyup', function(){
        var el = jQuery(this);
        searchResults.empty();
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(function() {
            search(el.val());
        }, 1000);
    });

});

So basically what we are saying here is that while we type into the search box, we will wait until the user is finished typing and then we will check each “indexed” element for the text we are searching for. If we find it we will create a link to that text to the chapter and append a query string value to the “data-reference” value of the element that contains the text. We can then use the event that fires every time the page changes (as a lot of mobile frameworks have) to check for this reference parameter in the url. If it is there we can do something like the following to scroll to the paragraph that contains the text we were searching for. We call the following scrollTo function on each change/load of a page.

function getParameter(name){
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

function scrollTo() {	
    if(getParameter('reference')) {
        jQuery('html,body').animate({
            scrollTop: jQuery('[data-reference="'+ getParameter('reference') +'"]').prev().offset().top -20
        }, 100);            
    }
}

The way things are set up at the moment, the regular expression will search for the exact text entered into the search box. Thus, search is case-snesitive at the moment. No matter. If we wanted to incorporate case-insensitivity into things we could simply add the following method…

// make :contains case insenstive for search
jQuery.expr[":"].contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

By implementing these sorts of techniques and methods, you can incorporate local search and linking into a single page application with a relatively small amount of code. You could take this and expand upon it pretty easily. So even within the perceived limitations of a single page application, you can find ways to implement dynamic functionality that you would expect from any other application. Until next time, happy searching!

View Demo
]]>
https://9bitstudios.com/2015/06/local-search-with-regex/feed/ 0
jQuery Event Delegation https://9bitstudios.com/2015/03/jquery-event-delegation/ https://9bitstudios.com/2015/03/jquery-event-delegation/#respond Sat, 21 Mar 2015 00:29:07 +0000 https://9bitstudios.com/?p=1020 Event delegation is a very important part of writing efficient code for handling events in JavaScript. We looked at JavaScript events in this section here and looked at some other components of it when exploring things like the publish/subscribe pattern in creating JavaScript event channels.

What is event delegation? Well, in general the concept of event delegation could be thought of as assigning a single event handler to handle multiple items.Event delegation is not necessarily a requirement for handling JavaScript events, but it certainly is a good practice and a good habit to apply to your JavaScript code.

We’ll take a look at this below using jQuery in our example. Let’s say we had a simple menu like the following.

<!DOCTYPE html>
<head>
    <title>Event Delegation jQuery | 9bit Studios</title>    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
    <div id="menu">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Portfolio</a>
        <a href="#">Projects</a>
    </div>          
</body>
</html>

So how would we add events to our <a> elements? Certainly we could do something like the following…

<!DOCTYPE html>
<head>
    <title>Event Delegation jQuery | 9bit Studios</title>    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
    <div id="menu">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Portfolio</a>
        <a href="#">Projects</a>
    </div>

    <script type="text/javascript">
    jQuery(document).ready(function(){
        jQuery('#menu a').on('click', function(e){ 
            console.log(e.target);
        });    
    });
    </script>  
          
</body>
</html>

In doing this, we have added events to each of the individual <a> elements. While this certainly works it becomes a bit messier when you start to dynamically add elements to the DOM. In modern web applications, dynamic, interactive, client-side updating of content is certainly a very common implementation that you come across. Let’s say we wanted to add a button to dynamically add new items to our menu…

<!DOCTYPE html>
<head>
    <title>Event Delegation jQuery | 9bit Studios</title>    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
    <div id="menu">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Portfolio</a>
        <a href="#">Projects</a>
    </div>
    <a id="addNew" href="#">+ Add New Menu Item</a>

    <script type="text/javascript">
    jQuery(document).ready(function(){
        jQuery('#menu a').on('click', function(e){ 
            console.log(e.target);
        });  
        jQuery('#addNew').on('click', function(e){ 
            var html = '<a href="#">New Item</a>';
            jQuery('#menu').append(html);
        });    
    });
    </script>  
          
</body>
</html>

When you add a few new menu items what happens when you click on the newly created items? Nothing. Why is that? Because when we ran our code to add the events to each individual <a> elements those newly added elements did not exist (and thus never got event handlers attached to them).

What could we do to solve this? Well, we could certainly run the code to add event handlers again, but as our codebase gets bigger and more complex handling things this way gets a bit on the messy side.

What should we do then? As it turns out a better way to approach this is to add the event to something that will always be there and won’t change. In this case, it’s our <div id=”menu”> container. By adding the click event to the this container, it servers as the delegate for all of our <a> elements. We can then do the following…

<!DOCTYPE html>
<head>
    <title>Event Delegation jQuery | 9bit Studios</title>    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
    <div id="menu">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Portfolio</a>
        <a href="#">Projects</a>
    </div>
    <a id="addNew" href="#">+ Add New Menu Item</a>

    <script type="text/javascript">
    jQuery(document).ready(function(){
        jQuery('#menu').on('click', 'a', function(e){ 
            console.log(e.target);
        });  
        jQuery('#addNew').on('click', function(e){ 
            var html = '<a href="#">New Item</a>';
            jQuery('#menu').append(html);
        });    
    });
    </script>  
          
</body>
</html>

Notice the syntax of displaying the a selector after the. As is described in the jQuery docs for the .on() method

If selector is omitted or is null, the event handler is referred to as direct or directly-bound. The handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element.

When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.

So now what happens when you click on a newly created <a> element in our menu. Voila! The event is captured. Huzzah! We now never have to worry about adding (or removing) any events for our dynamically created elements because we have used event delegation to handle it for us. A single function takes care of all future updates. It’s a one and done kinda thing.

Hopefully, this discussion has helped you better understand what event delegation is and where it might be useful. Until next time, happy delegating!

]]>
https://9bitstudios.com/2015/03/jquery-event-delegation/feed/ 0
JavaScript Extend https://9bitstudios.com/2014/06/javascript-extend/ https://9bitstudios.com/2014/06/javascript-extend/#respond Wed, 18 Jun 2014 13:48:30 +0000 https://9bitstudios.com/?p=983 One of the most important parts of any programming language is the ability to extend objects, creating your own objects and objects that inherit from those objects. In class-based languages like Java or PHP you’ll see the “extends” keyword being used to set up inheritance between different objects.

JavaScript, however, is structured quite a bit different than class-based languages because it is a prototype-based language. For a more detailed look at JavaScript inheritance see this article here. Additionally, opposed to having different types assigned to variables, in JavaScript everything is an object (and, as a result, everything can be extended)
.
In what follows we’ll take a brief look at JavaScript extend functions. Note that this is a little bit different than inheritance. Extend functions in JavaScript could maybe be thought of merging 2 objects, rather than one object inheriting from another. We’ll refer to these as the target object and an extending object. Remember in JavaScript that an object literal is essentially a collection of key/value pairs. Recall too that in JavaScript object keys can also have functions for their values as well. So if a “key” in our extending object already exists on the target object the value for the key in the extending object will overwrite the value for the key in the target object.

The function to extend an object will look something like what is below…

function extend(targetObject, extendingObject){
    for(var key in extendingObject) {
        targetObject[key] = extendingObject[key];
    }
}

Let’s take a look at how this works in practice. Say we have an object called “robot,” that has a couple of properties…

var robot = { 
    size: 'small',
    gas: 100,
    mode: 'helpful',
    move: function() {
        console.log('Walk')
    }
};

Now let’s say we want to extend our robot with some “upgrades”. New properties (keys) will be added to the object and existing properties will overwrite the values for the current object. Will give the robot some more gas (overwriting the robot’s current value), and give it a new mode (setting) and give it a rocket launcher,

var upgrades = {
    gas: 200,
    mode: 'crush kill destroy',
    rocketLauncher: function(){
        console.log('BOOM');
    }
};

Pass this into the extend function…

extend(robot, upgrades);

And now our robot object looks like the following…

var robot = { 

    size: 'small',
    gas: 200,
    mode: 'crush kill destroy',
    move: function() {
        console.log('Walk')
    },
    rocketLauncher: function(){
        console.log('BOOM');
    }
};

Now that we’ve set our robot to “crush kill destroy” it’s a good thing we’ve kept the size at “small.” Hopefully it will be easier to take out if it turns on us.

Let’s take a look at the popular Underscore.js libary’s extend function…

_.extend = function(obj) {
    each(slice.call(arguments, 1), function(source) {
        if (source) {
            for (var prop in source) {
                obj[prop] = source[prop];
            }
        }
    });
    return obj;
};

Aside from a little bit of conditional checking and variance in how it’s called, the core functional purpose is essentially the same as the function we wrote above.

You’ll often see the extend function used to pass in different options or settings when calling certain jQuery plugins.

$(window).load(function() {
    $('.flexslider').flexslider({
        animation: "slide",
        animationLoop: false,
        itemWidth: 210,
        itemMargin: 5,
        minItems: 2,
        maxItems: 4
    });
});

Within the plugin there will be some default settings, but an object literal can get passed in when calling the jQuery plugin that will overwrite the default settings by using the jQuery extend function. This is an easy way to implement custom settings for a jQuery plugin.

So as we have seen, extend functions in JavaScript are a common and useful way to merge two objects together for a variety of purposes. Hopefully you’ll be able to use this when writing some of your JavaScript based applications.

]]>
https://9bitstudios.com/2014/06/javascript-extend/feed/ 0
AJAX and WordPress https://9bitstudios.com/2014/04/ajax-and-wordpress/ https://9bitstudios.com/2014/04/ajax-and-wordpress/#respond Sun, 06 Apr 2014 13:53:47 +0000 https://9bitstudios.com/?p=955 When the web moved from HTML4 to HTML5, the rise of AJAX based web applications came along with it. AJAX (which stands for Asynchronous JavaScript and XML) can mean a number of things but in practice it often refers primarily to the client/server interaction where JavaScript can be used to communicate with a server by making calls at various times under various conditions to send and receive data. This can be happening as often as you like in real-time without the user having to navigate to another webpage or refresh their browser (i.e. asynchronously).

AJAX

What is an example of this? Well, say I wanted to put a stock ticker on my webpage or in my web application. I could use JavaScript to make a call to a service like some stock-market API that will give me quotes on a particular stock, get the data back, and display it in the UI in a visually appealing manner. As these market prices update over time, I can periodically update the quotes that I’m displaying on the page. The format that the server returns data in really depends on the service you are calling. It can often be be XML (as the X in AJAX suggests) but another popular format is JSON. I actually like JSON a bit better, myself. The experience of parsing through everything in code just seems a bit cleaner so if there is the option to have the data you are trying to get returned to you in JSON, I’ll usually opt for that.

Because JavaScript is such a universally cross-platform language capable of running on so many different devices in different environments, this can be a great way for different applications to communicate with each other. The result, hopefully, is to give your users the best experience possible whether they are on desktop, mobile, tablet, or some other crazy device.

In the early part of the 21st century, something else that was and has been absolutely ubiquitous across the internet is WordPress. From it’s humble beginnings of being exclusively web-based blog software, it has transformed into essentially the most popular content management system (CMS) used for running small and medium sized websites or web applications.

In what follows, we can look at how we can undertake merging these 2 things together. We’re basically going to look at how we can send and receive JSON data to a WordPress database and read from and write to the tables within WordPress using AJAX.

So let’s get started…

WordPress Options

Perhaps the most common component of customizing WordPress is using options. When you save custom options to your WordPress database they get stored in the wp_options table. A lot of themes and plugins use these in settings panels where you can customize various aspects of whatever plugin or theme you are using. The way that they save these options is by storing them in the wp_options table. NOTE: Recall that the “wp_” is a prefix that is set in the the wp-config.php file and might vary from installation to to installation depending on how your original WordPress database was set up… but an _options table will always be there regardless of the prefix, and the way that you get and save the options will always be the same.

The way that you save an option is to give it a name…

add_option('my_cool_option', 'hooray'); 

And you can get each option by reading it, save it to variables, etc.

$hooray = get_option('my_cool_option');

It perhaps is not a particularly efficient arrangement as sometimes you have to read an individual option for customizing every little piece of your entire WordPress stack. As the number of plugins in use and other custom parts of WordPress start to grow, this can potentially cause some slowdown. However, if we were to leverage saving JSON to our wp_options table we can put multiple options into one entry. We’ll still have to pull the JSON down and parse through it, but it may be that this approach leads to less clutter within or WordPress options table. One thing’s for sure. We’ll definitely have that more AJAXy “appy” feel in our WordPress setup.

This article “AJAX in Plugins” on WordPress.org goes over essentially what we want to accomplish. It’s talking about things in the context of plugins, but the same components also apply to theme settings and other areas of WordPress as well.

Creating the Plugin

So let’s start by creating a place in our WordPress admin panel where we can try to get and post some AJAX data using JSON. It’s always a good idea to wrap what we’re doing up in a class and our plugin here will use the same approach. First things first, we’re going to want to add some generic activation and deactivation hooks for our plugin. We’re also going to want to add a menu item to the WordPress admin panel. The page that this menu item will go to will be in the home.php file and we’ll add that in the same directory as our plugin.

<?php
/* 
Plugin Name: 9bit Studios WordPress AJAX
Plugin URI: https://9bitstudios.com
Description: A plugin demonstrating AJAX in WordPress
Author: 9bit Studios
Version: 1.0.0 
Author URI: https://9bitstudios.com
*/

class NBS_WordPress_Ajax {
     
    function __construct() {
        register_activation_hook(__FILE__,  array($this, 'activation'));
        register_deactivation_hook(__FILE__,  array($this, 'deactivation')); 
        add_action('admin_menu', array($this,'add_admin_menu'));  
    }
     
    function activation() { 
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    }
 
    function deactivation() { 
        /* Nothing to do here */
    }

    function add_admin_menu() {  
        add_menu_page('WordPress AJAX', 'WordPress AJAX', 'publish_posts', __FILE__, array($this,"home"));
    }   

    function home() {  
        include('home.php'); 
    } 

}
$nbsAjax = new NBS_WordPress_Ajax();

The home.php file won’t be too complicated. Just a couple of places that we will hook our JavaScript to for getting and saving our options, and a panel to show some output.

Next we’re going to want to add our JavaScript/jQuery file. This will also go in the same directory as our plugin. The proper way to do this in WordPress is to use the wp_enqueue_script function. We can use the plugins_url() WordPress function and PHP’s dirname function and __FILE__ constant to specify the path to our plugin directory.

So our plugin now currently looks like this…

<?php
/* 
Plugin Name: 9bit Studios WordPress AJAX
Plugin URI: https://9bitstudios.com
Description: A plugin demonstrating AJAX in WordPress
Author: 9bit Studios
Version: 1.0.0 
Author URI: https://9bitstudios.com
*/

class NBS_WordPress_Ajax {
     
    function __construct() {
        register_activation_hook(__FILE__,  array($this, 'activation'));
        register_deactivation_hook(__FILE__,  array($this, 'deactivation')); 
        add_action('admin_footer', array($this, 'cool_options_javascript'));  
        add_action('admin_menu', array($this,'add_admin_menu'));  
    }
     
    function activation() { 
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    }
 
    function deactivation() { 
        /* Nothing to do here */
    }

    function add_admin_menu() {  
        add_menu_page('WordPress AJAX', 'WordPress AJAX', 'publish_posts', __FILE__, array($this,"home"));
    }   

    function home() {  
        include('home.php'); 
    } 

    function cool_options_javascript() { 
        $pluginDirectory = plugins_url() .'/'. basename(dirname(__FILE__));
        wp_enqueue_script("nbs-wp-ajax", $pluginDirectory . '/nbs-wp-ajax.js');
    }  

}
$nbsAjax = new NBS_WordPress_Ajax();

WordPress AJAX Functions

Now comes the fun part. We’re going to want to create the functions that will handle getting and setting our WordPress options. How does this work in WordPress? Well, as it turns out we can name our function whatever we want, but we have to attach it to a custom action hook and we have to make sure that we prefix our action hook name with “wp_ajax_”. There are a lot of places where WordPress uses specifically named strings as part of its functionality. WordPress is weird like that but that’s how it is and this is one of those cases. We’re going to want to create places to both get and save our options. We need to prefix the string with wp_ajax followed by our_function_name and separate the 2 with an underscore. So our action will be something like “wp_ajax_our_function_name.” So if we were to add these to our plugin it would look something like the following…

<?php
/* 
Plugin Name: 9bit Studios WordPress AJAX
Plugin URI: https://9bitstudios.com
Description: A plugin demonstrating AJAX in WordPress
Author: 9bit Studios
Version: 1.0.0 
Author URI: https://9bitstudios.com
*/

class NBS_WordPress_Ajax {
     
    function __construct() {
         
        register_activation_hook(__FILE__,  array($this, 'activation'));
        register_deactivation_hook(__FILE__,  array($this, 'deactivation')); 
        add_action('admin_menu', array($this,'add_admin_menu'));         
        add_action('admin_footer', array($this, 'cool_options_javascript'));
        add_action('wp_ajax_get_cool_options',  array($this, 'get_cool_options'));		
        add_action('wp_ajax_save_cool_options',  array($this, 'save_cool_options'));

    }
     
    /**** ACTIVATION ****/
     
    function activation() { 
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    }
 
    /**** DEACTIVATION ****/
    function deactivation() { 
        /* Nothing to do here */
    }


    /**** REGISTER MENU & PAGES ****/
    function add_admin_menu() {  
        add_menu_page('WordPress AJAX', 'WordPress AJAX', 'publish_posts', __FILE__, array($this,"home"));
    }     

    function home() {  
        include('home.php'); 
    } 

    function cool_options_javascript() { 
        $pluginDirectory = plugins_url() .'/'. basename(dirname(__FILE__));
        wp_enqueue_script("nbs-wp-ajax", $pluginDirectory . '/nbs-wp-ajax.js');
    }  

    function get_cool_options() {

    } 	
	
    function save_cool_options() {
    }      

}

$nbsAjax = new NBS_WordPress_Ajax();

As you can see, we’ve used the custom action hook names “wp_ajax_get_cool_options” and “wp_ajax_save_cool_options” that will be used to get an save options when we sent data to them using JavaScript / jQuery a bit later on. Then we give these custom action hooks callback function to run when data get gets sent to WordPress’ core AJAX handling PHP file. We can name these callbacks whatever we want. We don’t need to prefix them with anything.

Now let’s utilize WordPress’s $wpdb class and PHP’s json_encode function to create a way to get and save our data. In WordPress’ AJAX functions, data is going to be available to us via the $_POST variables that will get sent to us via AJAX. We’ll then serialize these variables as a JSON string, and save it to the database using WordPress’ update_option function. Lastly, we’re also going to want to return something back to tell the user that his/her save was successful. So in our callback that saves options, it might look something like the following…

function save_cool_options() {
    global $wpdb; // this is how you get access to the database

    $itemArray = array(
        'name' => $_POST['name'],
        'age' => $_POST['age'],
        'favorite_color' => $_POST['color'],
    );    
        
    $saveData = json_encode($itemArray);        
    update_option('cool_json_option', $saveData); 
    
    echo 'true';

    die(); // this is required to return a proper result
}

So as we can see, we’re going to save our option value under the name “cool_json_option.”

Our get_cool_options function is goign to be a bit simpler. All we have to do is get the option from the database and return it to the browser as serialized JSON (which is basically the format that it already is).

function get_cool_options() {
    global $wpdb; // this is how you get access to the database

    $cool_options = get_option('cool_json_option');
    echo $cool_options;

    die(); // this is required to return a proper result
} 

So now that we have our functions all set, we can start calling them with AJAX in JavaScript.

Accessing Our Functions With AJAX

By default, all WordPress AJAX requests are sent to the admin-ajax.php file found in the WordPress core in the wp-admin directory. Fortunately, there is a global variable set by WordPress called “ajaxurl” that points to this file so that we can use in our JavaScript as the URL where we want to send our POST request. So to get or set our options via AJAX we know we’re going to want to send a POST request to a function, but how are we going to tell WordPress which function we want to use to handle our data? Recall, earlier that we gave our action hooks very specific names prefixed by “wp_ajax_.” Well, here is where we’re going to make use of that. This involves sending WordPress an action value in the JSON object we’re going to POST. “action” is the name of the key, and the value will be wp_ajax_our_function_name. So our JSON object that we’re going to send will at least contain the following…

{ action: save_cool_options }

If we wanted to call our function to get our options back from the database, we’d just have to change the “action” value to get_cool_options. We still have to indicate which function we want to call and that’s why we still have to send data to let WordPress know which function we want to use for interchanging data (even if it only involves getting data back).

So to handle this, we’re going to want to send our AJAX requests on the event that gets fired when one of the elements that we defined in our home.php file is clicked. So to do this, we’d create our jQuery file that we’re including in our plugin as follows…

jQuery(document).ready(function($) {

    $('#nbs-ajax-get').click(function(){
    
        var mydata = {
            action: "get_cool_options",
        };

        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        
        $.ajax({
            type: "POST",
            url: ajaxurl,

            dataType: "json",
            data: mydata,
            success: function (data, textStatus, jqXHR) {
                var name = data.name;
                var age = data.age;
                var color = data.favorite_color;
				
                $('#display').html('<p>Name: '+name+' Age: '+age+' Favorite Color: '+color+' </p>');
				
            },
            error: function (errorMessage) {

                console.log(errorMessage);
            }
        
        });      
	
    });	
	
    $('#nbs-ajax-save').click(function(){
    
        
        var mydata = {
            
            action: "save_cool_options",
            name: 'Bob Jones',
            age: 35,
            color: 'green'
        };


        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        
        $.ajax({
            type: "POST",
            url: ajaxurl,

            dataType: "json",
            data: mydata,
            success: function (data, textStatus, jqXHR) {
                if(data === true)
                    $('#display').html('<p>Options Saved!</p>');		
            },
            
            error: function (errorMessage) {

                console.log(errorMessage);
            }
        
        });    
    
    
    });

});

So as we can see on the click events of getting and saving our option, we’re sending our POST requests to ajaxurl (/wp-admin/admin-ajax.php) and then getting data back. Depending on the result, we’re updating the display panel. If we click the button/link to save options and then we open our database and look at the wp_options table, we can see that serialized JSON is saved under the cool_json_option identifier as serialized JSON. If we click the button/link to get these options, assuming all goes well, we can see the panel updated with the values that we specify.

Conclusion

Thus concludes our brief cursory overview of utilizing AJAX in WordPress. Hopefully you found it helpful. Obviously to use this in a more in-depth manner, we’d want to implement more sophisticated error handling and utilization of data in the UI. But hopefully this gives you a good start to being well on your way with using AJAX in WordPress. Take a look at the files(s) below by installing the plugin and playing around with it to see if using JSON in your WordPress admin panel is a good fit for you.

Download Files
]]>
https://9bitstudios.com/2014/04/ajax-and-wordpress/feed/ 0
Getting Data From the Wikipedia API Using jQuery https://9bitstudios.com/2014/03/getting-data-from-the-wikipedia-api-using-jquery/ https://9bitstudios.com/2014/03/getting-data-from-the-wikipedia-api-using-jquery/#comments Tue, 18 Mar 2014 13:09:55 +0000 https://9bitstudios.com/?p=948 Where would we be without Wikipedia? It’s hard to believe how we survived without this icon of the Internet. A novel idea of being an encyclopedia that anyone can edit, it’s always kinda interesting how you can look up an article about one thing and then end up somewhere completely different as you jump from article to article by clicking through its link-heavy content. But more important than that, Wikipedia is the authoritative mediating source of arbitration in all Internet arguments where the combatants usually don’t have anything other than extremely biased and inflammatory blogs as source material at hand and are too lazy to do their own research using actual respectable academic sources.

I’ve even heard that this spills over into the “real world.” Wikipedia has reported that it sees a huge spike in traffic coming in on mobile devices on Friday and Saturday nights and the underlying cause of this is believed to be attempts to settle disagreements than break out from drunken arguments in bars.

Wikipedia

So, all things considered Wikipedia usually has a good base on information just about any subject under the sun. And it got me thinking that a lot of websites and applications could benefit greatly from having an easy way to pull data from Wikipedia and use it to populate content. Fortunately, Wikipedia is built on some software that does provide an API for doing this. I remember seeing the super-slick Google Chrome experiment 100,000 stars put out by the folks at Google used Wikipedia excerpts as a brief description of each star. So I thought I’d look into the process of pulling data from Wikipedia using JavaScript and write it down because I figure someone else would find it useful at some point. Because other wikis are built upon the same foundation as Wikipedia, itself, this is not limited to getting data from Wikipedia alone. You can query other Wikis as well.

So to start, we’re going to need an article on Wikipedia to hit. Let’s use Jimi Hendrix. First we’re going to need to figure out what URL to call. I actually decided to use jQuery just because it’s a bit easier to parse through the returned data, but all of this could be done in native JavaScript if you wanted. So we’ll be making use of jQuery’s ajax method to make our asynchronous call.

So according to the API, the way that we call our Wiki API, is by using an endpoint like the following…

https://en.wikipedia.org/w/api.php?format=json&action=query&titles=Main%20Page&prop=revisions&rvprop=content

This is just one example. The API reference lists all of the possible actions. Reading through the docs, we can see that we’re probably going to want to specify JSON as the returned format. I chose the parse action and prop=text because I want to get the text out of the page. If we do this, rather than pulling down the entire page of text, let’s just say we want to get the top section (or blurb of Wikipedia data). To do this, we specify section=0. It’s probsbly outside the scope of this article to go into a detailed explanation of what each of these actions do specifically, so if all of this seems a little overwhelming and it feels like we’re moving too fast, take a look through the API documentation to get a more detailed description of what each of these components do.

So we know at the very least we’re going to need something like what is below…

$(document).ready(function(){

    $.ajax({
        type: "GET",
        url: "https://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text&section=0&page=Jimi_Hendrix",
        contentType: "application/json; charset=utf-8",
        async: false,
        dataType: "json",
        success: function (data, textStatus, jqXHR) {
            console.log(data);
        },
        error: function (errorMessage) {
        }
    });
});

If we try to make this call, nothing happens. This is because we are being blocked by the Same-origin policy. Just simple JSON is not going to suffice, so we’re going to need to trigger JSONP (JSON with Padding) by adding in a callback parameter callback=?.

Now, our AJAX call looks like the following…

$(document).ready(function(){

    $.ajax({
        type: "GET",
        url: "https://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text&section=0&page=Jimi_Hendrix&callback=?",
        contentType: "application/json; charset=utf-8",
        async: false,
        dataType: "json",
        success: function (data, textStatus, jqXHR) {
            console.log(data);
        },
        error: function (errorMessage) {
        }
    });
});

If we look in our console now, we can see we have data from Wikipedia! Wow! If we take a look at this object we can see that the part we are interested in is shown below.

{
    warnings: { ... },
    parse: {
        text:{
            *:{
                 "<div class="dablink">This article..."
             }
        }
    }
}

Those maybe are not the key/value pairs I would have chosen but oh well. This means that to get the markup that we need out of the object, we just have find the key. And if we add a div to our page with an id, e.g. <div id=”article”></div>, we can dump the markup into this div like so…

$(document).ready(function(){

    $.ajax({
        type: "GET",
        url: "https://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text&section=0&page=Jimi_Hendrix&callback=?",
        contentType: "application/json; charset=utf-8",
        async: false,
        dataType: "json",
        success: function (data, textStatus, jqXHR) {

            var markup = data.parse.text["*"];
            var blurb = $('<div></div>').html(markup);
            $('#article').html($(blurb).find('p'));

        },
        error: function (errorMessage) {
        }
    });
});

Note that there are a few other issues with our returned data (like warnings and links not working) so I’ve added a few extra items below to clean things up a bit…

$(document).ready(function(){

    $.ajax({
        type: "GET",
        url: "https://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text&section=0&page=Jimi_Hendrix&callback=?",
        contentType: "application/json; charset=utf-8",
        async: false,
        dataType: "json",
        success: function (data, textStatus, jqXHR) {

            var markup = data.parse.text["*"];
            var blurb = $('<div></div>').html(markup);

            // remove links as they will not work
            blurb.find('a').each(function() { $(this).replaceWith($(this).html()); });

            // remove any references
            blurb.find('sup').remove();

            // remove cite error
            blurb.find('.mw-ext-cite-error').remove();
            $('#article').html($(blurb).find('p'));

        },
        error: function (errorMessage) {
        }
    });
});

You can see the demo below. I have also wrapped this into a jQuery plugin called Wikiblurb.js that you can find on GitHub. The plugin has more options than our simple example here to make the portions of your wiki that you’re grabbing much more customizable.

View Demo
]]>
https://9bitstudios.com/2014/03/getting-data-from-the-wikipedia-api-using-jquery/feed/ 28
JavaScript PubSub https://9bitstudios.com/2013/08/javascript-pubsub/ https://9bitstudios.com/2013/08/javascript-pubsub/#comments Tue, 20 Aug 2013 01:18:47 +0000 https://9bitstudios.com/?p=891 One of the most useful implementations of software design patterns is the “PubSub” pattern. “PubSub” is a shorthand term for “Publish-Subscribe” which is a description of what the pattern is actually doing. The reason it is so useful is because it is so universal to how applications work. Basically the idea is that you have pieces of code (publishers) that say “something happened” — a user logged in, there was an error retrieving data, a button was clicked — it could be anything. Then you have pieces of code (subscribers) that run when those events occur. They are called subscribers because they subscribe to the event that gets published. PubSub implementations will also have some sort of capability for previously set subscribers to unsubscribe from an event. If that event happens again after this, the subscriber code will no longer execute.

Sometimes the terms used in PubSub pattern can vary. Sometimes “subscribers” are referred to as “listeners” because they “listen” for certain events occurring. You might recognize this in things like JavaScript’s addEventListener where you can attach callback functions to run when certain DOM events (such as button clicks and mouse hovers) occur. jQuery’s on, off, and trigger methods, are 3 methods that you can use in tandem to easily implemennt PubSub, with “on” being the subscribe functionality, “off” being unsubscribe, and “trigger” being the publish functionality. Backbone.js also uses on, off and trigger in its eventing system. Whatever the terms are and however the code is structured, ultimately these are just variations of the PubSub pattern and will nearly always follow similar ideas and principles.

A lot of examples of PubSub will use something that is pre-built, like jQuery’s methods mentioned above, or a library that implements it, but what we’re going to do in the following paragraphs is look at a raw JavaScript implementation of PubSub where we can do brodcasting (publishing) of our own custom events and attach subscribers to these events. This will give us a good understanding of how PubSub works under the hood. Our implementation will be pretty simple and it will only handle custom events that we name ourselves, but it could be taken and expanded upon to include more standard universal events such as mouse events, load events, error events, and others.

To start we will create an event channel function (object) that will have one object list where we will store the names of all of our events and the callback functions to run when those events are published. As a matter of personal preference, I’m going to be using the term “broadcast” to describe the publishing (or triggering) of our custom events. I borrowed this term from AngularJS, a client-sided MVC JavaScript framework developed by Google that I have worked with in the past. I used it when developing with AngularJS and I thought it was a good way to conceptualize what was happening. But ultimately it’s just a matter of personal preference in terminology. Subscribe and unsubscribe methods will be named “subscribe” and “unsubscribe” respectively.

So let’s start by creating our function…

function EventChannel(){ 
    this.list = {};
}

Pretty easy. On initialization of a new event channel, our event list will begin as an empty object because nothing has been subscribed yet. Now we need to add our methods to implement PubSub, and we’ll do this on the function prototype…

function EventChannel(){ 
    this.list = {};
}

EventChannel.prototype = {
    
    constructor: EventChannel,

    subscribe: function(name, callback) {
	
        if(!this.list[name])
            this.list[name] = [];

        this.list[name].push({callback:callback});
	
    },
    unsubscribe:function(name){
        if(this.list[name])
            delete this.list[name];
    },
    broadcast: function(name){
        
        for(var i in this.list){
            
            if(i === name) {
                var args = Array.prototype.slice.call(arguments);
                args.splice(0, 1);
                for(var j=0; j< this.list[name].length; j++) {
                    this.list[name][j].callback.apply(this, args);
                }
            }
        }
    }
	    
};

Let’s talk about what is happening in each of these. In our subscribe method, we take a name of an event and a callback function to run when the broadcast method corresponding to the name is fired. Below is how this looks in practice. We create our event channel add an event and then broadcast the event. The callback function that we passed into our subscribe method will run when we broadcast our event.


var channel = new EventChannel();

channel.subscribe('custom1', function(){
    console.log('Number 1 fired...');
});

channel.broadcast('custom1');

What if we wanted to pass arguments to a function. Well, our subscribe method is set up to handle this. The function arguments are accessed and put into an array using Array.prototype.slice.call(arguments). The first array element (which is the event name) is removed using the splice method because we won’t be needing it in our callback. So the rest of the arguments following the name get passed into our callback function sequentially.

channel.subscribe('custom2', function(one, two, three){
    console.log('Number 2 fired... With arguments ' + one + ' and ' + two + ' and ' + three);
});
channel.broadcast('custom2', 'one', 'two');

Going back to our original event channel prototype, when an event name and callback is added the event list property name is added to the object and callbacks are added to the property value as an array of objects. So so far our event list would look like the following…

list = {
    custom1:[
        { callback: function(){ console.log('Number 1 fired...'); } }
    ],
    custom2: [
        { callback: function(one,two,three){ console.log('Number 2 fired... With arguments... } }
    ]
}

We are doing things this way so that multiple callback functions can be added to a single event. These are pushed onto the array of objects as they are added. So if we wanted to, we could add another function to run on the same event…

channel.subscribe('custom1', function(){
    console.log('This is another function that is running on the custom1 event...');
});

which would transform the object into the following…

list = {
    custom1:[
        { callback: function(){ console.log('Number 1 fired...'); } }, 
        { callback: function(){ console.log('This is another function that is running on the custom1 event...'); } } 
    ],
    custom2: [
        { callback: function(one,two,three){ console.log('Number 2 fired... With arguments... } }
    ]
}

Now if we broadcast the custom1 event again, both of the callback functions will execute.

Below we add another event and broadcast all of our custom events. Then we unsubscribe from one event and broadcast all of our custom events again. The event that was unsubscribed from is removed.

channel.subscribe('custom3', function(){
    console.log('Number 3 fired...');
});
channel.broadcast('custom1');
channel.broadcast('custom2');
channel.broadcast('custom3');

channel.unsubscribe('custom3');
console.log('Unsubscribed from custom3... trying again....');

channel.broadcast('custom1');
channel.broadcast('custom2');
channel.broadcast('custom3');

Notice that our callback with arguments has all the arguments coming up as undefined now because we did not specify them in this last go around of broadcasting our events.

When we call unsubscribe on our event channel the entire event is removed (even if there were multiple callbacks added to the event). The code just finds the property in the list matching the name passed in to the unsubscribe method and removes that property. Our system is not yet sophisticated enough to remove individual callback functions from each event. The whole shebang is removed. But with a little more dev work and a little restructuring of code, we could definitely implement something that could do this if it was needed.

So there you have it… JavaScript PubSub. Implement it in you’re applications. You’ll be happy you did!

]]>
https://9bitstudios.com/2013/08/javascript-pubsub/feed/ 2
jQuery Isotope Tutorial https://9bitstudios.com/2013/04/jquery-isotope-tutorial/ https://9bitstudios.com/2013/04/jquery-isotope-tutorial/#comments Fri, 26 Apr 2013 15:40:35 +0000 https://9bitstudios.com/?p=831 I love jQuery Isotope from Metafizzy. As a longtime fan of the Springfield Isotopes, who wouldn’t love an isotopes jQuery plugin? I’ve enjoyed it so much that I bought the developer license so I could use it for my own commercial applications and themes. It’s an outstanding plugin and a lot of the popular templates and themes on sites like Theme Forest use it to create things like filterable portfolios or display content in other dynamic ways.

The Isotope homepage is awesomely flashy and shows some slick implementations on how you can use the plugin. However, because there is a lot going on there on the page, I think there’s the potential that it might be a bit challenging for users who are new to jQuery to find the simplest way to use it in the code examples. There is a lot of styling and code to sift through. Perhaps, it comes down to a matter of personal preference, but I’m more of a fan of the “Start really simple and plain and then build up from there” approach. So I thought I’d show a really simple, very vanilla example of jQuery Isotope so that you can get it up and running in your own applications as soon as possible. You can add more complexity and styling from there if you so desire. The demo of what we’ll be creating and the corresponding download are below…

View Demo Download Files

We’ll be creating a filterable portfolio-style implementation using jQuery Isotope.

So let’s start by downloading jQuery Istotope from GitHub. From there we can grab the .js file and include it in our project like so…

<!DOCTYPE html>
<html>
<head>
<title>jQuery Isotope</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script src="js/jquery.isotope.js" type="text/javascript"></script> 
</head>
<body>

<script type="text/javascript">


</script>
</body>
</html> 

Next we are going to want to add the following JavaScript to our page in-between the <script> tags in the markup…

$(window).load(function(){
    var $container = $('.portfolioContainer');
    $container.isotope({
        filter: '*',
        animationOptions: {
            duration: 750,
            easing: 'linear',
            queue: false
        }
    });

    $('.portfolioFilter a').click(function(){
        $('.portfolioFilter .current').removeClass('current');
        $(this).addClass('current');

        var selector = $(this).attr('data-filter');
        $container.isotope({
            filter: selector,
            animationOptions: {
                duration: 750,
                easing: 'linear',
                queue: false
            }
         });
         return false;
    }); 
});

We’re attaching the jQuery to the $(window).load event so that Isotope can calculate widths correctly based on the image sizes. Basically, we have 2 “sections” of jQuery here. The first section is necessary for us to initialize Isotope on our page and define the container that’s in it. Then we have what will be our filter for categories and we have our click event tied to $(‘.portfolioFilter a’).

Create a folder called “css” and add a style.css file. Add the following CSS to it…

body {
    font-family: Arial;
}

.portfolioFilter a { 
    margin-right: 10px; 
    color:#666;
    text-decoration:none;
}

.portfolioFilter a.current { 
    font-weight:bold;
}

img {
    margin:5px;
}

.isotope-item {
    z-index: 2;
}
.isotope-hidden.isotope-item {
    pointer-events: none;
    z-index: 1;
}
.isotope,
.isotope .isotope-item {
  /* change duration value to whatever you like */

    -webkit-transition-duration: 0.8s;
    -moz-transition-duration: 0.8s;
    transition-duration: 0.8s;
}
.isotope {
    -webkit-transition-property: height, width;
    -moz-transition-property: height, width;
    transition-property: height, width;
}
.isotope .isotope-item {
    -webkit-transition-property: -webkit-transform, opacity;
    -moz-transition-property: -moz-transform, opacity;
    transition-property: transform, opacity;
}

Here we are using CSS3 transitions to make the filter effect.

Lastly of course we would not want to forget our markup. Add the following code after the opening <body> tag in the markup…

<div class="portfolioFilter">

    <a href="#" data-filter="*" class="current">All Categories</a>
    <a href="#" data-filter=".people">People</a>
    <a href="#" data-filter=".places">Places</a>
    <a href="#" data-filter=".food">Food</a>
    <a href="#" data-filter=".objects">Objects</a>

</div>

<div class="portfolioContainer">

    <div class="objects">
        <img src="images/watch.jpg" alt="image">
    </div>

    <div class="people places">
        <img src="images/surf.jpg" alt="image">
    </div>	

    <div class="food">
        <img src="images/burger.jpg" alt="image">
    </div>
	
    <div class="people places">
        <img src="images/subway.jpg" alt="image">
    </div>

    <div class="places objects">
        <img src="images/trees.jpg" alt="image">
    </div>

    <div class="people food objects">
        <img src="images/coffee.jpg" alt="image">
    </div>

    <div class="food objects">
        <img src="images/wine.jpg" alt="image">
    </div>	
	
    <div class="food">
        <img src="images/salad.jpg" alt="image">
    </div>	

</div>

The important pieces (as you can see) are in the data-filter attribute in the filter and in the classes of the container. Notice how the classes in the container match the data-filter attribute in the filter. These values need to match exactly and this is, in essence, how you categorize the objects using Isotope. If you want to put objects into a particular category, you simply need to add the classes that you want and separate them by spaces. Some objects can have one category, some have multiple categories.

Now, this might seem like an ugly unstyled package right now, but this gives you all of the basics to build off of from here. You can now add the elements to it that you need to make it fit with both your front-end framework and your theme styles. You’ll probably also want to update your category names and use your own image, but this should be a good starting point.

]]>
https://9bitstudios.com/2013/04/jquery-isotope-tutorial/feed/ 165
Backbone.js Routers https://9bitstudios.com/2013/04/backbone-js-routers/ https://9bitstudios.com/2013/04/backbone-js-routers/#comments Thu, 11 Apr 2013 23:23:48 +0000 https://9bitstudios.com/?p=820 In what follows, we are going to look at Backbone.js routers. Routers are a great place to start whenever you begin developing a Backbone application (or any application for that matter) because you can figure out what URLs and sections your app will need and add hooks in your code to respond to them. It helps define application structure, much like a flow chart would.

The files for demo and download for the following discussion can be found below if you’d like to follow along…

View Demo Download Files

Backbone.js uses routers to execute certain actions when a user goes to a certain URL within a Backbone application. Backbone applications all use routes that follow a # character in the URL. The # might be familiar to you if you’ve ever used it as a named anchor to link to part of the current document without going to a new URL. This is very prevalent in pages that have tables of content at the top (e.g. like in Wikipedia articles), where the links at the top take you to a place on the same page further down. That’s what’s going to happen with Backbone. We’re going to stay on our same page, but we’re going to set up our JavaScript such that Backbone listens for the user going to these links. When the user clicks on different links within the application, instead of going to a different place on the page, we’ll be executing different portions of JavaScript in our code. That’s how a “client-side JavaScript application” essentially behaves.

So let’s say we have the following HTML page where we’ve loaded up Backbone. Note that we’re also going to want to load Backbone’s dependency library Underscore.js. We also want to load jQuery because jQuery has a really nice on method that is useful for catching events thrown by Backbone. If that last sentence seems little unclear to you at this point, you’ll see what we mean a bit later on..

We’re going to be adding code in the <script> section at the bottom. In a larger scale Backbone application, you’d probably have all of your routers in a separate file called “routers.js” or something like the.

<!DOCTYPE html>
<html>
<head>
<script src="js/jquery.js" type="text/javascript"></script> 
<script src="js/underscore.js" type="text/javascript"></script> 
<script src="js/backbone.js" type="text/javascript"></script> 
</head>
<body>

<script type="text/javascript">

</script>
</body>
</html> 

What we need to do first is define some routes. In the <script> section add the following code…

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
  }
});
var router = new Router;

What we have done here is create a new router and have given it a routes. The “routes” object follows the following format…

url : Name of event that fires

What does this mean? Well the string on the left is the URL that a user of your application is going to and the string on the right is the name of the event that is fired off when that URL is accessed.

So let’s look at our first example. This “” is a blank string. This means you are going to the root URL of your Backbone.js application. So, for example, if you had a BackboneJS application hosted at https://yourwebsite.com/. This event would fire when the user went to https://yourwebsite.com/ (the home page with no additional parameters or sub-page locations). The event would not fire if they went to https://yourwebsite.com/#/newUser or https://yourwebsite.com/#/somethingElse because the strings following the hash character would not be empty.

Next we want to add the following right after the code we added in the previous step…

router.on('route:home', function() {
  alert('We have loaded the home view');
});

Backbone.history.start();

Here we are using the jQuery on method mentioned earlier. Backbone.history.start(); is just a method that backbone uses to say “Start listening for routes.” Before routers will work in Backbone, you have to add this method. Just something to remember.

Now in your brwoser, go to your home URL. If you had this application hosted at https://yourwebsite.com/, you’d just go to https://yourwebsite.com/. If we do this, you shold see the alert fire meaning we are responding to the event “route:home”.

New Routes

Now let’s add another route so that our code looks like the following…

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
    "new": "createNew"
  }
});
var router = new Router;

Now in the location where we added the previous “on” method, place the following code below that (but before the Backbone.history.start(); statement) …

router.on('route:createNew', function() {
    alert('We are going to create something new here...')
});

Now in your browser, after your home URL add the the following…

/#/new

Such that your URL will be something like https://yourwebsite.com/#/new, if you go to it, you can see that the code in our method fires. What if you go to https://yourwebsite.com/#/createSomething. You’ll see that the code does not fire? Backbone has not matched either of the routes we have defined so no code is being executed.

Parameters & Splats

If you’ve ever done web development utilizing dynamic pages of any kind, you know that the content on pages are populated depending on the parameters that get passed in. So, for example, if you had a social profile of some sort, you might have something like https://9bitSocialNetwork.com/profile?id=2345&view=all. In that case, the parameters “id” and “view” would be used by the website to determine who’d profile to show and how to show it. You’d have one view that defined the layout and what you’d show in that view would depend on the specific parameters.

Backbone.js applications have the ability for you to pass in parameters as well.

Let’s add yet another route such that our code looks like the following…

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
    "new": "createNew"
    "edit/:id": "editItem",
  }
});
var router = new Router;

And in the place where we have added our “on” methods add the following (but, again, before the Backbone.history.start(); statement)…

router.on('route:editItem', function(idParam) {
    alert('We are going to edit entry number ' + idParam);
});

So obviously we are going to try to catch an event when the user goes to https://yourwebsite.com/#/edit, but what is that :id thing? This is how Backbone defines a parameter. Backbone is looking for a specific item to follow the https://yourwebsite.com/#/edit. What happens if we go to the following URL?

https://yourwebsite.com/#/edit

Nothing happened. Why is that? It’s because Backbone is expecting a parameter as we defined in our route. So now try this…

https://yourwebsite.com/#/edit/1

Now we see that backbone is catching the id parameter and it’s getting passed into the function. This is how we can populate a single view in Backbone and have variable content passed in. What if we went to the following URL…

https://yourwebsite.com/#/edit/1/steve

Again nothing happens because this is passing in 2 parameters. To catch it we’d have to add another route

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
    "new": "createNew"
    "edit/:id": "editItem",
     "edit/:id/:name": "editItemAndName",
  }
});
var router = new Router;

And catch the event here…

router.on('route:editItemAndName', function(idParam, nameParam) {
    alert('We are going to edit entry number ' + idParam + 'and name ' + nameParam);
});

Now if we go to the URL https://yourwebsite.com/#/edit/1/steve we can see that the event gets caught.

Backbone also has a special variable type of parameter called a “splat.” A splat looks like the following…

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
    "new": "createNew"
    "edit/:id": "editItem",
    "edit/:id/:name": "editItemAndName",
    "download/*anything": "downloadItem"
  }
});
var router = new Router;

A spat basically means “match anything and everything,” so as a result if you were going to use a splat you’d want to set it as the last item in your defined route.

So if put a place to respond to this event…

router.on('route:downloadItem', function(anythingParam) {
    alert('What is stored in anything is ' + anythingParam);
});

If we pass anything after “/#/download/” all of it (slashes and all) will get passed to the anythingParam argument. If we go to https://yourwebsite.com/#/download nothing happens because Backbone is still expecting a parameter. However if we go to something like https://yourwebsite.com/#/download/path/to/my/file we can see that path/to/my/file gets passed into the parameter (slashes and all)

Now that we have defined some routes (and can easly add as many more as we want to) we are well on our way to creating a nice Backbone.js application!

Better Code Organization

Now that we have a good introductory baseline on what is happening with Backbone routers, we should take a quick look at an alternate way of organizing Backbone routes in code. We can actually respond to the events within our router and don’t need separate jQuery “router.on” for each route outside of router. For example….

var Router = Backbone.Router.extend({
  routes: {
    "": "home", // url:event that fires
    "new": "createNew"
    "edit/:id": "editItem",
    "edit/:id/:name": "editItemAndName",
    "download/*anything": "downloadItem"
  },

  home: function() {
      alert('We have loaded the home view');
  },

  createNew: function() {
     alert('We are going to create something new');
  }

  editItem: function(idParam) {
      alert('We are going to edit entry number ' + idParam);
  }

});
var router = new Router;

Notice here that we have named some properties with the exact same string names defined in our routes. You can use this approach as well if you prefer. This implementation tends to make the code a bit cleaner because everything is nicely encapsulated within our router definition.

Navigate

A Backbone.js router discussion would be incomplete if we didn’t look at the very important router method navigate. The navigate method is basically how you redirect to other locations in your Backbone application. This becomes very important when you are saving, updating, or deleting data. Often times when you, say, add a new user by filing out a form in an application and hitting the “Submit” button, the application will redirect back to the list of all users with a message that says “User Added” or something of the sort. If you didn’t do this, the person using your application would still be on the form page after hitting “Submit” which is not the best user experience because they would have to then manually navigate themselves back to the home screen.

Take a look at the implementation below. This is how navigate is called.

router.navigate('', { trigger:true });

What does this mean? This means navigate to the homepage (i.e. the ” route). Navigate by itself does not actually execute the code that we have defined in our router. All it will do is update the URL. That is why we have to pass in the { trigger: true } option to trigger the code we have defined in our route based on the path we have given. We could direct users to any location in our application that we want using navigate. The code below would navigate to the edit form for a user with ID #4…

router.navigate('edit/4', { trigger:true });

Where would you use something like this in an actual Backbone application? It’s outside the scope of this tutorial to build an entire application showing all of the places where you would use navigate, but as a brief demo take a look at the code below. In this example we are deleting an artist inside of a Backbone View. After the artist is deleted we navigate back to the homepage on successful deletion.

var ArtistDeleteView = Backbone.View.extend({
    el: '.deletePage',
    events: {
        'click .delete': 'deleteArtist'
    },
    deleteArtist: function (ev) {
        this.artist.destroy({
          success: function () {
            console.log('Artist Deleted');
            router.navigate('', {trigger:true});
          }
        })
    },
});

For more info on Backbone routers, see the documentation on the official Backbone.js site here

]]>
https://9bitstudios.com/2013/04/backbone-js-routers/feed/ 2
Concatenate and Compress JavaScript with UglifyJS https://9bitstudios.com/2013/03/concatenate-and-compress-javascript-with-uglifyjs/ https://9bitstudios.com/2013/03/concatenate-and-compress-javascript-with-uglifyjs/#respond Thu, 28 Mar 2013 22:42:26 +0000 https://9bitstudios.com/?p=796 The benefits of using something like RequireJS to asynchronously to load your project’s JavaScript was discussed previously. However, if you wish to load JavaScript in the more conventional way (that is, just sticking a script tag or tags in the browser) there are quick and lightweight ways to make this an efficient and viable option as well. These methods involve concatenating and compressing (minifying) your JavaScript files into one script file. At the end of the process you’ll only need to end up loading this one large script file (which is a lot quicker than loading numerous smaller scripts file) Additionally, if you concatenate your JavaScript files in a particular sequential order, you can easily make this a way to manage your dependencies… you just need to make sure that you load the dependency libraries before you load the libraries that require them. The tools we will look at in what follows makes this a fairly simple process.

To accomplish this in my workflow I use something called UglifyJS. It’s a simple package that runs in a Node.js environment. Node.js is a platform that allows you to run JavaScript system level applications on a server environment (or in this case, on our local machine). We can open our terminal and type something like “node myJavaScriptFile.js” and run some JavaScript we have written to do all kinds of neat stuff… all outside of the browser. So first things first, go and download and install Node.js if you haven’t already.

After that navigate to the directory where node is installed and run…

npm install uglify-js -g

nmp (which stands for Node Package Manager, is a way of quickly installing the latest version of Node applications). You may have seen this elsewhere with Python’s pip command or Ruby’s gems. The -g parameter stands for global, which will enable you to run UglifyJS from anywhere on your machine.

Now what you can do is simply run the command according to the following format in the directory where your JavaScript files are…

uglifyjs -o scripts.js javascript-file1.js javascript-file2.js javascript-file3.js

In the example above, javascript-file1.js, javascript-file2.js, and javascript-file3.js will all be concatenated and compressed into a file named scripts.js file in the order in which they were set. So following this convention, you can load your dependencies where they are important in your JavaScript projects. Backbone.js, for example, has a hard dependency on Underscore. So you’d want to add Underscore *before* you’d add Backbone if you were doing a Backbone project. Also, a lot of times developers like to have jQuery available to them in their Backbone models, collections and views. So we could add jQuery into our list of files as well resulting in something like the following…

uglifyjs -o scripts.js underscore.js jQuery.js backbone.js

** Note that all of these files (underscore.js, jQuery.js, backbone.js) have to exist within the directory that you’re running the command from. scripts.js will be created if it doesn’t exist and overwritten if it does.

But whatever JavaScript you decide you need to include, all you have to do once the UglifyJS build process is complete is load the scripts.js file in your HTML. You can name this file whatever you want (it doesn’t have to be scripts.js). What I usually do in my workflow is set up a .bat file (and call it build-js.bat or something) that has all of my files and their dependencies set in the order that I need them. Then when I need to deploy my JavaScript to production I just run the .bat file.

So whichever way you choose to do it (either using the asynchronous module definition (AMD) pattern using something like RequireJS or using a tool like UglifyJS or using another similar solution) there are definitely good ways to load your handle your project’s JavaScript JavaScript in an efficient and effective manner.

]]>
https://9bitstudios.com/2013/03/concatenate-and-compress-javascript-with-uglifyjs/feed/ 0