$30 off During Our Annual Pro Sale. View Details »

Front-End of Future Past

Nathan Smith
September 06, 2014

Front-End of Future Past

Slides from my talk at the Big (D) Conference, 2014.

Nathan Smith

September 06, 2014
Tweet

More Decks by Nathan Smith

Other Decks in Programming

Transcript

  1. F R O N T - E N D O F F U T U R E P A S T

    View Slide

  2. #whoami ?
    My name is Nathan. I do
    UX and JS at TandemSeven.
    But most people know me
    as "the 960 guy" (that's ok).
    http:/
    /sonspring.com | http:/
    /960.gs | http:/
    /tandemseven.com

    View Slide

  3. View Slide

  4. Download the slides and follow along:
    http:/
    /j.mp/future-past
    Or, talk smack about me on Twitter:
    @nathansmith
    Note: You don't have to take notes feverishly.

    View Slide

  5. * My predictive powers are average (at best).
    Today, I want to talk a bit about what the future
    of HTML, CSS, and JavaScript will look like.*

    View Slide

  6. Difficult to see. Always in motion is the future.

    View Slide

  7. To determine
    where we may
    be heading, let's
    reflect on where
    we've been…

    View Slide

  8. PART 1:
    HOW WE
    GOT HERE

    View Slide

  9. http:/
    /w3.org/People/Raggett/book4/ch02.html
    HTML

    View Slide

  10. http:/
    /w3.org/People/Berners-Lee
    1989: Tim Berners-Lee created HTML to link research docs.

    View Slide

  11. "Storage of ASCII text, and display
    on [80x24] screens, is in the short
    term sufficient, and essential.
    Addition of graphics would be an
    optional extra with very much less
    penetration for the moment."
    – Tim Berners-Lee
    http:/
    /w3.org/History/1989/proposal.html

    View Slide

  12. http:/
    /en.wikipedia.org/wiki/CERN
    HTML was for serious work. Initially, no tag.

    View Slide

  13. Before long though, the masses got their hands it.
    That is when great chaos befell the Internet…

    View Slide

  14. View Slide

  15. But, I digress.
    We're getting a little
    ahead of ourselves.
    (
    sorry )

    View Slide

  16. http:/
    /en.wikipedia.org/wiki/Mosaic_(web_browser)
    Marc L.
    Andreessen
    Eric J. Bina

    View Slide

  17. "Standardizing" on
    browser innovation…
    1993: Marc
    Andreessen
    proposed the
    tag.
    Mosaic later becomes
    Netscape, which then
    introduces JS, SSL, etc.

    View Slide

  18. View Slide

  19. JavaScript
    http:/
    /oreilly.com/pub/a/javascript/2001/04/06/js_history.html

    View Slide

  20. "JavaScript had to 'look like
    Java' only less so, be Java's
    dumb kid brother or boy-
    hostage sidekick. Plus, I
    had to be done in ten days
    or something worse than
    JS would have happened."
    Brendan Eich created JavaScript in 10 days.
    http:/
    /en.wikipedia.org/wiki/Brendan_Eich

    View Slide

  21. JavaScript is quirky and prototypal. Java is classy. Get it? :)

    View Slide

  22. With classical inheritance, if
    your mother breaks her leg, you
    go visit her in the hospital. With
    prototypal inheritance, your leg
    would also (instantly) break.
    Object Inheritance #TLDR
    #TLDR = "Too Long, Didn't Read" aka: Sum it up for me :)

    View Slide

  23. http:/
    /en.wikipedia.org/wiki/Netscape_Navigator
    1995: JavaScript debuted in Netscape Navigator 2.0.

    View Slide

  24. The word "JavaScript" was chosen to tap into the
    brand name of the Java programming language.
    Sun Microsystems (since acquired by Oracle) owned
    the trademarks for both Java™ and JavaScript™, and
    stewards the development of Java (not JavaScript).
    In 1997, JavaScript (the language) was standardized by
    the European Computer Manufacturers Association,
    and it was dubbed "ECMAScript."
    http:/
    /en.wikipedia.org/wiki/JavaScript | http:/
    /en.wikipedia.org/wiki/ECMAScript
    Um - what?
    Brief history of JavaScript = Clear as mud...

    View Slide

  25. Altogether different beasts: Both potentially delicious (or dangerous), but not actually derived from the same animal.
    Similar in name: JavaScript is to Java as Hamburger is to Ham.

    View Slide

  26. With apologies to Jeremy Keith and Brad Colbow…
    http:/
    /coding.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip

    View Slide

  27. 1996: IE 3.0 ships with "JScript" (for copyright purposes).
    In 1995, MS begins to ship Internet
    Explorer with Windows 95. For
    Netscape, it was the beginning of
    the end. Microsoft also reverse-
    engineered JavaScript, as "JScript."
    http:/
    /en.wikipedia.org/wiki/Internet_Explorer

    View Slide

  28. Created at
    Netscape
    "ECMA TC39"
    Committee responsible
    for evolving the language
    Who is responsible for JavaScript now?
    {to name
    a few...
    http:/
    /en.wikipedia.org/wiki/JavaScript | http:/
    /en.wikipedia.org/wiki/ECMAScript
    TM of Oracle (via
    Sun)

    Defines the
    ECMAScript
    DOM API

    View Slide

  29. JS browser support is pretty good.
    JavaScript (ECMAScript 3.0) is supported fairly
    consistently in all major browsers.
    ⾨ This is Wikipedia's compatibility table* for:
    – Trident (IE)
    – Gecko (Firefox)
    – WebKit (Chrome & Safari)
    – Presto (Opera)
    * I realize those are rendering engines, not specific JS engines
    (which change names more rapidly). It's how Wikipedia lists 'em.
    http:/
    /en.wikipedia.org/wiki/Comparison_of_layout_engines_(ECMAScript)

    View Slide

  30. JavaScript is that friend in high
    school you secretly had a crush
    on, but was always hanging out
    with the sleazy boyfriend, DOM.
    Nice >
    What a punk!
    http:/
    /w3.org/DOM

    View Slide

  31. The Document Object Model (DOM) is what
    allows JS to interact with XML/HTML, ala:
    window.document.getElementsByTagName('*');
    The DOM is stewarded by a different group than governs
    JS. Browsers also implement it slightly differently. For
    instance, IE historically didn't treat whitespace as text
    nodes, even though the official DOM spec says it should.
    http:/
    /w3.org/DOM

    View Slide

  32. 2005: Then there was jQuery...
    Heck yeah!
    $('p.neat').addClass('ohmy').show('slow');
    JavaScript that reads like CSS code!?
    http:/
    /jquery.com

    View Slide

  33. $(document).ready(function() {
    // Many tutorials put all the code here.
    });
    But we treated it like CSS...
    Um, okay... What's the big deal?

    View Slide

  34. Loosely translated:
    "You'd better lose yourself in
    the music, the moment. You
    own it, you better never let it
    go... You only get one shot, do
    not miss your chance to [load]."
    (with apologies to Eminem)
    window.onload
    http:/
    /en.wikipedia.org/wiki/8_Mile_(film)

    View Slide

  35. Really, it's not the fault of jQuery, nor of
    any other capable JavaScript libraries:
    Dojo, MooTools, Prototype, YUI, etc.
    As is almost always the case with code,
    the problem is actually a human one.
    We've become complacent and forgotten
    (or never learned) how JavaScript works.
    Beware the danger of abstraction & illiteracy.
    http:/
    /ejohn.org/blog/javascript-language-abstractions

    View Slide

  36. http:/
    /w3.org/Style/LieBos2e/history/Overview.html
    CSS

    View Slide

  37. http:/
    /intercom.co.cr/www-archives/1994-q1/0648.html
    1994: Marc Andreessen, on styling... "Sorry, you're screwed."

    View Slide

  38. 1994: Håkon Wium Lie proposed CSS.
    Initially it was called CHSS,
    ("Cascading HTML Style
    Sheets"), but was later
    shortened to simply CSS.
    1996: The first browser to
    support CSS was Internet
    Explorer 3.0, followed
    closely by Netscape
    Navigator version 4.0.
    http:/
    /people.opera.com/howcome/2006/phd

    View Slide

  39. CHSS had 100 levels of !important
    h1.font.size = 24px 12% /* 12% importance */
    h1.font.size = 16px 100% /* 100% importance */
    h1.font.size = 12px 89% /* 89% importance */
    h1 {font-size: 24px;} /* Applies globally (weak) */
    h1.x {font-size: 16px;} /* More specific */
    h1 {font-size: 12px;} /* Beats line 1, not line 2 */
    Thankfully, CHSS was never implemented:
    CSS has "last-in" wins, with specificity override.
    http:/
    /www.w3.org/People/howcome/p/cascade.html

    View Slide

  40. Brief history of the first "Browser War"
    http:/
    /en.wikipedia.org/wiki/Browser_wars

    View Slide

  41. 1998: "Web Standards" advocacy begins.
    http:/
    /w3.org/Style/LieBos2e/history/Overview.html
    The box model
    isn't fixed until
    October 2006,
    in IE7 debut.

    View Slide

  42. We made sites "best viewed in IE6,"
    and Netscape lost the browser war.
    http:/
    /en.wikipedia.org/wiki/Netscape_Navigator

    View Slide

  43. The "dark side" = developing for 1 browser.
    Oh, what... Like you never photoshopped
    you vs. yourself with a lightsaber? C'mon!
    http:/
    /flickr.com/photos/nathansmith/32757176

    View Slide

  44. In 2001, IE had over 90% market share.
    https:/
    /en.wikipedia.org/wiki/Browser_wars

    View Slide

  45. 2004: Firefox arose from Netscape's ashes.
    Thus began a new Browser War, still in progress.

    View Slide

  46. Since then, IE has been in steady decline.
    http:/
    /en.wikipedia.org/wiki/File:Usage_share_of_web_browsers_(Source_Net_Applications).svg

    View Slide

  47. Chrome grew, at the expense of Firefox.
    http:/
    /en.wikipedia.org/wiki/File:Usage_share_of_alternative_web_browsers_(Source_StatCounter).svg

    View Slide

  48. Today, Chrome has overtaken IE… What!?
    https:/
    /en.wikipedia.org/wiki/Browser_wars
    Chrome = green | IE = blue | Firefox = orange

    View Slide

  49. "Those who cannot
    remember the past
    are condemned to
    repeat it."
    – George Santayana
    http:/
    /en.wikipedia.org/wiki/George_Santayana
    So your "pure CSS" demo only works in WebKit?

    View Slide

  50. PART 2:
    WHERE
    WE'RE
    GOING

    View Slide

  51. http:/
    /zeldman.com/2009/07/02/xhtml-wtf

    View Slide

  52. Realistically speaking, XHTML 2.0 would've
    been a very tough sell, from a practical
    standpoint. It was extremely rigid. A page
    simply would not render, if it wasn't
    perfectly formed from an XML structural
    standpoint.
    Oh, and it would've done away with .
    Oh noes!

    View Slide

  53. There were differing schools of thought on HTML vs. XHTML.
    In the field
    "make it work"
    Academic
    "make it valid"

    View Slide

  54. rapid —>
    iteration
    http:/
    /whatwg.org/specs/web-apps/current-work/multipage

    View Slide

  55. Ian Hickson, benevolent HTML5 specification dictator curator…
    http:/
    /en.wikipedia.org/wiki/Ian_Hickson

    View Slide

  56. Technically, HTML5 is now a misnomer. (But, it's too
    late. Marketing already got ahold of it.) HTML is to
    be considered an ever-evolving "living standard."
    The WHATWG — Web Hypertext Application
    Technology Working Group — will continue to work
    on HTML, and the W3C will snapshot feature sets
    periodically, and tag them with incremental version
    numbers: HTML5 (and presumably, HTML6, etc).
    Thus, no more version numbers in DOCTYPE…

    View Slide

  57. HTML5 "killed" XHTML. Good riddance, I say.


    <— Much easier to remember!
    As it turns out, is the minimum number of
    characters to trigger "standards" mode in older IE versions.

    View Slide

  58. You don't have to type extra junk anymore.
    <br/>alert('This is some inline JS.');<br/>
    <br/>/* <![CDATA[ */<br/>alert('Are you kidding me?');<br/>/* ]]> */<br/>

    View Slide

  59. Have you ever used a non-CSS stylesheet?

    type="text/css" media="all" />
    Note: Media queries are best defined via @media in a single
    stylesheet anyway, to avoid unnecessary HTTP requests.
    No? Me neither, so why "type" it?

    View Slide

  60. You can't do that! What about the validator?
    Relax. It's valid. HTML5 is no longer a sub-
    set of SGML like all versions of HTML before
    it. Nor is it a spin on XML, like XHTML 1.x was.
    HTML is just HTML now. This is how
    browsers always treated (X)HTML anyway.
    I know what you XHTML purists are thinking:
    (
    phew! )
    http:/
    /en.wikipedia.org/wiki/HTML

    View Slide

  61. HTML5 CSS3
    http:/
    /w3.org/html/logo
    What about JS? It's actually not stewarded by the W3C.

    View Slide

  62. View Slide

  63. https:/
    /github.com/voodootikigod/logo.js

    View Slide

  64. Branding, FTW! So, what's next?
    1. Get cool logo(s). [X]
    2. Convince others. [X]
    3. Profit! [X]

    View Slide

  65. http:/
    /apple.com/html5
    Apple likes HTML5.

    View Slide

  66. http:/
    /html5rocks.com
    Google likes HTML5.

    View Slide

  67. https:/
    /developer.mozilla.org/en/HTML/HTML5
    Mozilla likes HTML5.

    View Slide

  68. http:/
    /opera.com/docs/specs/presto25/html5
    Opera likes HTML5.

    View Slide

  69. http:/
    /msdn.microsoft.com/en-us/ie/aa740476
    Microsoft likes HTML5.

    View Slide

  70. HTML5 is gaining traction.
    http:/
    /playbiolab.com

    View Slide

  71. As of IE9, all browsers support .
    http:/
    /ie.microsoft.com/testdrive/performance/asteroidbelt/default.html

    View Slide

  72. 2011: IE9 supports SVG (proposed in 1999).
    Examples of
    Dojo.js charts
    To be fair, IE renders SVG very
    fast, via hardware acceleration.
    Konqueror (WebKit predecessor), was the first
    browser to have built-in SVG support, in 2004.
    http:/
    /user.sitepen.com/~dwalsh/dojo-charting.html

    View Slide

  73. http:/
    /flickr.com/photos/124330160/2127121118
    And, each layer
    can respond to
    mouse events!
    SVG is like construction paper. Layers retain
    distinct shapes. SVG files work fine without JS.

    View Slide

  74. http:/
    /flickr.com/photos/azuriblue/3350954960
    Canvas is like a whiteboard drawing, one layer.
    Note: Canvas only works in the browser via JS.

    View Slide

  75. Quick CSS tip to fix IE's SVG rendering:
    svg {
    overflow: hidden;
    }

    View Slide

  76. IE9, without the CSS fix for SVG:
    http:/
    /host.sonspring.com/raph

    View Slide

  77. IE9, with the CSS fix for SVG:
    http:/
    /host.sonspring.com/raph

    View Slide

  78. SVG in: Chrome, Firefox, Opera, & Safari.
    http:/
    /host.sonspring.com/raph

    View Slide

  79. I won't cover or in
    detail during this talk, but two helpful
    JavaScript libraries are worth noting...
    Raphaël (SVG) – Dmitry Baranovskiy Processing JS (Canvas) – John Resig
    http:/
    /raphaeljs.com http:/
    /processingjs.org

    View Slide

  80. More Semantic Richness!

    New tags
    in HTML5
    http:/
    /html5doctor.com/element-index

    View Slide












  81. etc...





    etc...

    Mixes well with ARIA roles
    ( Accessible Rich Internet Applications )

    View Slide

  82. The dawn of 3D browser graphics.
    aka: Can I play Farmville in IMAX!?
    WebGL is going to be HUGE
    (
    eventually )
    http:/
    /en.wikipedia.org/wiki/WebGL

    View Slide

  83. https:/
    /github.com/mrdoob/three.js

    View Slide

  84. https:/
    /github.com/mrdoob/three.js

    View Slide

  85. View Slide

  86. View Slide

  87. Thoughts on Metaprogramming…
    Haml => HTML
    Sass/Compass => CSS
    CoffeeScript => JS
    Note: Yes, I'm sure there are many, many
    more examples in the wild. But my time is
    finite, and this is what I'm familiar with.
    http:/
    /haml-lang.com | http:/
    /sass-lang.com | http:/
    /compass-style.org | http:/
    /coffeescript.org

    View Slide

  88. Personal note: After giving 'em a try, I am
    on the fence regarding meta languages
    that treat whitespace as significant.
    Usual disclaimers apply:
    "It depends." Your mileage may vary. No purchase
    necessary. Machine-wash only. Enter at own risk.
    Batteries not included. Void where prohibited, etc.

    View Slide

  89. Example of Sass (with Compass).
    @import compass/css3 // CSS3 helpers, etc.
    // I write this Sass code:
    .foobar
    +background-image(linear-gradient(#fff, #ccc))
    +border-top-right-radius(4px)
    +box-shadow(rgba(#000, 0.5) 0 2px 5px 0)
    &:hover
    text-decoration: underline

    View Slide

  90. Example of Sass (with Compass).
    /* This CSS is generated... */
    .foobar {
    background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #cccccc));
    background-image: -webkit-linear-gradient(#ffffff, #cccccc);
    background-image: -moz-linear-gradient(#ffffff, #cccccc);
    background-image: -o-linear-gradient(#ffffff, #cccccc);
    background-image: -ms-linear-gradient(#ffffff, #cccccc);
    background-image: linear-gradient(#ffffff, #cccccc);
    -moz-border-radius-topright: 4px;
    -webkit-border-top-right-radius: 4px;
    -o-border-top-right-radius: 4px;
    -ms-border-top-right-radius: 4px;
    -khtml-border-top-right-radius: 4px;
    border-top-right-radius: 4px;
    -moz-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0;
    -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0;
    -o-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0;
    box-shadow: rgba(0, 0, 0, 0.5) 0 2px 5px 0;
    }
    .foobar:hover {
    text-decoration: underline;
    }
    BLOAT? Not really. You'd
    have to type all this to make
    it work cross-browser anyway.

    View Slide

  91. Note: Don't indent unnecessarily with Sass.
    // This looks innocent enough:
    table.table-class
    tbody
    tr
    td
    a.link-class
    color: orange

    View Slide

  92. Note: Don't indent unnecessarily with Sass.
    /* But it generates this... */
    table.table-class tbody tr td a.link-class {
    color: orange;
    }
    /* When you probably just meant... */
    .table-class .link-class {
    color: orange;
    }

    View Slide

  93. Haml rocks, if you're in a Ruby project.
    To me, Haml means
    never typing this again...

    View Slide

  94. Haml can generate nicely formatted HTML.
    I'm not an über-Ruby guy. Get your feet wet:

    View Slide

  95. Okay, so abstraction for HTML and CSS
    is fine. It saves keystrokes, and those
    languages are pretty #yawn anyway,
    right? I mean, they're declarative, so of
    course we should automate them.
    But do not touch my JavaScript.

    View Slide

  96. get.your(coffee) {
    return 'off my lawn';
    }

    View Slide

  97. Not everyone's a fan. Dustin Diaz, quoting Douglas Crockford:

    View Slide

  98. http:/
    /blog.meloncard.com/post/12175941935/how-one-missing-var-ruined-our-launch

    View Slide

  99. http:/
    /nodejs.org

    View Slide

  100. Can you spot the bug?
    var joe = 1
    sue = 2,
    bob = 3;
    var joe = 1,
    sue = 2,
    bob = 3;
    Bugs like this can be laborious to find, which is why I write...

    View Slide

  101. It's okay to be obvious.
    var joe = 1;
    var sue = 2;
    var bob = 3;
    Minifiers like Uglify JS can handle removing repeated var
    keywords. Put that burden on automation, not yourself.
    https:/
    /github.com/mishoo/UglifyJS | http:/
    /marijnhaverbeke.nl/uglifyjs

    View Slide

  102. Just tell JSLint… "Relax, it's okay."
    JSLint (and JSHint) is a great tool for checking for JS errors.
    But validation is a means to an end, not a goal in itself.
    If you want to ensure JSLint compliance, there's CoffeeScript...
    http:/
    /jslint.com | http:/
    /jshint.com

    View Slide

  103. Recursion -> CoffeeScript is written in… CoffeeScript!?
    https:/
    /plus.google.com/116264189418994838408/posts/CSXeyftovTJ

    View Slide

  104. # CoffeeScript:
    $('#foobar').click ->
    # Do stuff.
    // JavaScript:
    $('#foobar').click(function() {
    // Do stuff.
    });
    CoffeeScript -to- JavaScript...
    LOL - That's all?
    http:/
    /coffeescript.org

    View Slide

  105. # CoffeeScript:
    is_between = 1 < my_value < 10
    // JavaScript:
    var is_between;
    is_between = (1 < my_value && my_value < 10);
    CoffeeScript = Syntactic Sugar...
    Oh, I see.
    http:/
    /coffeescript.org

    View Slide

  106. "Unless" is cool…
    # CoffeeScript:
    happy = true unless raining
    // JavaScript:
    var happy;
    if (!raining) {
    happy = true;
    }
    That's hawt.
    http:/
    /coffeescript.org

    View Slide

  107. Despite its positive aspects,
    I am not a fan of CoffeeScript.
    Why? Because it's more than just syntactic sugar.
    It's dangerous artificial sweetener, so to speak.

    View Slide

  108. http:/
    /coffeescript.org
    obj =
    foo: 'bar'
    for i in obj
    console.log obj[i]
    var i, obj, _i, _len;
    obj = {
    foo: 'bar'
    };
    for (_i = 0, _len = obj.length; _i < _len; _i++) {
    i = obj[_i];
    console.log(obj[i]);
    }
    Want to iterate
    through an object
    in CoffeeScript?
    Sure thing, just...
    WTF?

    View Slide

  109. View Slide

  110. http:/
    /www.2ality.com/2013/06/iterators-generators.html
    let arr = ['foo', 'bar', 'baz'];
    for (let [index, element] of arr.entries()) {
    console.log(index + '. ' + element);
    }
    // Yields...
    //
    // 1. foo
    // 2. bar
    // 3. baz
    "for of" loops in the future…

    View Slide

  111. http:/
    /coffeescript.org
    obj =
    foo: 'bar'
    for i of obj
    console.log obj[i]
    var i, obj;
    obj = {
    foo: 'bar'
    };
    for (i in obj) {
    console.log(obj[i]);
    }
    You would have to
    actually type this
    in CoffeeScript.
    Then the resulting
    JavaScript output
    is a "for in" loop.

    View Slide

  112. This is why we can't have nice things!

    View Slide

  113. Backbone.js — Actually pretty nice…

    View Slide

  114. Underscore.js — Also nice…

    View Slide

  115. But use Lo-Dash instead. It's more solid…

    View Slide

  116. There are plenty of good MV* JS frameworks.
    &

    View Slide

  117. View Slide

  118. View Slide

  119. View Slide

  120. View Slide

  121. Key tenets of most MV* JS frameworks:
    — Model, View, Controller (MVC) or…
    — Model, View, View Model (MVVM)
    — Two-way data binding…
    If user interacts with page, you can
    reflect these changes in your data
    — Declarative UI: in markup, not in JS
    — Observables: If data changes, UI updates

    View Slide

  122. Trask-Industries.com (X-Men spoof site) uses Angular.js

    View Slide

  123. Trask-Industries.com (X-Men spoof site) uses Angular.js

    View Slide

  124. DEMO
    http://github.com/nathansmith/ko-table

    View Slide

  125. View Slide

  126. Below a certain width,
    the layout switches to
    a “mobile” view.
    The table rows & cells
    are display:block, and
    text from each is
    inserted as a label,
    preceding the data.

    View Slide





  127. First Name




    Last Name




    Character First Name




    Character Last Name




    View Slide

















  128. View Slide

















  129. View Slide

  130. // In a real app, this data would potentially be dynamic.
    // But for the purposes of this demo, is hard-coded here.
    [
    {
    "first_name": "Amy",
    "last_name": "Poehler",
    "character_first_name": "Leslie",
    "character_last_name": "Knope"
    },
    {
    "first_name": "Nick",
    "last_name": "Offerman",
    "character_first_name": "Ron",
    "character_last_name": "Swanson"
    },
    {
    "first_name": "Aziz",
    "last_name": "Ansari",
    "character_first_name": "Tom",
    "character_last_name": "Haverford"
    },
    ...
    ]

    View Slide

  131. // Extend KO array, to make it sortable
    ko.observableArray.fn.sort_by = function(key, reverse) {
    var self = this;
    self.sort(function(a, b) {
    var a_key = String(a[key]);
    var b_key = String(b[key]);
    var n, val;
    if (reverse) {
    n = a_key - b_key;
    val = !isNaN(n) ? n : b_key.localeCompare(a_key);
    }
    else {
    n = b_key - a_key;
    val = !isNaN(n) ? n : a_key.localeCompare(b_key);
    }
    return val;
    });
    };

    View Slide

  132. // APP.models
    models: {
    // APP.models.table_view_model
    table_view_model: function() {
    var self = this;
    // This data comes from "/json/data.js"
    APP.data = APP.data || ko.observableArray(DATA_JSON);
    self.data = APP.data;
    }
    },
    ...

    View Slide

  133. // APP.init.sort_by
    sort_by: function(key) {
    var event = 'click.sort_by';
    var str = '.table-data th[data-key] a';
    body.off(event).on(event, str, function(ev) {
    var el = $(this);
    var th = el.closest('th');
    var th_other = th.siblings('th');
    var key = th.attr('data-key');
    var sort = th.attr('data-sort');
    var asc = 'ascending';
    var desc = 'descending';
    var dir = asc;
    if (!sort || sort === asc) {
    dir = desc;
    }
    var reverse = dir !== asc;
    th.addClass(on).attr('data-sort', dir);
    th_other.removeClass(on).removeAttr('data-sort');
    APP.data.sort_by(key, reverse);
    });
    },

    View Slide

  134. Get the slides…
    http:/
    /j.mp/future-past
    Keep in touch…
    @nathansmith
    Questions? — I may (not) know the answer!
    http:/
    /corsariomarcio.deviantart.com/art/X-MEN-DAYS-OF-FUTURE-PAST-poster-455872133

    View Slide