End Publish

To Do

Following sections need to be reviewed and updated.

Common Libraries

Summary

  • JQuery - Approx 9K lines. Browser independent way of accessing components and manipulating them.
  • JQuery-ui - Approx 15K lines. UI related stuff on top of JQuery.
  • prototype.js - Approx 7K lines. General useful functions. e.g. each(), clone(), etc.
  • Backbone.js - Approx 1500 lines. Small generic util collection to be used on any environment (browser or not). Includes Events, History, etc handling helper functions. Provides basic MVC framework. Requires underscore.js. Can optionally use jquery for view. The model closely resembles Ruby on Rails.
  • underscore.js - Approx 1200 lines. Provides functional programming support without extending any of the built-in JavaScript objects. Used along with Backbone or JQuery. jquery offers only partial support for functional programming.
  • modernizr.js - Approx 1500 lines. Small library to easily manipulate CSS. It is HTML5 and CSS3 aware. Good for progressive enhancement.

Following are complete JavaScript framework libraries, more heavyweight:

  • YUI - Yahoo User Interface Library
  • dojo toolkit
  • mootools - A compact framework with 6000 lines of Javascript code.

Until drupal 7 (PHP based web framework), only jQuery is included in core. Drupal 8 includes backbone.js and underscore.js in it's core.

See Also:

Built-in Types

There are only few built-in types. They are:

  • Undefined, Null, Boolean, Number, String and Object.

Note that Function is not a separate type; Function type is a specialization of Object type-- which is callable.

Built-in Objects

Operators

Closure

Design Patterns

Window Event Programming

Example Events

onmouseover, onmouseout

AJAX Requests

An example usage:

function handler()
{
    if (oReq.readyState == 4 /* complete */) {
        if (oReq.status == 200) {
            alert(oReq.responseText);
        }
    }
}

var oReq = new XMLHttpRequest();

if (oReq != null) {
    oReq.open("GET", "http://localhost/test.xml", true);
    oReq.onreadystatechange = handler;
    oReq.send();
}
else {
    window.alert("AJAX (XMLHTTP) not supported.");
}

prototype.js defines following function:

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

jquery.js sets the global XMLHttpRequest variable if needed using following code:

// If IE is used, create a wrapper for the XMLHttpRequest object
if ( jQuery.browser.msie && typeof XMLHttpRequest == "undefined" )
    XMLHttpRequest = function(){
        return new ActiveXObject(
            navigator.userAgent.indexOf("MSIE 5") >= 0 ?
            "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
        );   
    };   

An example usage from w3schools:

<html>
<head>
<script>
function loadXMLDoc()
{
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
}
</script>
</head>
<body>

<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button type="button" onclick="loadXMLDoc()">Change Content</button>

</body>
</html>

Style Guidelines

Better to use CSS for presentation, HTML for structure and Javascript for interactivity. However, there are cases for which it makes sense to manipulate CSS and html from JavaScript--this should be kept in minimum.

For accessibility reasons, you may want to define CSS class for hiding like below:

.hide {
   position: absolute;
   top: -9999px;
   left: -9999px;
}

.remove {
   display: none;
}

JQuery Basics

  • $(document).ready(fn);

  • Selectors:

    • CSS Style: $('#mycontainer'), $('a'), $('li:first-child'), etc.
    • X-Path: $('a[title]'), $('div[ul]'), etc.
    • Custom: $('li:eq(1)')

Some Useful Methods

  • DOM Traversal – .parent(), .siblings(), .next() •
  • Manipulation – .html(), .empty(), .append(content) •
  • Events – .ready(fn), .hover(fn1, fn2), .click(fn)
  • Effects – .slideToggle(), .show(), .hide()

Chaining

$(‘#someElement’) .parent().parent() .find(‘div.green’)
.hide().end() .siblings().find(‘div.blue’) 
.show().end() .parent().next()
.addClass(‘redBorder’);

Show/Hide Example:
$(document).ready(function() {
      $('a.showhide').click(function() { $(this).parent().parent()
        .find('div.view-data-body') .slideToggle(); 
        return false; 
      }); 
}); 

jQuery in Drupal

drupal_add_js($data, $type) – Add a JavaScript file,
                 setting or inline code to the page, for example: 
drupal_add_js(drupal_get_path(‘module’, ‘mymodule’) .'/myjs.js'); •
drupal_add_js(array(‘myjs’=>$mysettings), ‘setting’); 
Drupal_add_js(‘var myVar = “foo”;’, ‘inline’); 

Where do I put my code?

– themers: put your .js file in your theme directory 
       and call drupal_add_js(drupal_get_path(‘theme’, ‘mytheme’) . ‘myjs.js’) 
       from a tpl file 
– module developers: put your .js file in your module directory and call 
                      drupal_add_js() before you output content

Ajaxifying Drupal with jQuery

Basic essentials: 
 – jQuery’s .ajax() or .get() method
 - drupal/path – callback function • drupal_to_js($var) 
 – Converts a PHP variable into its JavaScript equivalent. 

Quick Tabs

Create blocks of tabbed views! http://drupal.org/project/quicktabs

Tips

var_dump() equivalent in JavaScript

  • Use console.log(obj) if it is console.

  • obj.toString() ==> works well if obj is array; but for associative array yields just [Object ]

  • http://phpjs.org/functions/sprintf

  • Use following function. Be warned that it is too noisy:

    function dump(obj) 
    {
      var out = '';
      for (var i in obj) { out += i + ": " + obj[i] + "\n"; }
    
      // alert(out);   or ...
      console.log(out);
    
      // or, if you wanted to avoid alerts...
    
      var pre = document.createElement('pre');
      pre.innerHTML = out;
      document.body.appendChild(pre)
    }
    
  • JSON.stringify(obj) (you may get recursive structure error)

Objects Vs Arrays vs Associative Arrays

Enumerate all hidden properties/methods

for (var i in obj) console.log(i) // This excludes built-in properties. Possible solutions are:

  • console.dir(), console.log() // Chrome lets you explore Object by clicking.
  • Object.getOwnPropertyNames(obj); // This lists all properties enumerable or not. Object.getOwnPropertyNames(obj.__proto__); Object.getOwnPropertyNames(obj.__proto__.__proto__); // till __proto__ becomes null

Note: getOwnPropertyNames() is part of ECMA v5 specification.

Interesting API calls

Object.getOwnPropertyNames(Math) // ECMA V5

Mixins

Getting OuterHTML

  • Simplest method:

    console.log(document.getElementsByTagName("head")[0].innerHTML)  // innerHTML
    
    $('.classSelector').html();    // innerHTML using JQuery
    
    // Gives you the outside wrapper as well
    $('.classSelector')[0].outerHTML      // Most browsers support this DOM property.
    
  • Using jQuery + clone:

    (function($) {
      $.fn.outerHTML = function() {
          return $(this).clone().wrap('<div></div>').parent().html();
      }
    })(jQuery);
    
    And use it like this: $("#myTableRow").outerHTML();
    
  • Using jQuery without clone:

    $.fn.outerHTML = function() {
        $t = $(this);
        if ('outerHTML' in $t[0]) {
            return $t[0].outerHTML;
        } else {
            var content = $t.wrap('<div></div>').parent().html();
            $t.unwrap();
            return content;
        }
    }
    
    And use it like this: $("#myID").outerHTML();
    
  • Extend jQuery properly:

    (function($) {
        if (!$.outerHTML) {
            $.extend({
                outerHTML: function(ele) {
                    var $return = undefined;
                    if (ele.length === 1) {
                        $return = ele[0].outerHTML;
                    }
                    else if (ele.length > 1) {
                        $return = {};
                        ele.each(function(i) {
                            $return[i] = $(this)[0].outerHTML;
                        })
                    };
                    return $return;
                }
            });
            $.fn.extend({
                outerHTML: function() {
                    return $.outerHTML($(this));
                }
            });
        }
    })(jQuery);
    
    $.outerHTML($("#eleID")); // will return outerHTML of that element and is 
    // same as
    $("#eleID").outerHTML();
    For multiple elements
    $("#firstEle, .someElesByClassname, tag").outerHTML();
    

Toggle Visibility Vs Display

Using javascript you can choose to hide an element by clicking on it. You can either completely remove it from display or just toggle visibility.

function toggleVisibility() {
  document.getElementById("toggleMe").style.display = "";
  if(document.getElementById("toggleMe").style.visibility == "hidden" ) {
    document.getElementById("toggleMe").style.visibility = "visible";
  }
  else {
  document.getElementById("toggleMe").style.visibility = "hidden";
  }
}
function toggleDisplay() {
  document.getElementById("toggleMe").style.visibility = "visible";
  if(document.getElementById("toggleMe").style.display == "none" ) {
    document.getElementById("toggleMe").style.display = "";
  }
  else {
    document.getElementById("toggleMe").style.display = "none";
  }
}

<p><a href="#" onclick="toggleDisplay();">Click to toggle display.</a> | <a
href="#" onclick="toggleVisibility();">Click to toggle visibility.</a></p>

<div id="toggleMe" style="visibility: hidden;"> Something to Hide and show.
Display collapses it's layout while visibility will keep it's layout.</div>

Treatment of this keyword

The this keyword is a magic keyword which refers to current object. In browser this is global window by default. The only way to implicitly set the current object is by calling as below:

> f = function() { console.log(this) }
> f
   // Prints global object window
> obj = { 'one' : 1, 'two' : 2 }
> obj.p = f
> obj.p()
   // Prints obj object

Display definition of the function using toString()

> util.puts(util.puts.toString())        # To see definition of function!!!
  function () {
    for (var i = 0, len = arguments.length; i < len; ++i) {
      process.stdout.write(arguments[i] + '\n');
    }
  }

Glossary (In progress, Draft, needs cleanup )

V8 Javascript Engine
V8 JavaScript Engine is an open source JavaScript engine developed by Google. It ships with the Google Chrome web browser.

SpiderMonkey
First JavaScript Engine developed at Netscape.

PhoneGap
PhoneGap is a mobile development framework to build applications for mobile devices using JavaScript, HTML5 and CSS3,

Ringojs
A JavaScript runtime and shell based on Rhino providing a CommonJS conformant module library and web application framework.