Building Evented Single Page Applications

4,791 views

Published on

Published in: Technology, Sports
1 Comment
20 Likes
Statistics
Notes
No Downloads
Views
Total views
4,791
On SlideShare
0
From Embeds
0
Number of Embeds
2,644
Actions
Shares
0
Downloads
198
Comments
1
Likes
20
Embeds 0
No embeds

No notes for slide

Building Evented Single Page Applications

  1. 1. building evented single-page applications Sunday, September 13, 2009
  2. 2. 1. who 2. why 3. demo 4. how Sunday, September 13, 2009
  3. 3. 1. who Sunday, September 13, 2009
  4. 4. chancellor http://orderedlist.com/ Sunday, September 13, 2009
  5. 5. professor http://teaching.johnnunemaker.com/ Sunday, September 13, 2009
  6. 6. rubyist http://railstips.org/ Sunday, September 13, 2009
  7. 7. i’m not perfect Sunday, September 13, 2009
  8. 8. 2. why Sunday, September 13, 2009
  9. 9. because? Sunday, September 13, 2009
  10. 10. because? Sunday, September 13, 2009
  11. 11. speed only send what changes across the wire Sunday, September 13, 2009
  12. 12. perceived speed Sunday, September 13, 2009
  13. 13. interactivity Sunday, September 13, 2009
  14. 14. but the greatest of these is... experience Sunday, September 13, 2009
  15. 15. 3. demo Sunday, September 13, 2009
  16. 16. http://peoplebase.com/ http://harmonyapp.com/ Sunday, September 13, 2009
  17. 17. 4. how Sunday, September 13, 2009
  18. 18. goals Sunday, September 13, 2009
  19. 19. no reloads Sunday, September 13, 2009
  20. 20. no reloads history/refresh Sunday, September 13, 2009
  21. 21. no reloads history/refresh easy Sunday, September 13, 2009
  22. 22. # Sunday, September 13, 2009
  23. 23. no reloads history/refresh easy Sunday, September 13, 2009
  24. 24. no reloads history/refresh easy Sunday, September 13, 2009
  25. 25. no reloads history/refresh easy Sunday, September 13, 2009
  26. 26. no reloads history/refresh easy Sunday, September 13, 2009
  27. 27. the end Sunday, September 13, 2009
  28. 28. no reloads Sunday, September 13, 2009
  29. 29. <a href="#/items">Items</a> Sunday, September 13, 2009
  30. 30. $("a[href^='#/']").live('click', function (event) { var $link = $(this); window.location.hash = $link.attr('href'); $(document).trigger('hashchange'); return false; }); Sunday, September 13, 2009
  31. 31. $(document).bind('hashchange', Layout.reload); Sunday, September 13, 2009
  32. 32. var Layout = { reload: function() { Layout.load(window.location.hash); } }; Sunday, September 13, 2009
  33. 33. 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
  34. 34. 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
  35. 35. var Layout = { onSuccess: function(json) { Layout.applyJSON(json); // trigger layout success }, }; Sunday, September 13, 2009
  36. 36. no reloads Sunday, September 13, 2009
  37. 37. history/refresh Sunday, September 13, 2009
  38. 38. 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
  39. 39. #/org/groups/12/45/new Sunday, September 13, 2009
  40. 40. org groups 12 45 new Sunday, September 13, 2009
  41. 41. org groups 12 45 new Sunday, September 13, 2009
  42. 42. org groups 12 45 new Sunday, September 13, 2009
  43. 43. org groups 12 45 new Sunday, September 13, 2009
  44. 44. org groups 12 45 new Sunday, September 13, 2009
  45. 45. org groups 12 45 new Sunday, September 13, 2009
  46. 46. 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
  47. 47. 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
  48. 48. $(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
  49. 49. history/refresh Sunday, September 13, 2009
  50. 50. easy Sunday, September 13, 2009
  51. 51. rule #1: abuse events for better code separation and easier customization http://orderedlist.com/articles/jquery-evented-programming-primer Sunday, September 13, 2009
  52. 52. $('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
  53. 53. $('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
  54. 54. 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
  55. 55. 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
  56. 56. Layout.applyJSON accepts json like below and “applies” it to the layout; gets called with each url load either from click or form Sunday, September 13, 2009
  57. 57. 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
  58. 58. rule #2: the url dictates everything Sunday, September 13, 2009
  59. 59. 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
  60. 60. 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
  61. 61. rule #3: do it live Sunday, September 13, 2009
  62. 62. $('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
  63. 63. easy Sunday, September 13, 2009

×