Was assigned to a team to create an awesome app called I Was There (iwasthereproof.com). My primary focus was the mobile site application development. I also worked quite a bit on the main site application when finished with the mobile web app.
Responsible for testing and debugging on multiple platforms; mimicking the main site as efficiently and user friendly as possible; managing redirections for mobile platforms; creating a mobile friendly shopping cart with purchasing capabilities; responsible for researching limitations of various platforms and how to overcome them.
Organized and contained…
My beef with JavaScript is that it works (sometimes) no matter how ugly the code is behind the screen. I’ve set out to organize my JavaScript to meet these requirements:
JS MVC? Of course, well, sorta…
Since I regularly use jQuery for my scripts, I am going to explain this as if I am using jQuery, but these scripts can easily be translated to a non-jQuery environment.
I create a single loading script, aptly called initiate_scripts.js, in a “js” folder.
Within that folder, I create another folder called “controllers”. The “controllers” folder is where I put my code and third party script files.
First I create a globals namespace -
var GLOBALS = {
initiated = false, // My document.ready check
site_url: ‘http://localhost/’, // Include trailing slash controller_loc: ’js/controllers/’
}
Then my initiate function, not namespaced, accounting for if I want to load JS files locally, absolutely, or from an external source -
function initiate(jsFile) {
if( jsFile.indexOf(‘/’) < 0 ) {
jsFile = GLOBALS.site_url + GLOBALS.controller_loc + jsFile;
}document.write(‘<script type=”text/javascript” src=”’+ jsFile + ‘”></scr’ + ‘ipt>’);
}
Now I call my controllers -
initiate(‘form_controller.js’);
initiate(‘capture_controller.js’);
And my repository files -
initiate(‘https://code.google.com/apis/gears/gears_init.js’);
And my plugins/third party
initiate(‘third_party_scripts.js’);
As you can see, I am loading each file dynamically… None of the files should self-execute (I’m covering that in the next section). This is merely to keep my <script> area clean in my html. It’s also easy to add another .js by calling the initiate() function in this script file. You want to make sure you are calling jQuery first before initiate_scripts.js in your HTML file.
In each controller, I organize the code as follows -
VAR CONTROLLERNAME_CONTROLLER = {
variable_one: ”,
variable_two: ”,
initiate: function() {
…
// Put the execute code here
…
}, //initiate()
anotherfunction: function(){
…
…
…
} //anotherfunction()
Referred to as Namespacing, this allows me to organize everything into one controller. If I needed to validate a form, I would put everything needed for that validation in a file called - form_controller.js and name it var FORM_CONTROLLER = {}
Why am I yelling? That’s a common best practice for Namespacing: capitalize the controller object name.
Now I know what some of you are thinking, “This isn’t MVC?”… I know, but for the rest of this post I will still use the terms controllers and methods, I like it that way. There are other options out there, some that require an extra .js file. However, this is a nifty little way to achieve the concept of MVC without much effort. Where do the models come to play? I’ll typically put all of my “ajax” calls in a separate file, namespaced after the controller (i.e. FORM_MODEL), but I just don’t cover that in detail in this post.
Wide load! Why load?
This one was easy. I will also explain why I have an “initiated” variable.
We’re still in initiate_scripts.js, now let’s prepare our document ready call -
jQuery(document).ready(function($) {
…
…
…
});
Now in the ready function, we’re going to make sure it hasn’t been called before -
if(!GLOBALS.initiated) {
GLOBALS.initiated = true;…
…
…
};
Why do I check to see if it’s already been initiated? It was an issue I ran into a while back using Facebook Connect. When initiating FB’s Connect via JS I managed to trigger jQuery’s document ready function twice, this caused much heartache (double event handlers etc). So it’s a simple few lines of code that won’t hurt anyone, and is a backup in case it happens to me again.
Now the fun part, initiate each controller as the page needs. If you need to run a your form validator, why initiate it unless you need it?
if( ($(‘#myform’).length > 0) ){
FORM_CONTROLLER.initiate();
}
I dynamically put classes on my <body> tag using PHP, this helps me easily target the home page -
if( $(‘body’).attr(‘class’).indexOf(‘home’) >= 0 ){
BANNER_CONTROLLER.initiate();
}
Conclusion
Using these methods I’ve been able to create a very clean, easy to readJavaScript environment. My file structure keeps all .js files in one area:
/js
/controllers
/form_controller.js
/plugins.js
/initiate_scripts.js
Namespacing keeps everything out of the global space (with only a few exceptions). My “GLOBALS” namespace allows me to have global variables accessible to each controller via GLOBALS.global_var. While JS files are loaded, they are not executed, with internet speeds these days I have no problem having the user download the file, but this lifts some of the number crunching the local browser might have to do on JS heavy sites.
Lazy Shortcuts and tricks
This might not be best practice, but I use a few lazy shortcuts to make my typing go a little faster.
In the local method variable call line I use this shortcut -
var vars = FORM_CONTROLLER, func = vars;
Now when I want to access a controller wide variable or sibling method I call them via vars.variable or func.internal_function() respectively instead of FORM_CONTROLLER.variable and FORM_CONTROLLER.internal_function(). “vars” and “func” are the same, but I use them separately to help me visually separate them.
Notice I said variable line. All of my variables are called in one JS line like so:
var vars = FORM_CONTROLLER, func = vars,
var1,
var2,
var3 = “value”;
I multiline them for readability at first (notice the commas, making JS read them as one line), then at launch I crunch them down. Repeating “var” throughout is a waste of characters.
At the end of each method I always comment the name of the function and variables/types expected -
internal_function: function(var1, var2, var3) {
…
…
…}, // internal_function(var1 = int, var2 = str, var3 = array)
You’ll notice in my document.write function that my end </script> tag is broken
document.write(‘<script type=”text/javascript” src=”’+ jsFile + ‘”></scr’ + ‘ipt>’);
It’s important to do this, otherwise the browser will assume the end of the script and stop translating the rest of the code as JavaScript.
Thank you for reading, feel free to contact me with any comments about observations/suggestions you have or mistakes/errors you find.
I had an awesome chance to work on a special project for the Kettle Brand Potato Chips.
I was tasked with creating a single use website for a contest Kettle Brand was running. I hand coded my own MVC architecture to handle some of the dynamic content. The website included:
To all you food product package designers out there… Did it ever occur to you that I never thought that the taste changed just because the box did?
Ooh look, a new box, now it must taste like junk!
Why even tell me that it’s a new look? If I eat the product enough I’ll know! If I’ve never eaten your product, well then, I couldn’t care less that it has a new box color and a fancy three-tone gradient instead of a two-tone. Borderline insulting my intelligence there!
Some day I may grow tired of posting well-produced, tilt-shift, fast-forward films. Today, however, is not that day.
Coachelletta by Sam O’Hare.
GRACEPOLARIS – 2010
Designed and Developed new website for gracepolaris.org.
Attached to a Wordpress backend.
LANGUAGES: xhtml, css, php, mysql, javascript/jquery
SOFTWARE: adobe photoshop cs4, adobe illustrator cs4, wordpress, crimson editor, wamp
SITE KEYWORDS – 2010
Developed a plugin for wordpress to use with gracepolaris.org. Client needed keyword functionality (similar to the AOL keywords).
LANGUAGES: php, mysql, javascript/jquery
SOFTWARE: wordpress, crimson editor
GRACE MEDIA GROUP – 2009
Designed and developed online music store using the BusinessCatalyst suite at gracemediagroup.org.
LANGUAGES: xhtml, css, javascript
SOFTWARE: adobe photoshop cs 3, crimson editor, business catalyst
So I finish the murder mystery show I was watching… Then I remembered, all I need to do it look out my window for my entertainment! This was outside my window immediately after my show.
Every Wednesday through the summer there is a Denver Cruise. Hundreds of people get on bikes and just cruise around downtown Denver. This was my view!
The view from above is simply majestic… Trip up Mt. Evans on September 6th, the 14th highest peak in Colorado and has the highest paved road in North America. Our way down Mt Evans we could see the Boulder, CO Fourmile Canyon Fire.
A few other photos from Breckenridge, CO on the same trip.