Archive for 'Javascript'

Select2 Version 4 loading data remotely

Using select2 version 4
  • Custom data loader
  • Infinite scrolling
  • Setting values programmatically

$.fn.select2.amd.require([
                'select2/data/array',
                'select2/utils'], function(select2ArrayData, select2Utils) {

  var CustomData = function($element, options) {
    CustomData.__super__.constructor.call(this, $element, options);
  };

  select2Utils.Extend(CustomData, select2ArrayData);

  CustomData.prototype.current = function(callback) {
    var $element = this.$element;
    var currentVal = $element.val();
    // - do whatever you need to load the data needed to create data objects

    // callback with array of data objects
    callback([{id: '1', text: 'result 1'}, {id: '3', text: 'result 3'}]); 
  };

  CustomData.prototype.query = function(params, callback) {
    var searchTerm = params.term;
    var page = params.page || 1;

    // - do whatever you need to get your data -

    var resp = {
      // these are your results
      results: [
        {id: '1', text: 'result 1'}, 
        {id: '2', text: 'result 2'}
      ],
      pagination: {
        // this means there are additional pages to load, set to false if not
        more: true 
      }
    };

    callback(resp);
  };

  var attrs = {};

  attrs.dataAdapter = CustomData;
  attrs.ajax = {}; // this trick is important to allow for infinite scrolling

  attrs.multiple = true;


  // the $('.some-select') should return a SELECT element
  var $select = $('.some-select').select2(attrs); 


  // Now suppose you want to set some values on your select2
  // don't forget to add 'option' tags

  var values = ['1', '3'];

  // this step is really important!
  $select.find('option').remove();
  for(var i = 0, len = values.length; i < len; i++) {
    $select.append('<option value="' + values[i] + '" selected="selected"></option>');
  }
  
  // set the values and trigger the change event to select2 knows about it
  $select.val(values).trigger("change"); 

});

Just Underscore Templating

I was recently looking for a light-weight html templating library to use for a project. It needed to work on strings (not DOM) and be very small. I remembered that UnderscoreJS had a great templating mechanism, but I did not want to pull in all of underscore just to enjoy this one feature. I ended up pulling the templating engine out and thought I would post it here for others to use:
var _ = {};

  // By default, Underscore uses ERB-style template delimiters, change the
  // following template settings to use alternative delimiters.
  _.templateSettings = {
    evaluate    : /<%([\s\S]+?)%>/g,
    interpolate : /<%=([\s\S]+?)%>/g,
    escape      : /<%-([\s\S]+?)%>/g
  };

  // When customizing `templateSettings`, if you don't want to define an
  // interpolation, evaluation or escaping regex, we need one that is
  // guaranteed not to match.
  var noMatch = /(.)^/;

  // Certain characters need to be escaped so that they can be put into a
  // string literal.
  var escapes = {
    "'"      : "'",
    '\\'     : '\\',
    '\r'     : 'r',
    '\n'     : 'n',
    '\u2028' : 'u2028',
    '\u2029' : 'u2029'
  };

  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;

  var escapeChar = function(match) {
    return '\\' + escapes[match];
  };

  _.defaults = function(obj) {
    if(typeof(obj) !== 'object') return obj;
    for(var i = 1, length = arguments.length; i < length; i++) {
      var source = arguments[i];
      for(var prop in source) {
        if(obj[prop] === void 0) obj[prop] = source[prop];
      }
    }
    return obj;
  };

  _.template = function(text, settings, oldSettings) {
    if(!settings && oldSettings) settings = oldSettings;
    settings = _.defaults({}, settings, _.templateSettings);

    // Combine delimiters into one regular expression via alternation.
    var matcher = RegExp([
      (settings.escape || noMatch).source,
      (settings.interpolate || noMatch).source,
      (settings.evaluate || noMatch).source
    ].join('|') + '|$', 'g');

    // Compile the template source, escaping string literals appropriately.
    var index = 0;
    var source = "__p+='";
    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
      source += text.slice(index, offset).replace(escaper, escapeChar);
      index = offset + match.length;

      if(escape) {
        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
      } else if(interpolate) {
        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
      } else if(evaluate) {
        source += "';\n" + evaluate + "\n__p+='";
      }

      // Adobe VMs need the match returned to produce the correct offest.
      return match;
    });
    source += "';\n";

    // If a variable is not specified, place data values in local scope.
    if(!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

    source = "var __t,__p='',__j=Array.prototype.join," +
    "print=function(){__p+=__j.call(arguments,'');};\n" +
    source + 'return __p;\n';

    try {
      var render = new Function(settings.variable || 'obj', '_', source);
    } catch(e) {
      e.source = source;
      throw e;
    }

    var template = function(data) {
      return render.call(this, data, _);
    };

    // Provide the compiled source as a convenience for precompilation.
    var argument = settings.variable || 'obj';
    template.source = 'function(' + argument + '){\n' + source + '}';

    return template;
  };

NaN…what?

NaN is the only value in Javascript that is not equal to anything, including itself.
if(NaN !== NaN){
  alert("what??? how???  huh???");
}
Therefore, one way you could check if a variable has the value of NaN is to do something like this:
if(yourVar !== yourVar) { // thanks Vigen Sarksyan for this suggestion
  alert("yourVar has a value of NaN");
}
While this will work, it is not recommended as most people will think you wrote this by mistake and assume there is a bug in your code. The correct way to check if a variable contains a NaN is by calling the isNaN function:
if(isNaN(yourVar)) {
  alert("yourVar has a value of NaN");
}
This is much more readable and produces the same result.

Also note the fact that while NaN stands for “Not a Number”, calling typeof(NaN) returns “number”…so it’s a number that is not a number 🙂

Removing values from nested Arrays in MongoDB

Deleting values from beep nested array by calling the ‘update’ function can be tricky to get right when using MongoDB. Suppose you have this structure:
{
  _id: 'someID',
  foo: [
    {
      bar: [
        {
          title: 't1'
        },
        {
          title: 't2'
        }
      ]
    },
    {
      bar: [
        {
          title: 't3'
        },
        {
          title: 't4'
        }
    }
  ]
}
Now suppose we want to remove the object with title ‘t1’ from the array it is in. I first tried doing this:
 db.myCollection.update({ _id : 'someID' },
                        { $pull : { 'foo.bar' : { 'title' : 't1' } } }); 
However, this did not seem to work. Adding a ‘.$’ after foo seemed to do the trick:
 db.myCollection.update({ _id : 'someID' },
                        { $pull : {'foo.$.bar' : { 'title' : 't1' } } });
I hope this saves you some time. Good luck!

ZIP a Folder in NodeJS

Here is a simple way to archive and pipe a folder in NodeJS.
First, get the fstream and tar modules:
  • npm install fstream
  • npm install tar
Do something like this on your server:
var fstream = require('fstream'),
    tar = require('tar'),
    zlib = require('zlib');

    res.writeHead(200, {
      'Content-Type'        : 'application/octet-stream',
      'Content-Disposition' : 'attachment; filename=myArchive.zip', 
      'Content-Encoding'    : 'gzip'
    });

    var folderWeWantToZip = '/foo/bar';

    /* Read the source directory */
    fstream.Reader({ 'path' : folderWeWantToZip, 'type' : 'Directory' })
        .pipe(tar.Pack())/* Convert the directory to a .tar file */
        .pipe(zlib.Gzip())/* Compress the .tar file */
        .pipe(response); // Write back to the response, or wherever else...
This solution is based on an answer on StackOverflow

The Javascript Echosystem – Slides Available

I’ve recently added a set of slides I have been developing and using to teach courses around building modern web applications. Topics include:
  • World Wide Web Technologies – An introduction to http, browsers, html and css.
  • Javascript – Prototype-based programming language that is dynamic, loosely typed and has first-class functions.
  • Document Object Model – Manipulating the live HTML.
  • JQuery – Library for working with the DOM.
  • RequireJS – JavaScript file and module loader.
  • AngularJS – Application development framework for the browser.
  • HTML5 – Semantic markup, canvas, CSS3 etc…
  • Debugging – Common tools used for debugging web applications.
  • Performance – Best practices for a fast website.
  • Bootstrap – Front-end framework for the web
  • KnockoutJS – Declarative data-binding framework

Please take a look and let me know what you think: http://roubenmeschian.com/tuts/
The source for this project is available on github.

It’s common for developers to want to run angular’s compilation over some piece of html inside a directive. However, if you are not careful, you can easily cause memory leaks.

Here is an example of code that may leave behind unneeded child scopes:
// in your directive's link function, you do something like this
var content = $compile(template)(scope); // compile and link to the current scope
element.append(content); // add to the DOM

// ... the later, we want to update the content of the element ...

var newContent = $compile(template2)(scope);
content.replaceWith(newContent);

// While replaceWith does remove the old html, it does not remove any of the scopes that may have been added the first time we did compile/link on the old template.
This is a better way to do it:
var newScope = scope.$new(); // create a new scope from the current scope
var content = $compile(template)(newScope); // compile and link to the new scope
element.append(content); // add to the DOM

// .. then later, we want to update the content of the element ...

newScope.$destroy(); // destroy the scope and all child scopes
var newScope2 = scope.$new(); // create a new scope
var content2 = $compile(template2)(newScope2); // compile and link
content.replaceWith(content2); // replace the html content with the new content
Also, note that if you want to know when a directive is destroyed to do any kind of additional cleanup, you can add a destroy listener to the element the directive’s link function is called with:
element.on('$destroy', function() {
 .. unhook whatever ..
});

Just remember that you won’t need to unhook jquery events that have been attached on or below the target element, since angular calls .remove() on it, thereby removing all listeners.

Guard and default operators in Javascript

Most programmers are familiar with the ‘&&’ and ‘||’ logical operators. What many do not know is how these operators behave in Javascript.

Quick review

In Javascript, the following values are considered falsy:

  • false
  • 0 (zero)
  • “” (empty string)
  • null
  • undefined
  • NaN (a special Number value meaning Not-a-Number!)
All other values are considered truthy.

Guard operator

Let’s say you want to access an attribute deep inside an object:

var name = data.person.name;

It’s entirely possible that not all objects in that chain are defined. So, to write safe code, we may want to do something like this:

var name;
if(data.person) {
  name = data.person.name;
}

To avoid nesting, which can sometimes make the code seem bulkier and more difficult to read, we can write the same code without the ‘if’ statement while still GUARD ourselves against possibly referencing an undefined object in the chain:

var name = data.person && data.person.name;

The reason why we can do this is because the ‘&&’ operator behaves in the following way:

  • If the value on the left is falsy, return it
  • If the value on the left is truthy, continue the evaluation of the value to the right recursively
  • If the last value is reached, return it no matter if it is falsy or truthy

var obj0;

// obj0 is undefined, so is falsy and is returned
// val0 is set to obj0, so is set to undefined
var val0 = obj0 && obj0.foo && obj0.foo.name;
var obj1 = {};

// obj1 is truthy, so continue
// obj1.foo is undefined (falsy), so return it
// val1 is therefore set to undefined
var val1 = obj1 && obj1.foo && obj1.foo.val;
var obj2 = {
  foo: {}
};

// obj2 is truthy, so continue
// obj2.foo is truthy, so continue
// obj2.foo.name is the last value, return it
// val2 is set to obj2.foo.name, which is undefined
var val2 = obj2 && obj2.foo && obj2.foo.name;
var obj3 = {
  foo: {
    name: 'Joe'
  }
};

// obj3 is truthy, continue
// obj3.foo is truthy, continue
// obj3.foo.name is the last value, return it
// val3 is set to obj3.foo.name, which is 'Joe'
var val3 = obj3 && obj3.foo && obj3.foo.name;

Since the ‘&&’ operator can be used to GUARD against errors when retrieving members of an object, it is commonly referred to as the ‘guard operator’.

Note that the ‘&&’ operator can be used in other scenarios as well:

var a = 1;
var b = 0;
var c = a && b;  // c is now set to 0, since b was the last value returned by the expression

Default operator

Where the ‘||’, on the other hand, returns the first truthy value in the expression.

var a = 0;
var b = 1;
var c = a || b; // c is set to 1, since b is the first truthy value in the expression

The ‘||’ operator is commonly referred to as the ‘Default operator’, because it is often used to assign a default value.

function myFunc(node, params) {
  
  // if params was an object that was passed in (is truthy), assign it to 'settings'
  // if params is not passed in (is falsy), assign a default object to 'settings'
  var settings = params || {isAwesome: true}; 
  
  if(settings.isAwesome)
    node.innerHTML = "Awesome";
}

Javascript ‘this’ scoping

The keyword ‘this’ refers to the context in which a given function is running.

Default context

If a function belongs to an object, it is generally called using the dot notation:

var obj = {
  func: function() {
    alert(this === obj); // alerts 'true'
  }
};

obj.func(); // run 'func' in the context of 'obj'

Therefore, by calling obj.func(), we are saying: “Run ‘func’ in the context of ‘obj’, such that the ‘this’ keyword in ‘func’ refers to ‘obj'”

This kind of behavior allows us to do things like this:

var obj = {
  name: 'Joe',
  func: function() {
    alert(this.name); // 'this' is referring to obj, so obj.name gives us 'Joe'
  }
};
obj.func(); // func runs in the context of obj

So far so good, right?

Context coercion

In javascript, we have the power to tell any function to run in the context of absolutely any object we want…not just the one it belongs to, using the magic ‘apply’ and ‘call’ functions:

var obj = {
  name: 'Joe',
  func: function() {
    alert(this.name);
  }
};

var obj2 = {
  name: 'Mike'
};

var obj3 = {
  name: 'Bill'
};

obj.func.apply(obj2); // run 'func' in the context of 'obj2', alerts "Mike"
obj.func.call(obj3); // run 'func' in the context of 'obj3', alerts "Bill"
Both the ‘call’ and ‘apply’ functions give us the ability to specify context. The two are a bit different in that if you wanted to pass arguments to the called function, using ‘apply’ you would pass the arguments as an array while with ‘call’ you would pass individual arguments:
var obj = {
  name: 'Joe',
  func: function(age, weight) {
    alert(this.name+" with age of "+age+" and height of "+weight);
  }
};

var obj2 = {
  name: 'Mike'
};

var obj3 = {
  name: 'Bill'
};

obj.func.apply(obj2, [23, 155]); // run 'func' in the context of 'obj2', alerts "Mike"
obj.func.call(obj3, 43, 176); // run 'func' in the context of 'obj3', alerts "Bill"

So, to review:

  1. Functions that belong to objects can be called using dot notation and run in the context of those objects
  2. Any function can be coerced to run in the context of any other object using the ‘call’ and ‘apply’ methods
  3. Just a reminder, the context of a function is whatever the ‘this’ keyword refers to

Anonymous functions

An anonymous function is one that does not belong to any object. In other words, you can’t call it using dot notation (e.g. someObj.yourFunc() ). Anonymous functions, unless coerced via the ‘call’ or ‘apply’ methods, run in the context of the global scope (usually the ‘window’ object).

var obj = {
  func: function() {
    var anonFunc = function() {
      alert(this === obj); // alerts 'false'
      alert(this === window); // alerts 'true', running in the context of the global object
    };
    anonFunc(); // run anonFunc in...well...no context specified...
  }
};

obj.func(); // run 'func' in the context of 'obj'

So how can we refer to ‘obj’ from the anonFunc? One way is to change the code like so:

var obj = {
  func: function() {
    var anonFunc = function() {
      alert(this === obj); // alerts 'false'
      alert(this === window); // alerts 'true', running in the context of the global object
    };
    anonFunc.call(this); // run anonFunc in the context of 'this', where 'this' is 'obj'
  }
};

obj.func(); // run 'func' in the context of 'obj'

However, a much more common way of fixing this issue is by assigning a variable ‘self’ to the target ‘this’, then just using the ‘self’ variable everywhere.

var obj = {
  func: function() {
    var self = this;
    var anonFunc = function() {
      alert(self === obj); // alerts 'true', since 'self' is set to the 'this' that is the 'obj'
      alert(self === window); // alerts 'false'
    };
    anonFunc(); // run anonFunc in the context of 'this', where 'this' is 'obj'
  }
};

obj.func(); // run 'func' in the context of 'obj'

Here is a more practical example:

var obj = {
  name: "John Doe",
  id: "82384349",
  func: function() {
    var self = this;
    $.get('ajax/getAge', {id: self.id}).done(function(data) {
      alert(self.name+" is "+data+" years old" );
    });
  }
};

obj.func(); // run 'func' in the context of 'obj'

Notice how I declared ‘self’ at the top of the ‘func’ function and then used it everywhere. This has the advantage of making our code less error-prone. Also, if you run your javascript through a minimizer, the ‘self’ variable will be compressed and you will end up with a slightly smaller file then you would if you used ‘this’ everywhere (which does not compress, since it is a keyword in javascript).

Happy Hacking!

Generating a parser

An important feature of Anzo on the Web is the ability to specify custom equations, similar to the ones you see in Excel, to do various analytics.  The language is similar to what you see in Excel, except the values are specified by RDF paths, rather than regions.  The editor has the formula editing region at the top, a place to select value fields on the bottom-left and a function selector on the bottom-right:

formulaEditor

For fast validation of formulas, I needed to build a parser for the language that would run in the browser (in javascript).  To do so, I used the awesome LALR(1) parser and lexical analyzer generator for JavaScript, which is itself written in javascript.

The installed version can be found here: JS/CC

To create a parser, you need to tell it about the language you want to parse.  You do this using aBackus-Naur-Form-based meta language , and it generates the javascript parser for you!  A good way to get started is to study the Calculator example, which can be loaded by clicking on the dropdown at the top, selecting it and clicking the ‘load’ button.