building evented single page applications

63
building evented single-page applications Sunday, September 13, 2009

Upload: john-nunemaker

Post on 18-May-2015

4.354 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Building Evented Single Page Applications

building evented single-page applications

Sunday, September 13, 2009

Page 2: Building Evented Single Page Applications

1. who2. why3. demo4. how

Sunday, September 13, 2009

Page 3: Building Evented Single Page Applications

1. whoSunday, September 13, 2009

Page 4: Building Evented Single Page Applications

chancellorhttp://orderedlist.com/

Sunday, September 13, 2009

Page 5: Building Evented Single Page Applications

professorhttp://teaching.johnnunemaker.com/

Sunday, September 13, 2009

Page 6: Building Evented Single Page Applications

rubyisthttp://railstips.org/

Sunday, September 13, 2009

Page 7: Building Evented Single Page Applications

i’m not perfect

Sunday, September 13, 2009

Page 8: Building Evented Single Page Applications

2. whySunday, September 13, 2009

Page 9: Building Evented Single Page Applications

because?

Sunday, September 13, 2009

Page 10: Building Evented Single Page Applications

because?

Sunday, September 13, 2009

Page 11: Building Evented Single Page Applications

speedonly send what changes

across the wire

Sunday, September 13, 2009

Page 12: Building Evented Single Page Applications

perceived speed

Sunday, September 13, 2009

Page 13: Building Evented Single Page Applications

interactivity

Sunday, September 13, 2009

Page 14: Building Evented Single Page Applications

experiencebut the greatest of these is...

Sunday, September 13, 2009

Page 15: Building Evented Single Page Applications

3. demoSunday, September 13, 2009

Page 16: Building Evented Single Page Applications

http://peoplebase.com/ http://harmonyapp.com/

Sunday, September 13, 2009

Page 17: Building Evented Single Page Applications

4. howSunday, September 13, 2009

Page 18: Building Evented Single Page Applications

goals

Sunday, September 13, 2009

Page 19: Building Evented Single Page Applications

no reloads

Sunday, September 13, 2009

Page 20: Building Evented Single Page Applications

no reloadshistory/refresh

Sunday, September 13, 2009

Page 21: Building Evented Single Page Applications

no reloadshistory/refresheasy

Sunday, September 13, 2009

Page 22: Building Evented Single Page Applications

#Sunday, September 13, 2009

Page 23: Building Evented Single Page Applications

no reloadshistory/refresheasy

Sunday, September 13, 2009

Page 24: Building Evented Single Page Applications

no reloadshistory/refresheasy

Sunday, September 13, 2009

Page 25: Building Evented Single Page Applications

no reloadshistory/refresheasy

Sunday, September 13, 2009

Page 26: Building Evented Single Page Applications

no reloadshistory/refresheasy

Sunday, September 13, 2009

Page 27: Building Evented Single Page Applications

the end

Sunday, September 13, 2009

Page 28: Building Evented Single Page Applications

no reloads

Sunday, September 13, 2009

Page 29: Building Evented Single Page Applications

<a href="#/items">Items</a>

Sunday, September 13, 2009

Page 30: Building Evented Single Page Applications

$("a[href^='#/']").live('click', function (event) { var $link = $(this); window.location.hash = $link.attr('href'); $(document).trigger('hashchange'); return false;});

Sunday, September 13, 2009

Page 31: Building Evented Single Page Applications

$(document).bind('hashchange', Layout.reload);

Sunday, September 13, 2009

Page 32: Building Evented Single Page Applications

var Layout = { reload: function() { Layout.load(window.location.hash); }};

Sunday, September 13, 2009

Page 33: Building Evented Single Page Applications

var Layout = { load: function(path, options) { path = path.replace(/^#/, ''); // trigger path loading events $.ajax({ url : path, dataType : 'json', success : function(json) { Layout.onSuccess(json); // trigger path success events if (options && options.success) { options.success(); } }, complete : function() { if (options && options.complete) { options.complete(); } } }); }};

Sunday, September 13, 2009

Page 34: Building Evented Single Page Applications

var Layout = { load: function(path, options) { path = path.replace(/^#/, ''); $(document).trigger('path:loading', [path]); $(document).trigger('path:loading:' + path); $.ajax({ url: path, dataType: 'json', success: function(json) { Layout.onSuccess(json); $(document).trigger('path:success', [path, json]); $(document).trigger('path:success:' + path, [json]); if (options && options.success) { options.success(); } }, complete: function() { if (options && options.complete) { options.complete(); } } }); }};

Sunday, September 13, 2009

Page 35: Building Evented Single Page Applications

var Layout = { onSuccess: function(json) { Layout.applyJSON(json); // trigger layout success },};

Sunday, September 13, 2009

Page 36: Building Evented Single Page Applications

no reloads

Sunday, September 13, 2009

Page 37: Building Evented Single Page Applications

history/refresh

Sunday, September 13, 2009

Page 38: Building Evented Single Page Applications

setInterval(function() { var hash_is_new = window.location.hash && window.currentHash != window.location.hash; if (hash_is_new) { window.currentHash = window.location.hash; Layout.handlePageLoad(); }}, 300);

Sunday, September 13, 2009

Page 39: Building Evented Single Page Applications

#/org/groups/12/45/new

Sunday, September 13, 2009

Page 40: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 41: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 42: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 43: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 44: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 45: Building Evented Single Page Applications

org groups 12 45 new

Sunday, September 13, 2009

Page 46: Building Evented Single Page Applications

var Layout = { handlePageLoad: function() { var segments = window.location.hash.replace(/^#\//, '').split('/'), total = segments.length, path = ''; function loadSectionsInOrder() { var segment = segments.shift(); path += '/' + segment; var onComplete = function() { var loaded = total - segments.length, finished = loaded == total; if (!finished) { loadSectionsInOrder(); } }; Layout.load(path, {complete: onComplete}); } loadSectionsInOrder(); }};

Sunday, September 13, 2009

Page 47: Building Evented Single Page Applications

var Layout = { handlePageLoad: function() { var segments = window.location.hash.replace(/^#\//, '').split('/'), total = segments.length, path = ''; $(document).trigger('page:loading'); function loadSectionsInOrder() { var segment = segments.shift(); path += '/' + segment; var onComplete = function() { var loaded = total - segments.length, finished = loaded == total; $(document).trigger('page:progress', [total, loaded]); if (finished) { $(document).trigger('page:loaded'); } else { loadSectionsInOrder(); } }; Layout.load(path, {complete: onComplete}); } loadSectionsInOrder(); }};

Sunday, September 13, 2009

Page 48: Building Evented Single Page Applications

$(document).bind('page:progress', function(e, total, loaded) { if (total != loaded) { var final_width = 114, new_width = (loaded/total) * final_width; $('#loading_progress').animate({width: new_width+'px'}, 200); } }); $(document).bind('page:loading', function() { $('#harmony_loading').show(); $('#loading_progress').css('width', 0); }); $(document).bind('page:loaded', function() { $('#loading_progress').animate({width:'114px'}, 300, 'linear', function() { $('#harmony_loading').hide(); }); });

Sunday, September 13, 2009

Page 49: Building Evented Single Page Applications

history/refresh

Sunday, September 13, 2009

Page 50: Building Evented Single Page Applications

easy

Sunday, September 13, 2009

Page 51: Building Evented Single Page Applications

rule #1: abuse events for better code separation

and easier customizationhttp://orderedlist.com/articles/jquery-evented-programming-primer

Sunday, September 13, 2009

Page 52: Building Evented Single Page Applications

$('form').live('submit', function(event) { var $form = $(this); $form.ajaxSubmit({ dataType: 'json', beforeSend: function() { // trigger before send }, success: function(json) { // if errors, show them, else apply json and reset form }, error: function(response, status, error) { // trigger error }, complete: function() { // trigger complete } }); return false;});

Sunday, September 13, 2009

Page 53: Building Evented Single Page Applications

$('form').live('submit', function(event) { var $form = $(this); $form.ajaxSubmit({ dataType: 'json', beforeSend: function() { $form.trigger('form:beforeSend'); }, success: function(json) { if (json.errors) { $form.showErrors(json.errors); } else { Layout.onSuccess(json); $form.trigger('form:success', [json]); $form.resetForm(); } }, error: function(response, status, error) { $form.trigger('form:error', [response, status, error]); }, complete: function() { $form.trigger('form:complete'); } }); return false;});

Sunday, September 13, 2009

Page 54: Building Evented Single Page Applications

var Site = { onCreateSuccess: function(event, json) { Sidebar.highlight($('#site_' + json.id)) Layout.updateHashWithoutLoad(window.location.hash.replace(/new$/, json.id)); }, onUpdateSuccess: function(event, json) { Sidebar.highlight($('#site_' + json.id)) }};

$('form.new_site').live('form:success', Site.onCreateSuccess);$('form.edit_site').live('form:success', Site.onUpdateSuccess);

Sunday, September 13, 2009

Page 55: Building Evented Single Page Applications

var Field = { onCreateSuccess: function(event, json) { $('#list_section_' + json.section_id) .addSectionField(json.field_title.toLowerCase()); }, onUpdateSuccess: function(event, json) { $('#list_section_' + json.section_id) .removeSectionField(json.old_title.toLowerCase()) .addSectionField(json.new_title.toLowerCase()); }};

$('form.new_field') .live('form:success', Field.onCreateSuccess);$('form.edit_field').live('form:success', Field.onUpdateSuccess);

Sunday, September 13, 2009

Page 56: Building Evented Single Page Applications

Layout.applyJSONaccepts json like below and “applies” it to the layout;

gets called with each url load either from click or form

Sunday, September 13, 2009

Page 57: Building Evented Single Page Applications

Layout.applyJSON

{ 'replace': { '#content': '<h1>Heading</h1><p>Yay!</p>' }, 'replaceWith': { '#post_12': '<div class="post">...</div>' }, 'remove': ['#post_11', '#comment_12']}

Sunday, September 13, 2009

Page 58: Building Evented Single Page Applications

rule #2: the url dictates everything

Sunday, September 13, 2009

Page 59: Building Evented Single Page Applications

var Layout = { livePath: function(event, path, callback) { if (typeof(test) === 'string') { $(document).bind('path:' + event + ':' + path, callback); } else { Layout.live_path_regex[event].push([path, callback]); } }};

Sunday, September 13, 2009

Page 60: Building Evented Single Page Applications

Layout.livePath('loading', /\/org\/([^\/]+)([0-9\/]+).*/, Groups.loading);

Layout.livePath('loading', /\/sections\/([0-9]+)$/, Sections.markCurrent);

Layout.livePath('success', '/org/groups', Groups.setup);

Layout.livePath('success', '/sections', Sections.makeSortable);

Layout.livePath('success', /\/admin\/assets(.*)/, Assets.init);

Layout.livePath('success', /\/admin\/items\/(\d+)/, ItemForm.init);

Layout.livePath('success', /\/admin\/items\/([0-9\/]+)/, Items.manageSidebar);

Sunday, September 13, 2009

Page 61: Building Evented Single Page Applications

rule #3: do it live

Sunday, September 13, 2009

Page 62: Building Evented Single Page Applications

$('a.field_form_toggler') .live('click', Fields.toggleAddFieldForm);$('form.new_section') .live('form:success', SectionForm.onCreateSuccess);$('form.edit_section') .live('form:success', SectionForm.onUpdateSuccess);$('form.new_field') .live('form:success', Field.onCreateSuccess);$('form.edit_field') .live('form:success', Field.onUpdateSuccess);$('a.field_destroy') .live('destroy:success', Field.onDestroySuccess);

Sunday, September 13, 2009

Page 63: Building Evented Single Page Applications

easy

Sunday, September 13, 2009