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;
  };

Software Engineering Videos

Youtube videos of the lectures

Harp – zero-configuration static web server

Getting started with Harp, a static web server that can intelligently serve out Jade, EJS, LESS, CoffeeScript and other such files without any configuration.

If you don’t already have NodeJS, please download and install it: http://nodejs.org/

Run this command to install Harp globally:
> npm install harp -g
Go into whatever directory has the files you want to serve out (your project) and type in:
> harp server
You can now go to the given address in the browser to view the served files. If you are a MAC user, you can add an alias to make using Harp even easier. Type the following in your command-line:
> nano ~/.bash_profile
Add this to the end of that file: alias server=”harp server” Save, close the terminal and re-open. You can now just type in ‘server’ as a command in any directory and it will start a server that will serve out the files from that directory.

For more information about Harp, please visit their site: http://harpjs.com/

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";
}