selector based view
play

Selector-based View Composition William Zeller and Edward Felten - PowerPoint PPT Presentation

Selector-based View Composition William Zeller and Edward Felten Princeton University http://svc.from.bz What is SVC? Modification to Model-View-Controller (MVC) architecture Provides automatic progressive enhancement (Ajaxification)


  1. First Tab Page HTML Page title <html> <head> <title>First tab page</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li class="selected"><a href="/tab1">First Tab</a></li> <li><a href="/tab2">Second Tab</a></li> <li><a href="/tab3">Third Tab</a></li> </ul> </div> (continued on next page...) WebApps '10 - June 24, 2010 38

  2. First Tab Page HTML <html> <head> <title>First tab page</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> Tabs header <h1>Tabs Example</h1> <ul> <li class="selected"><a href="/tab1">First Tab</a></li> <li><a href="/tab2">Second Tab</a></li> <li><a href="/tab3">Third Tab</a></li> </ul> </div> (continued on next page...) WebApps '10 - June 24, 2010 39

  3. First Tab Page HTML <html> <head> <title>First tab page</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> CSS class showing selected tab <h1>Tabs Example</h1> <ul> <li class="selected"><a href="/tab1">First Tab</a></li> <li><a href="/tab2">Second Tab</a></li> <li><a href="/tab3">Third Tab</a></li> </ul> </div> (continued on next page...) WebApps '10 - June 24, 2010 40

  4. First Tab Page HTML (continued...) <div id="content"> First tab content <br/><br/> <b>Bold</b> first tab message. </div> </body> </html> WebApps '10 - June 24, 2010 41

  5. First Tab Page HTML Tab content (continued...) <div id="content"> First tab content <br/><br/> <b>Bold</b> first tab message. </div> </body> </html> WebApps '10 - June 24, 2010 42

  6. Tabs Page without SVC • Create site without JavaScript • Use JavaScript to add Ajax support – This is the Progressive Enhancement step WebApps '10 - June 24, 2010 43

  7. Tabs Controller <?php class TabsExample extends Controller { function tab1() { } function tab2() { } function tab3() { } } WebApps '10 - June 24, 2010 44

  8. Tabs Controller <?php class TabsExample extends Controller { function tab1() { } tab1() runs when /tab1 function tab2() { is requested, etc } function tab3() { } } WebApps '10 - June 24, 2010 45

  9. Tabs Controller <?php class TabsExample extends Controller { function tab1() { } function tab2() { } function tab3() { } } We don't show tab3() due to space limitations. WebApps '10 - June 24, 2010 46

  10. Tabs Controller <?php class TabsExample extends Controller { function tab1() { } function tab2() { } } WebApps '10 - June 24, 2010 47

  11. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); } function tab2() { } } WebApps '10 - June 24, 2010 48

  12. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); } function tab2() { } Define array with data which will } be sent to the view WebApps '10 - June 24, 2010 49

  13. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); } function tab2() { $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); } } WebApps '10 - June 24, 2010 50

  14. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 51

  15. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { Call view "tab_template" with data array. $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 52

  16. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { $data = array('title' => 'Second tab page', Output interpreted view. 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 53

  17. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 54

  18. Template (tab_template) <html> <head> <title><?=$title?></title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> <li <? if ($tab_num == 2) { ?> class="selected" <? } ?> id="tab_2"><a href="/tab2">Second Tab</a></li> (continued on next page...) WebApps '10 - June 24, 2010 55

  19. Template (tab_template) Output Title <html> <head> <title><?=$title?></title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> <li <? if ($tab_num == 2) { ?> class="selected" <? } ?> id="tab_2"><a href="/tab2">Second Tab</a></li> (continued on next page...) WebApps '10 - June 24, 2010 56

  20. Template (tab_template) <html> <head> <title><?=$title?></title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> Set CSS class if appropriate <h1>Tabs Example</h1> <ul> <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> <li <? if ($tab_num == 2) { ?> class="selected" <? } ?> id="tab_2"><a href="/tab2">Second Tab</a></li> (continued on next page...) WebApps '10 - June 24, 2010 57

  21. Template (tab_template) (continued...) <li <? if ($tab_num == 3) { ?> class="selected" <? } ?> id="tab_3"><a href="/tab3">Third Tab</a></li> </ul> </div> <div id="content"><?=$content?></div> </body> </html> WebApps '10 - June 24, 2010 58

  22. Template (tab_template) (continued...) <li <? if ($tab_num == 3) { ?> class="selected" <? } ?> id="tab_3"><a href="/tab3">Third Tab</a></li> </ul> Set CSS class if appropriate </div> <div id="content"><?=$content?></div> </body> </html> WebApps '10 - June 24, 2010 59

  23. Template (tab_template) (continued...) <li <? if ($tab_num == 3) { ?> class="selected" <? } ?> id="tab_3"><a href="/tab3">Third Tab</a></li> </ul> </div> Output content <div id="content"><?=$content?></div> </body> </html> WebApps '10 - June 24, 2010 60

  24. Tabs Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 61

  25. Content Templates First tab content <br/><br/> tab1_content <b>Bold</b> first tab message. Some content for the second tab. tab2_content WebApps '10 - June 24, 2010 62

  26. Non-Ajax Tabs Example Complete • Site works (but no Ajax) • Let's enhance! WebApps '10 - June 24, 2010 63

  27. Adding Ajax (Main Template) <html> <head> <title><?=$title?></title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> ... WebApps '10 - June 24, 2010 64

  28. Adding Ajax (Main Template) <html> Add scripts to progressively enhance <head> <title><?=$title?></title> <script type="text/javascript" src="jQuery.js"></script> <script type="text/javascript" src="tabs.js"></script> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> ... WebApps '10 - June 24, 2010 65

  29. Add Ajax to Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } ... } WebApps '10 - June 24, 2010 66

  30. Add Ajax to Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); if (is_ajax()) { return json_encode($data); } else { return view('tab_template', $data); } } ... } WebApps '10 - June 24, 2010 67

  31. Add Ajax to Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); if (is_ajax()) { return json_encode($data); } else { return view('tab_template', $data); If Ajax request, return JSON } } ... } WebApps '10 - June 24, 2010 68

  32. Add Ajax to Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); if (is_ajax()) { return json_encode($data); } else { return view('tab_template', $data); } } Otherwise, output HTML ... } WebApps '10 - June 24, 2010 69

  33. Example: Adding Ajax (tabs.js) $(function() { }); WebApps '10 - June 24, 2010 70

  34. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { // ... }; Add click handler to tab links $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 71

  35. Example: Adding Ajax (tabs.js) Function to be called when tab link is clicked $(function() { var onTabClk = function() { // ... }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 72

  36. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { return false; }; Return false to prevent normal link load $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 73

  37. Example: Adding Ajax (tabs.js) Extract link URL $(function() { var onTabClk = function() { var href = $(this).attr('href'); return false; }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 74

  38. Example: Adding Ajax (tabs.js) $(function() { Make JSON request var onTabClk = function() { var href = $(this).attr('href'); $.getJSON(href, function(data) { // ... process JSON response }); return false; }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 75

  39. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { Set page title var href = $(this).attr('href'); $.getJSON(href, function(data) { document.title = data.title; }); return false; }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 76

  40. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { var href = $(this).attr('href'); $.getJSON(href, function(data) { document.title = data.title; $('#tab_' + data.tabNum).addClass('selected'); }); return false; Set CSS class of new tab }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 77

  41. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { var href = $(this).attr('href'); $.getJSON(href, function(data) { document.title = data.title; $('#tab_' + data.tabNum).addClass('selected'); $('#content').html(data.content); }); return false; Set tab content }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 78

  42. Example: Adding Ajax (tabs.js) $(function() { Remove "selected" CSS var onTabClk = function() { var href = $(this).attr('href'); class from all elements $.getJSON(href, function(data) { document.title = data.title; $('.selected').removeClass('selected'); $('#tab_' + data.tabNum).addClass('selected'); $('#content').html(data.content); }); return false; }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 79

  43. Example: Adding Ajax (tabs.js) $(function() { var onTabClk = function() { var href = $(this).attr('href'); $.getJSON(href, function(data) { document.title = data.title; $('.selected').removeClass('selected'); $('#tab_' + data.tabNum).addClass('selected'); $('#content').html(data.content); }); return false; }; $('#tab_header a').click(onTabClk); }); WebApps '10 - June 24, 2010 80

  44. Tabs Example Now Progressively Enhanced • Tabs will load using Ajax in JS browsers WebApps '10 - June 24, 2010 81

  45. Cost of Progressive Enhancement • Requires duplication of view updates. – Server-side using templates. – Client-side using JavaScript WebApps '10 - June 24, 2010 82

  46. Examples of Duplication: Page Title • Server-side code <title><?=$title?></title> • Client-side code document.title = data.title; WebApps '10 - June 24, 2010 83

  47. Examples of Duplication: Tab Headers • Server-side code <li <? if ($tab_num == 1) { ?> class="selected" <? } ?> id="tab_1"><a href="/tab1">First Tab</a></li> <li <? if ($tab_num == 2) { ?> class="selected" <? } ?> id="tab_2"><a href="/tab2">Second Tab</a></li> <li <? if ($tab_num == 3) { ?> class="selected" <? } ?> id="tab_3"><a href="/tab3">Third Tab</a></li> • Client-side code $('.selected').removeClass('selected'); $('#tab_' + data.tabNum).addClass('selected'); WebApps '10 - June 24, 2010 84

  48. Examples of Duplication: Page Content • Server-side code <div id="content"><?=$content?></div> • Client-side code $('#content).html(data.content); WebApps '10 - June 24, 2010 85

  49. Tabs Example Using SVC • Instead of duplicating view update code, use SVC API to describe how to compose views WebApps '10 - June 24, 2010 86

  50. Example: Non-SVC Controller <?php class TabsExample extends Controller { function tab1() { $data = array('title' => 'First tab page', 'tab_num' => 1, 'content' => view('tab1_content')); return view('tab_template', $data); } function tab2() { $data = array('title' => 'Second tab page', 'tab_num' => 2, 'content' => view('tab2_content')); return view('tab_template', $data); } } WebApps '10 - June 24, 2010 87

  51. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { // } function tab2() { // ... } } WebApps '10 - June 24, 2010 88

  52. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } tabbase() creates an SVC list function tab1() { // consisting of only the template } "tabbase_template" function tab2() { // ... } } WebApps '10 - June 24, 2010 89

  53. Example: Template (tabbase) <html><head> <title></title> <link rel="stylesheet" type="text/css" href="style.css"/> </head><body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li id="tab_1"><a href="/tab1">First Tab</a></li> <li id="tab_2"><a href="/tab2">Second Tab</a></li> <li id="tab_3"><a href="/tab3">Third Tab</a></li> </ul> </div> <div id="content"></div> </body></html> WebApps '10 - June 24, 2010 90

  54. Example: Template (tabbase) <html><head> <title></title> Like "tab_template", but all <link rel="stylesheet" type="text/css" href="style.css"/> content is empty. </head><body> <div id="tab_header"> <h1>Tabs Example</h1> <ul> <li id="tab_1"><a href="/tab1">First Tab</a></li> <li id="tab_2"><a href="/tab2">Second Tab</a></li> <li id="tab_3"><a href="/tab3">Third Tab</a></li> </ul> </div> <div id="content"></div> </body></html> WebApps '10 - June 24, 2010 91

  55. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { // } function tab2() { // ... } } WebApps '10 - June 24, 2010 92

  56. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); } function tab2() { // ... } } WebApps '10 - June 24, 2010 93

  57. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); } Start with output of tabbase() function tab2() { // ... } } WebApps '10 - June 24, 2010 94

  58. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); } function tab2() { // ... } } WebApps '10 - June 24, 2010 95

  59. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); } Update the title function tab2() { // ... } } WebApps '10 - June 24, 2010 96

  60. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); $this->svc->removeClass('.selected', 'selected'); } ... } WebApps '10 - June 24, 2010 97

  61. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); $this->svc->removeClass('.selected', 'selected'); } ... Remove the "selected"' class from all } elements to clear tab highlighting WebApps '10 - June 24, 2010 98

  62. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); $this->svc->removeClass('.selected', 'selected'); $this->svc->addClass('#tab_1', 'selected'); } ... } WebApps '10 - June 24, 2010 99

  63. Example: SVC Controller <?php class TabsExample extends Controller { function tabbase() { $this->svc->initial(view('tabbase_template')); } function tab1() { $this->svc->initial('tabbase'); $this->svc->text('title', 'First tab page'); $this->svc->removeClass('.selected', 'selected'); $this->svc->addClass('#tab_1', 'selected'); } ... Add "selected" class to the first tab. } WebApps '10 - June 24, 2010 100

Recommend


More recommend