Dynamic Multi Sort

See "Sort array of objects by string property value in JavaScript" -> http://stackoverflow.com/questions/1129216

HTML

<div class="section group">
    <div class="col span_1_of_2" id="col1"></div>
    <div class="col span_1_of_2" id="col2"></div>
</div>

CSS

body {
    font-family: monospace;
    background: #444;
}
/*  SECTIONS  */
.section {
    clear: both;
    padding: 0px;
    margin: 0px;
}
/*  COLUMN SETUP  */
.col {
    display: block;
    float: left;
    margin: 1% 0 1% 1.6%;
    padding: 2%;
    background: #FFF;
    white-space: pre;
}
.col:first-child {
    margin-left: 0;
}
/*  GROUPING  */
.group:before, .group:after {
    content: "";
    display: table;
}
.group:after {
    clear: both;
}
.group {
    zoom: 1; /* For IE 6/7 */
}
/*  GRID OF TWO  */
.span_2_of_2 {
    width: 100%;
}
.span_1_of_2 {
    width: 45.2%;
}
/*  GO FULL WIDTH AT LESS THAN 480 PIXELS */
@media only screen and (max-width: 480px) {
    .col {
        margin: 1% 0 1% 0%;
    }
}
@media only screen and (max-width: 480px) {
    .span_2_of_2, .span_1_of_2 {
        width: 96%;
    }
}

JavaScript

Object.defineProperty(Object.prototype, 'deepVal', {
    enumerable: false,
    writable: true,
    value: function (propertyChain) {
        var levels = propertyChain.split('.');
        var parent = this;
        for (var i = 0; i < levels.length; i++) {
            if (!parent[levels[i]]) return undefined;
            parent = parent[levels[i]];
        }
        return parent;
    }
});

function _dynamicSort(sorter) {
    var property = sorter;
    var direction = 1;
    if (typeof sorter !== 'string') {
        property = sorter.property;
        direction = sorter.direction === 'DESC' ? -1 : 1;
    } else {
        if (property[0] === '-') {
            direction = -1;
            property = property.substr(1);
        }
    }
    return function (a, b) {
        var aVal = a.deepVal(property);
        var bVal = b.deepVal(property);

        if (aVal < bVal) {
            return -1 * direction;
        } else if (aVal > bVal) {
            return 1 * direction;
        } else {
            return 0;
        }
    }
}

function _dynamicSorter(sorters) {
    var properties = arguments;
    return function (obj1, obj2) {
        var index = 0,
            result = 0;
        while (result === 0 && index < properties.length) {
            result = _dynamicSort(properties[index++]).apply(null, arguments);
        }
        return result;
    };
}
Object.defineProperty(Array.prototype, 'sortBy', {
    enumerable: false,
    writable: true,
    value: function () {
        return this.sort(_dynamicSorter.apply(null, arguments));
    }
});

function toJson(obj, indent) {
    return JSON.stringify(obj, null, indent || 1);
}

var people = [
    { person: { name : { first: "Patrick", last: "Swayze" } } },
    { person: { name : { first: "Ian", last: "Anderson" } } },
    { person: { name : { first: "Wil", last: "Wheaton" } } },
    { person: { name : { first: "Patrick", last: "Stewart" } } },
    { person: { name : { first: "Ian", last: "McKellen" } } }
];

var...