JavaScript and jQuery

If you are new to JavaScript or use it everyday it’s worth re-reading this article every once in a while for a refresher: A re-introduction to JavaScript from the Mozilla Developer Network.

Script Tags

Inline

<script>/* JavaScript code here */</script>

Referenced


<script name="myScript" src="path/or/url/to/myScript.js"></script>
  • When referencing a file, no javascript code should be put inside the tag.
  • The name attribute is optional and is intended for humans only.

Dynamic

<script>
    document.write('\x3Cscript src="foo.js">\x3C/script>');
</script>

You can dynamically create a script tag and run it.

Overview

The HTML script tag is used to identify and run javaScript code.

  • The javascript defined by a script tag is compiled and run immediately after the tag is recognized by the browser.
  • You can use as many script tags in a document as you feel necessary.
  • The browser reads each script tag in the order in which it appears in the document. If a script is defining functions or data that are used by another script, then the defining must be done before use. So the defining scripts must come before the using scripts.
  • type="text/javascript" is required in the script tag in HTML 4 and XHTML, but optional in HTML5.
  • Do not use the <!-- //--> hack with scripts. It was intended to prevent scripts from showing up as text on the first generation browsers Netscape 1 and Mosaic.
  • CDATA is needed for XHTML pages if the script has any HTML characters like < and > in it. <script>//<![CDATA[ ...code... //]]></script>
  • JS security ( Same-origin policy ) prevent scripts hosted at other domains from running unless you setup CORS.
 

More Resources

Documentation Standards

Messaging

Alert

Alert a message to the browser.

alert('You are being alerted!');

Confirm

Open a confirmation message in the browser.

if( confirm('Are you sure?') )
{
    // Continue...
}

Console Log

Log text or objects to the console.

// Text
console.log( 'loggin text here' );

// Object
console.log( myObj );

// Testing for 'window.console' prevents errors
// in browsers without console.
window.console && console.log('hello');

Data Types

  • Number
  • String
  • Boolean
  • Symbol (new in ES2015)
  • Object
  • Function
  • Array
  • Date
  • RegExp
  • null
  • undefined

Primitives

Primitives are not an object and have no methods or properties. There are 6 primitive data types:

Type Value Comment
string “Hello” “Hello” is always “Hello”
number 3.14 3.14 is always 3.14
boolean true true is always true
boolean false false is always false
null (object) null null is always null
undefined undefined undefined is always undefined

Methods

// Call a function dynamically.
window[varClassName][varFunctionName]( params );
var returned = window[varClassName][varSubClassName][varFunctionName]( params );

Objects

An object is a collection of properties. Properties can reference an object, a primitive, or a method.

There are two basic ways to create an empty object:

var obj = new Object();

And:

var obj = {};

These are semantically equivalent; the second is called object literal syntax, and is more convenient. This syntax is also the core of JSON format and should be preferred at all times.

Variables

The simplest object in JavaScript is a variable. Variables can contain single values:

var person = "John";

Properties

Properties are a collection of named values or key-value pairs grouped under a named object.

This object is a like a collection of variables.

var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
// Create an object.
var obj = {};
// Assign a property and it's value to an object.

// Array notation.
jsonObj["myProperty"] = value;

// Dot notation.
jsonObj.myProperty = value;
// Count the number of properties in an object.
$var total_properties = Object.keys( my_obj ).length;
// Check if a property exists in an object.
if( 'prop_name' in obj )
{
    console.log( prop_name + ' exists!' );
}

if( jsonObj.hasOwnProperty( 'prop_name' ))
{
    console.log( prop_name + ' exists!' );
}
// Iterate over a json object.

// jQuery.
$.each( obj, function( i, property )
{
    // Log the whole property.
    console.log( property );

    // Log a sub-property of the property.
    console.log( property.sub_property );
});

// Native javascript.
for(i in jsonObj){
    var key = i;
    var val = jsonObj[i];
    for(j in val){
        var sub_key = j;
        var sub_val = val.j;
        console.log(sub_key);
    }
}

JSON stands for JavaScript Object Notation. “JSON object” is a vague term. A JSON object is really a string, a fragment of text that is written in JSON format, that has yet to be turned into the object it represents.

/**
 * Converts a json object to an array object.
 */
function get_array( data_obj )
{
    var array_obj = [];

    for( var key in data_obj ){
        if ( data_obj.hasOwnProperty(key) ){
            array_obj.push( { name:key, value:data_obj[key] } );
        }
    }

    return array_obj;
}

Tests

// Test if a DOM element exists.
if ($('selector').length)
{
    console.log('element exists!');
}
// Test if a function exists.
if (typeof myFunctionName === "function")
{
    console.log( myFunctionName + ' exists!');
}

if (typeof window[class_name][sub_class_name][method_name] === "function")
{
    console.log( 'Class function exists!');
}
// Test for a valid email address.
// http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
var emailaddy = 'a@b.com';
if (emailaddy.match(/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/))
{
    console.log('email is valid!');
}

Event Listeners and Binding


/**
 * jQuery 'On' Delegated
 *
 * An event-delegation approach to 'on' attaches an event handler
 * to only one outer element (#my-nav), and the inner element's
 * event ('click' on 'a.item') only bubbles up one level.
 * This also allows you to dynamically add new "a.item" elements
 * to '#my-nav' which will immediately bind.
 */
$( "#my-nav" ).on( "click", "a.item",
    function( e )
    {
        e.preventDefault( e ); // Stops the normal element action.
        console.log( $( this ).text() );
    }
);

/**
 * jQuery 'On'
 *
 * 'on' can attach to almost any element and hear almost any event.
 */
$( "a.button" ).on( "click",
    function( e )
    {
        e.preventDefault( e ); // Stops the normal element action.
        console.log( $( this ).text() );
    }
);

/**
 * Native Javascript Event Listener.
 *
 * elem: The object you want to listen to.
 * type: The event you want to listen to.
 * functionName: The name of the function to call when the event is fired.
 */
var addEvent = function(elem, type, functionName)
{
    if (elem == null || typeof(elem) == 'undefined') return;
    if ( elem.addEventListener ) {
        elem.addEventListener( type, functionName, false );
    } else if ( elem.attachEvent ) {
        elem.attachEvent( "on" + type, functionName );
    } else {
        elem["on"+type] = functionName;
    }
};

// Use examples:

// Bind a function to the 'window' 'load' event.
addEvent( window, "load", someFunctionName );
 
// Bind a function to the 'window' 'resize' event.
addEvent( window, "resize", someFunctionName );

Attaching a function to an event like so: window.onload = myFunc; works, and many people do it, however, only the last function attached to an event will get executed. This means that if there is another function further down the code which also attaches to the same event, only the last function attached will actually fire with the event. To prevent this conflict it is best to attach a listener, not a function, to an event.

This native JavaScript function can be used to add event listeners to elements.
It tests if the element exists and which function (addEventListener or attachEvent) to use with it, much like what happens behind the scenes in jQuery for stuff like jQuery(window).resize();.


/**
 * Inline Binding
 *
 * Attach a function directly to an inline element's event.
 */
<a href="javascript:void(0)" onclick="myJsFunction();">Run JavaScript Code</a>

DOM Elements

Create


// Create a script link tag in the head.
// Create the tag.
var new_script_link = document.createElement('script');
// Add attributes to the tag.
new_script_link.src = 'url-to-my-new-script-file.js';
new_script_link.type = 'text/javascript';
new_script_link.id = 'new-script-link-id';
// Attach the created tag along with it's attributes to the DOM.
document.getElementsByTagName('head')[0].appendChild( new_script_link );

// Creates a form element to post data dynamically.
function postData(path, params)
{
    var form = document.createElement("form");
    form.setAttribute("method", "post");
    form.setAttribute("action", path);
    form.setAttribute("target", "_blank"); // This opens the form in a new tab.
    
    for(var key in params)
    {
        if(params.hasOwnProperty(key))
        {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);
            form.appendChild(hiddenField);
        }
    }
    
    document.body.appendChild(form);
    form.submit();
}

// Use.
postData( 'http://mysite.com/something/', { customerId: "168325" } );

Read


// Get the current page URL
var url = window.location.href;

Update


// Redirect to another URL
window.location = "http://www.yoururl.com";

// Update the "src" attribute on an "img" element.
document
    .getElementById('myElementId')
    .src = 'http://mysite.com/mynewimage.jpg';

Time and Timers


// Time-Outs
// Calls a function or executes a code snippet after a specified delay.
setTimeout( function(){
    // Do something here.
}, 5000);

// Or...
function message(){ alert( 'Hi' ); }
setTimeout( message, 1000 );

// Timed Intervals
// Calls a function or executes a code snippet repeatedly,
// with a fixed time delay between each call to that function.
// Returns an intervalID.
var intervalTimer = window.setInterval( function(){
    // Do something here.
}, 6000);

// Or...
function message(){ alert( 'Hi' ); }
var intervalTimer = window.setInterval( message, 6000);

// Stop the interval.
clearInterval( intervalTimer );

// Convert Seconds to Time
function convertSecondsToTime( secondsIn ){
        
        var seconds = Math.round( secondsIn );
        var output = '';
        var minutes = 0;
        var hours = 0;
        
        minutes = Math.floor(seconds/60);
        seconds = seconds-(minutes*60);
        
        if(seconds.toString().length == 1){
            seconds = "0" + seconds;
        }
        
        hours = Math.floor(minutes/60);
        minutes = minutes-(hours*60);
        
        if(minutes.toString().length == 1){
            minutes = "0" + minutes;
        }
        
        if(hours > 0){
            output += hours + ':';
        }
        
        output += minutes + ':' + seconds;
        return output;
        
    }

Cookies

Create

Cookies have four parameters name, value, expiration, and path.

  • The name is a unique identifier for the cookie. The cookie name must be unique to the path it is set on.
  • A cookie only holds one value and it must be a string.
  • The expiration is the date and time after which the cookie becomes invalid.
  • The path should almost always be set to the root path=/ unless you have reason to set the cookie to a deeper path.
function setCookie( cName, cValue, cExDays )
{
    var d = new Date();x
    d.setTime( d.getTime() + ( cExDays*24*60*60*1000 ));
    var expires = "expires=" + d.toUTCString();
    document.cookie = cName + "=" + cValue + "; " + expires + "; path=/";
}

// Set a cookie called "myCookie" with
// a value of "1" which will expire in 90 days.
setCookie( 'myCookie', 1, 90 );

Read

function getCookie( cName ) {
    var value = "; " + document.cookie;
    var parts = value.split("; " + cName + "=");
    if (parts.length == 2)
    {
        return parts.pop().split(";").shift();
    }
}

// Get the value of a cookie named "myCookie".
var myCookieValue = getCookie( 'myCookie' );

Update

To update a cookie, simply redefine it.

Delete

When a cookie expires it is automatically deleted, so to delete a cookie, set it’s expiration date to the past.

function delete_cookie( cookieName )
{
    document.cookie = cookieName +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
};
function delete_cookie( name, path, domain ) {
  if( get_cookie( name ) ) {
    document.cookie = name + "=" +
      ((path) ? ";path="+path:"")+
      ((domain)?";domain="+domain:"") +
      ";expires=Thu, 01 Jan 1970 00:00:01 GMT";
  }
}

JSON Values

To store more complex data sets in a cookie you must first convert the javascript object into a string. After you retrieve the cookie value, you must then convert it back to a javascript object.

// Set a jSon object.
var customerJsonObj = {
    'userName': 'Bob',
    'userId': '24735',
    'Likes': [{
        '0': 'Walking',
        '1': 'Trees'
    }],
    'totalPurchases': '6',
    'Dislikes': [{
        '0': 'Biking'
     }]
};

// Convert the jSon object into a string.
var customerJsonString = JSON.stringify( customerJsonObj );
 
// Set a cookie called 'customer', set the jSon
// string as its value and set a 90-day expiration.
setCookie( 'customer', customerJsonString, 90 );

// Get the raw value of the cookie we just set.
var rawCustomerCookieValue = getCookie( 'customer' );

// Parse the string into a jSon object.
var newCustomerJsonObj = JSON.parse( rawCustomerCookieValue );

Input Textfield Default Value

Module Pattern

// Standard module pattern enclosure.
var module = (function(){
    /* module code */
}());

// jQuery module pattern enclosure.
var module = (function($){
    /* module code */
})(jQuery);

See a demo on codepen.io

// jQuery Module definition.
var module = (function($){

    // Private variable.
    var privateValue = 0;

    // Public functions.
    function getValue()
    {
        return privateValue;
    }

    function setValue( value )
    {
        privateValue = value;
    }

    function incrementValue()
    {
        privateValue++;
    }
    
    // Return public functions.
    return {
        getValue: getValue,
        setValue: setValue,
        incrementValue: incrementValue
    }

})(jQuery);

jQuery( document ).ready(function() {
    // Use the module.
    console.log( module.getValue() );          // Returns: 0
    module.setValue( 5 );                      // Set the value to 5
    console.log( module.getValue() );          // Returns: 5
    module.incrementValue();                   // Increment the number
    console.log( module.getValue() );          // Returns: 6
});

This pattern is a way of creating a self-contained module or library that can be accessed by other scripts.

When JavaScript executes, the module is immediately bound to a variable. This is done by wrapping the content of the module in a self-executing function which returns the module’s public functions to the variable. The module’s public functions and properties can then be accessed from the variable using the . (dot notation property accessor) like so: module.myFunction();.

Ajax

/**
 * Submits a jSON Ajax Request
 * The server should send back a json object with at least:
 * - json['status'] = 1: on success, 'error': on app error
 * - json['message'] = {some success message}: on success, {some error message}: on error
 */
function send_ajax_request(
    request_url,            // The URL to send the request to.
    request_data,           // jSon object of data to send with the request.
    callback_function_name, // The callback function name.
    callback_class_name    // The callback function's class namespace.
)
{    
    // Using the jQuery core $.ajax() method.
    $.ajax({
        url:        request_url,
        data:       request_data,
        type:       'POST',     // Whether this is a POST or GET request.
        dataType :  'json',     // The type of data we expect back from the response.
     
        // Code to run if the request succeeds:
        success: function( json_response )
        {
            // If no json was set, the request got a 200 but the server returned nothing.
            if( json_response == 0 )
            {
                console.log( 'Response returned no json data.' );
            }
            // If json was set...
            else
            {
                // Check for an error message from the application.
                if( json_response.status == 'error' )
                {
                    console.log( 'Error: ' + json_response.message );
                }
                // Pass the response data to the callback function defined with
                // 'callback_class_name' and callback_function_name'.
                else
                {
                    // if a callback function was defined...
                    if( ( callback_function_name != undefined ) && callback_function_name != '' )
                    {
                        // If the callback class name was defined...
                        if( ( callback_class_name != undefined ) && callback_class_name != '' )
                        {
                            // Run the callback class function and pass it the json response.
                            window[callback_class_name][callback_function_name]( json_response );
                        }
                        // If the callback class name was NOT defined...
                        else
                        {
                            // Run the callback function and pass it the json response.
                            window[callback_function_name]( json_response );
                        }
                    }
                }
            }
        },
     
        // If the request fails: raw request and status codes are passed to this function.
        error: function( xhr, status, error )
        {
            console.log( 'Ajax request failed!' );
            console.log( 'Status: ' + status );
            console.log( 'Error: ' + error );
        }
    });
    
}

// Set some data and call the function.
var data = {};
data['foo'] = 'bar';

// Simple request.
send_ajax_request(
    'http://myurl.com',
    data
);

// Request with callback to a global function.
send_ajax_request(
    'http://myurl.com',
    data,
    'myGlobalFunctionName'
);

// Request with callback to a class-function.
send_ajax_request(
    'http://myurl.com',
    data,
    'myClassFunctionName',
    'myClassName'
);

Glossary

Javascript
Javascript is an application most commonly run as a module within the browser on the user’s computer, although the code being run can (and most often does) come from a server. Javascript can interact with the user, control the browser, communicate asynchronously (without refreshing the page), and alter the content and HTML of a web page.

DOM (Document Object Model)
The DOM is a technical term to describe the structure of the elements (HTML tags) which form a web page running in a web browser. The

Namespace
You can think of a namespace in JavaScript as the unique name given to any function or variable. JavaScript does not have built-in support for namespaces like other languages. It does have objects and closures which can be used to achieve pseudo name-spacing.

Scope
In JavaScript every function, when invoked, creates a new execution context or scope. Variables and functions defined inside a function may only be accessed from inside that function. However, anything within a scope can access variables and functions outside the scope, this is called a closure.

Closures
A closure is when one function is within another function allowing the inner function to access variables in the outer function. Simply accessing variables outside of the immediate scope creates a closure. A function does not have to return in order to be called a closure. More info: mozilla.org.

More Resources