SlideShare a Scribd company logo
1 of 36
Download to read offline
Beyond the DOM:
            Sane Structure for JS Apps
            Rebecca Murphey • @rmurphey • BVJS 2012

Wednesday, March 7, 12
github.com/rmurphey/bvjs




Wednesday, March 7, 12
function ObjInlineDown(e) {
                       if( is.ie ) e = event
                       if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return
                       if( is.ieMac && e.button != 0 ) return
                       if( is.ns && !is.ns4 && e.button!=0 && e.button!=2 ) return
                       if( is.ns4 && e.which!=1 && e.which!=3 ) return
                       this.onSelect()
                       this.onDown()
                     }

                     function ObjInlineUp(e) {
                       if( is.ie ) e = event
                       if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return
                       if( is.ieMac && e.button!=0 ) return
                       if( is.ns && !is.ns4 && !is.nsMac && e.button!=0 && e.button!=2 ) return
                       if( is.ns4 && e.which!=1 && e.which!=3 ) return
                       if( ( !is.ns4 && e.button==2 ) || ( is.ns4 && e.which==3 ) )
                       {
                         if( this.hasOnRUp )
                         {
                           document.oncontextmenu = ocmNone
                           this.onRUp()
                           setTimeout( "document.oncontextmenu = ocmOrig", 100)
                         }
                       }
                       else if( this.hasOnUp )
                         this.onUp()
                     }




Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
<!doctype html>
                     <html lang="en">
                     <head>
                       <meta charset="utf-8">
                       <title>Twitter Search</title>
                       <link rel="stylesheet" href="/assets/css/index.css">
                     </head>

                     <body>
                       <h1>Twitter Search</h1>
                       <div id="searchInput">
                         <form>
                            <input placeholder="enter your search term">
                            <button>submit</button>
                         </form>
                       </div>
                       <ul id="searchResults"></ul>

                       <script src="/assets/js/libs/jquery.js"></script>
                       <script src="/assets/js/app.js"></script>
                     </body>
                     </html>




Wednesday, March 7, 12
$('#searchInput form').submit(function(e){
                       e.preventDefault();

                         var term = $('#searchInput input').val(),
                             req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' +
                                   escape(term));

                         req.then(function(resp) {
                           var resultsHtml = $.map(resp.results, function(r) {
                             return '<li>' +
                               '<p class="tweet">' + r.text + '</p>' +
                               '<p class="username">' + r.from_user + '</p>' +
                             '</li>';
                           }).join('');

                         $('#searchResults').html(resultsHtml);
                       });
                     });




Wednesday, March 7, 12
Wednesday, March 7, 12
// NAVIGATION
               function togglePage(section) {
                   // if the clicked section is already the current section AND we're in full page mode
                   // minimize the current tab
                   if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) {
                       // alert('clicked section is current section AND fullpage mode is active; teaser should load');
                   // Minimize
                       jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideDown('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                jQuery('#md_tabs_navigation a').each(function(){
                                    var thisSection = jQuery(this).html().replace('<span<','').replace('</span<','');
                                    var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                                    jQuery('#md_body_'+ thisSection_comp).load(
                                        '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                                        function(){
                                            tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                            bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow");
                                        }
                                    );
                                });
                            });
                       });
                       jQuery('#expandtabs span').empty().append('Expand Tabs');
                   } else {
                   // if the clicked section is NOT the current section OR we're NOT in full page mode
                   // then let's go to full page mode and show the whole tab
                   // Maximize
                       // alert('clicked section is not the current section OR full page mode is not active; full section should load');
                       jQuery('#md_tabs_navigation li').removeClass('current');
                       jQuery('#md_tab_'+ section).addClass('current');
                       jQuery('#md_tabs_navigation a').addClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideUp('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                bodyContent.empty();
                                var pageLoader = 'info/loadSection.php?sect='+ section;
                                if (section == 'contact_us') {
                                     pageLoader = 'contact/loadContactForm.php?form_id=1';
                                }
                                bodyContent.load('/app/modules/'+ pageLoader,function(){
                                    // ADD THICKBOXES
                                    tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                    $recent_news_links = jQuery('ul.md_news li a.recent_news_link');
                                    $recent_news_links
                                        .unbind('click')
                                        .each(function(){
                                            var hrefMod = this.href;
                                            hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id');
                                            this.href = hrefMod;
                                        })
                                        .click(function(){
                                            var t = this.title || this.name || null;
                                            var a = this.href || this.alt;
                                            var g = this.rel || false;
                                            tb_show(t,a,g);
                                            this.blur();
                                            return false;
                                        });
Wednesday, March 7, 12              // ACCORDION
$('#btn-co-complete').live('click', function() {
            jobCompleted = true;
            $.mobile.changePage('#page-clockout-deficiency', {changeHash: false});
        });

        $('#btn-co-nocomplete').live('click', function() {
            jobCompleted = false;
            $.mobile.changePage('#page-clockout-deficiency', {changeHash: false});
        });

        $('#btn-co-nodef').live('click', function() {
            clockOut(activeJob, { completed:jobCompleted }, DW_JOB_COMPLETED);
        });

        $('#btn-co-otherdef').live('click', function() {
            $.mobile.changePage('#page-clockout-redtag', {changeHash: false});
        });

        $('#btn-co-redtag').live('click', function() {
            clockOut(activeJob, { completed:jobCompleted, redTag:true }, DW_JOB_FOLLOWUP)
        });

        $('#btn-co-noredtag').live('click', function() {
            $('#page-clockout-resolve').page();
            $.mobile.changePage('#page-clockout-resolve', {changeHash: false});
        });

             $('#btn-clockout-resolve').live('click', function() {
                       switch ($('#page-clockout-resolve :checked').val()) {
                       case 'return':
Wednesday, March 7, 12     clockOut(activeJob, { completed:false }, DW_JOB_RETURN);
search input   $('#searchInput form').submit(function(e){
                                          e.preventDefault();

                                          var term = $('#searchInput input').val(),
                                              req = $.getJSON('http://search.twitter.com/searc
                                                    escape(term));

                                          req.then(function(resp) {
                         search data        var resultsHtml = $.map(resp.results, function(r)
                                              return '<li>' +
                                                '<p class="tweet">' + r.text + '</p>' +
                                                '<p class="username">' + r.from_user + '</p>'
                                              '</li>';
                                            }).join('');

                                            $('#searchResults').html(resultsHtml);
                     search results       });
                                        });




Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
<script   type="text/javascript"   src="http://static.a2cdn.net/misc/jquery.js?9"></script>
               <script   type="text/javascript"   src="http://static.a2cdn.net/misc/drupal.js?9"></script>
               <script   type="text/javascript"   src="/google_analytics/googleanalytics.js?9"></script>
               <script   type="text/javascript"   src="/mollom/mollom.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery-1.4.2.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery-ui-1.8.4.custom.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery.infieldlabel.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery.nivo.slider.js?9"></script>
               <script   type="text/javascript"   src="/js/validations.js?9"></script>
               <script   type="text/javascript"   src="/js/site.js?9"></script>
               <script   type="text/javascript"   src="/js/noconflict.js?9"></script>




Wednesday, March 7, 12
<script data-main="app/config" src="/assets/js/libs/require.js"></script>




Wednesday, March 7, 12
require.config({
                       deps: ["main"],

                         paths: {
                           // JavaScript folders
                           libs: "../assets/js/libs",
                           plugins: "../assets/js/plugins",

                           // Libraries
                           jquery: "../assets/js/libs/jquery",
                           underscore: "../assets/js/libs/underscore",
                           backbone: "../assets/js/libs/backbone"
                       }
                     });




Wednesday, March 7, 12
define([
                       "components/page",
                       "components/search/input",
                       "components/search/results",
                     ], function(Page, SearchInput, SearchResults) {
                       return {
                          // ...
                       };
                     });




Wednesday, March 7, 12
// NAVIGATION
               function togglePage(section) {
                   // if the clicked section is already the current section AND we're in full page mode
                   // minimize the current tab
                   if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) {
                       // alert('clicked section is current section AND fullpage mode is active; teaser should load');
                   // Minimize
                       jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideDown('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                jQuery('#md_tabs_navigation a').each(function(){
                                    var thisSection = jQuery(this).html().replace('<span<','').replace('</span<','');
                                    var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                                    jQuery('#md_body_'+ thisSection_comp).load(
                                        '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                                        function(){
                                            tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                            bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow");
                                        }
                                    );
                                });
                            });
                       });
                       jQuery('#expandtabs span').empty().append('Expand Tabs');
                   } else {
                   // if the clicked section is NOT the current section OR we're NOT in full page mode
                   // then let's go to full page mode and show the whole tab
                   // Maximize
                       // alert('clicked section is not the current section OR full page mode is not active; full section should load');
                       jQuery('#md_tabs_navigation li').removeClass('current');
                       jQuery('#md_tab_'+ section).addClass('current');
                       jQuery('#md_tabs_navigation a').addClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideUp('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                bodyContent.empty();
                                var pageLoader = 'info/loadSection.php?sect='+ section;
                                if (section == 'contact_us') {
                                     pageLoader = 'contact/loadContactForm.php?form_id=1';
                                }
                                bodyContent.load('/app/modules/'+ pageLoader,function(){
                                    // ADD THICKBOXES
                                    tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                    $recent_news_links = jQuery('ul.md_news li a.recent_news_link');
                                    $recent_news_links
                                        .unbind('click')
                                        .each(function(){
                                            var hrefMod = this.href;
                                            hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id');
                                            this.href = hrefMod;
                                        })
                                        .click(function(){
                                            var t = this.title || this.name || null;
                                            var a = this.href || this.alt;
                                            var g = this.rel || false;
                                            tb_show(t,a,g);
                                            this.blur();
                                            return false;
                                        });
                                    // ACCORDION
                                    jQuery('div.applemenu div.submenu').hide();
                                    jQuery('div.applemenu div.silverheader < a').click(
Wednesday, March 7, 12                  function(){
component              controller


                         component




                                                 service



               components display data, observe input, and
               broadcast messages that controllers can react
               to; may also provide an API for updating


Wednesday, March 7, 12
component            controller


                         component




                                               service



               controllers set up components and broker
               communications between them, eliminating
               the need for direct communication


Wednesday, March 7, 12
component              controller


                         component




                                                 service




               services expose an API for controllers
               to retrieve and persist data


Wednesday, March 7, 12
Wednesday, March 7, 12
controller




                         twitter search




Wednesday, March 7, 12
components display data, observe input, and
               broadcast messages that controllers can react
               to; may also provide an API for updating




Wednesday, March 7, 12
define([
                 "components/base"
               ], function(Component) {
                 return Component({
                   template : "app/templates/search/input.html",
                   className : 'search-input',

                         events : {
                            "submit form"   :   "_onSubmit"
                         },

                   _onSubmit : function(e) {
                     e.preventDefault();
                     var term = $.trim(this.$el.find('input')[0].value);
                     if (!term) { return; }
                     this.trigger('search', term);
                   }
                 });
               });




Wednesday, March 7, 12
<form>
                 <input placeholder="enter your search term">
                 <button>submit</button>
               </form>




Wednesday, March 7, 12
controllers set up components and broker
               communications between them, eliminating
               the need for direct communication




Wednesday, March 7, 12
<!doctype html>
                     <html lang="en">
                     <head>
                       <meta charset="utf-8">
                       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                       <meta name="viewport" content="width=device-width,initial-scale=1">

                         <title>Searchr</title>

                       <!-- Application styles -->
                       <link rel="stylesheet" href="/assets/css/index.css">
                     </head>

                     <body>
                       <!-- Main container -->
                       <div role="main" id="main"></div>

                       <!-- Application source -->
                       <script data-main="app/config" src="/assets/js/libs/require.js"></
                     script>
                     </body>
                     </html>




Wednesday, March 7, 12
var Router = Backbone.Router.extend({
                      routes: {
                         "": "twitter",
                         ":hash": "twitter"
                      },

                      twitter : function(hash) {
                        SearchController.init();
                      }
                    });




Wednesday, March 7, 12
define([
                 "components/page", "components/search/input",
                 "components/search/results", "services/twitter"
               ], function(Page, SearchInput, SearchResults, twitterService) {
                 return {
                   init : function() {
                     this.page = new Page({ template : 'app/templates/pages/search.html' });
                     this.page.render().then(_.bind(this.setupPage, this));
                   },

                         setupPage : function() {
                           var p = this.page;
                           this.searchInput = p.place(new SearchInput(), 'searchInput');
                           this.searchResults = p.place(new SearchResults(), 'searchResults');
                           this.searchInput.on('search', _.bind(this.handleSearch, this));
                         },

                         handleSearch : function(term) {
                            twitterService.query(term).then(_.bind(this.showResults, this));
                         },

                         showResults : function(results) {
                           this.searchResults.show(results);
                         }
                 };
               });




Wednesday, March 7, 12
services expose an API for controllers
               to interact with data




Wednesday, March 7, 12
define([
                 "use!backbone"
               ], function(Backbone) {
                 var TwitterResult = Backbone.Model.extend({
                   // ...
                 });

                   var TwitterResults = Backbone.Collection.extend({
                     type : 'twitter', model : TwitterResult
                   });

                   return {
                     query : function(term) {
                       var req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' +
                            escape(term)),
                            dfd = $.Deferred();

                         req.then(function(resp) {
                           dfd.resolve(new TwitterResults(resp.results));
                         });

                         return dfd.promise();
                   }
                 };
               });




Wednesday, March 7, 12
“Writing to be read means writing code ... with
               the idea that someone else will read it. is
               fact alone will make you edit and think of better
               ways to solve the problem you have at hand.”
                                       Stoyan Stefanov, “JavaScript Patterns”



Wednesday, March 7, 12
github.com/rmurphey/bvjs




Wednesday, March 7, 12
rmurphey.com • @rmurphey




Wednesday, March 7, 12

More Related Content

What's hot

jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace PatternDiego Fleury
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScriptryanstout
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j queryMd. Ziaul Haq
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax pluginsInbal Geffen
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented ArchitectureLuiz Messias
 

What's hot (20)

jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace Pattern
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
jQuery
jQueryjQuery
jQuery
 
jQuery
jQueryjQuery
jQuery
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax plugins
 
Matters of State
Matters of StateMatters of State
Matters of State
 
JQuery
JQueryJQuery
JQuery
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 

Similar to BVJS

[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docxgerardkortney
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applicationsSteve Smith
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page ApplicationsSteve Smith
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Treeadamlogic
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScriptkvangork
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascriptkvangork
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformanceJonas De Smet
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery PresentationSony Jain
 

Similar to BVJS (20)

Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applications
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page Applications
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Unit – II (1).pptx
Unit – II (1).pptxUnit – II (1).pptx
Unit – II (1).pptx
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Tree
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
course js day 3
course js day 3course js day 3
course js day 3
 
Backbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 Floripa
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
 
Jquery examples
Jquery examplesJquery examples
Jquery examples
 

More from Rebecca Murphey

More from Rebecca Murphey (7)

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with Mulberry
 
Introducing Mulberry
Introducing MulberryIntroducing Mulberry
Introducing Mulberry
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large Apps
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gotham
 
Lessons from a Rewrite
Lessons from a RewriteLessons from a Rewrite
Lessons from a Rewrite
 
Modern JavaScript
Modern JavaScriptModern JavaScript
Modern JavaScript
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 

Recently uploaded

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

BVJS

  • 1. Beyond the DOM: Sane Structure for JS Apps Rebecca Murphey • @rmurphey • BVJS 2012 Wednesday, March 7, 12
  • 3. function ObjInlineDown(e) { if( is.ie ) e = event if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return if( is.ieMac && e.button != 0 ) return if( is.ns && !is.ns4 && e.button!=0 && e.button!=2 ) return if( is.ns4 && e.which!=1 && e.which!=3 ) return this.onSelect() this.onDown() } function ObjInlineUp(e) { if( is.ie ) e = event if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return if( is.ieMac && e.button!=0 ) return if( is.ns && !is.ns4 && !is.nsMac && e.button!=0 && e.button!=2 ) return if( is.ns4 && e.which!=1 && e.which!=3 ) return if( ( !is.ns4 && e.button==2 ) || ( is.ns4 && e.which==3 ) ) { if( this.hasOnRUp ) { document.oncontextmenu = ocmNone this.onRUp() setTimeout( "document.oncontextmenu = ocmOrig", 100) } } else if( this.hasOnUp ) this.onUp() } Wednesday, March 7, 12
  • 6. <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Twitter Search</title> <link rel="stylesheet" href="/assets/css/index.css"> </head> <body> <h1>Twitter Search</h1> <div id="searchInput"> <form> <input placeholder="enter your search term"> <button>submit</button> </form> </div> <ul id="searchResults"></ul> <script src="/assets/js/libs/jquery.js"></script> <script src="/assets/js/app.js"></script> </body> </html> Wednesday, March 7, 12
  • 7. $('#searchInput form').submit(function(e){ e.preventDefault(); var term = $('#searchInput input').val(), req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' + escape(term)); req.then(function(resp) { var resultsHtml = $.map(resp.results, function(r) { return '<li>' + '<p class="tweet">' + r.text + '</p>' + '<p class="username">' + r.from_user + '</p>' + '</li>'; }).join(''); $('#searchResults').html(resultsHtml); }); }); Wednesday, March 7, 12
  • 9. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab // Maximize // alert('clicked section is not the current section OR full page mode is not active; full section should load'); jQuery('#md_tabs_navigation li').removeClass('current'); jQuery('#md_tab_'+ section).addClass('current'); jQuery('#md_tabs_navigation a').addClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideUp('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ bodyContent.empty(); var pageLoader = 'info/loadSection.php?sect='+ section; if (section == 'contact_us') { pageLoader = 'contact/loadContactForm.php?form_id=1'; } bodyContent.load('/app/modules/'+ pageLoader,function(){ // ADD THICKBOXES tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); $recent_news_links = jQuery('ul.md_news li a.recent_news_link'); $recent_news_links .unbind('click') .each(function(){ var hrefMod = this.href; hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id'); this.href = hrefMod; }) .click(function(){ var t = this.title || this.name || null; var a = this.href || this.alt; var g = this.rel || false; tb_show(t,a,g); this.blur(); return false; }); Wednesday, March 7, 12 // ACCORDION
  • 10. $('#btn-co-complete').live('click', function() { jobCompleted = true; $.mobile.changePage('#page-clockout-deficiency', {changeHash: false}); }); $('#btn-co-nocomplete').live('click', function() { jobCompleted = false; $.mobile.changePage('#page-clockout-deficiency', {changeHash: false}); }); $('#btn-co-nodef').live('click', function() { clockOut(activeJob, { completed:jobCompleted }, DW_JOB_COMPLETED); }); $('#btn-co-otherdef').live('click', function() { $.mobile.changePage('#page-clockout-redtag', {changeHash: false}); }); $('#btn-co-redtag').live('click', function() { clockOut(activeJob, { completed:jobCompleted, redTag:true }, DW_JOB_FOLLOWUP) }); $('#btn-co-noredtag').live('click', function() { $('#page-clockout-resolve').page(); $.mobile.changePage('#page-clockout-resolve', {changeHash: false}); }); $('#btn-clockout-resolve').live('click', function() { switch ($('#page-clockout-resolve :checked').val()) { case 'return': Wednesday, March 7, 12 clockOut(activeJob, { completed:false }, DW_JOB_RETURN);
  • 11. search input $('#searchInput form').submit(function(e){ e.preventDefault(); var term = $('#searchInput input').val(), req = $.getJSON('http://search.twitter.com/searc escape(term)); req.then(function(resp) { search data var resultsHtml = $.map(resp.results, function(r) return '<li>' + '<p class="tweet">' + r.text + '</p>' + '<p class="username">' + r.from_user + '</p>' '</li>'; }).join(''); $('#searchResults').html(resultsHtml); search results }); }); Wednesday, March 7, 12
  • 15. <script type="text/javascript" src="http://static.a2cdn.net/misc/jquery.js?9"></script> <script type="text/javascript" src="http://static.a2cdn.net/misc/drupal.js?9"></script> <script type="text/javascript" src="/google_analytics/googleanalytics.js?9"></script> <script type="text/javascript" src="/mollom/mollom.js?9"></script> <script type="text/javascript" src="/js/jquery-1.4.2.min.js?9"></script> <script type="text/javascript" src="/js/jquery-ui-1.8.4.custom.min.js?9"></script> <script type="text/javascript" src="/js/jquery.infieldlabel.min.js?9"></script> <script type="text/javascript" src="/js/jquery.nivo.slider.js?9"></script> <script type="text/javascript" src="/js/validations.js?9"></script> <script type="text/javascript" src="/js/site.js?9"></script> <script type="text/javascript" src="/js/noconflict.js?9"></script> Wednesday, March 7, 12
  • 17. require.config({ deps: ["main"], paths: { // JavaScript folders libs: "../assets/js/libs", plugins: "../assets/js/plugins", // Libraries jquery: "../assets/js/libs/jquery", underscore: "../assets/js/libs/underscore", backbone: "../assets/js/libs/backbone" } }); Wednesday, March 7, 12
  • 18. define([ "components/page", "components/search/input", "components/search/results", ], function(Page, SearchInput, SearchResults) { return { // ... }; }); Wednesday, March 7, 12
  • 19. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab // Maximize // alert('clicked section is not the current section OR full page mode is not active; full section should load'); jQuery('#md_tabs_navigation li').removeClass('current'); jQuery('#md_tab_'+ section).addClass('current'); jQuery('#md_tabs_navigation a').addClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideUp('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ bodyContent.empty(); var pageLoader = 'info/loadSection.php?sect='+ section; if (section == 'contact_us') { pageLoader = 'contact/loadContactForm.php?form_id=1'; } bodyContent.load('/app/modules/'+ pageLoader,function(){ // ADD THICKBOXES tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); $recent_news_links = jQuery('ul.md_news li a.recent_news_link'); $recent_news_links .unbind('click') .each(function(){ var hrefMod = this.href; hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id'); this.href = hrefMod; }) .click(function(){ var t = this.title || this.name || null; var a = this.href || this.alt; var g = this.rel || false; tb_show(t,a,g); this.blur(); return false; }); // ACCORDION jQuery('div.applemenu div.submenu').hide(); jQuery('div.applemenu div.silverheader < a').click( Wednesday, March 7, 12 function(){
  • 20. component controller component service components display data, observe input, and broadcast messages that controllers can react to; may also provide an API for updating Wednesday, March 7, 12
  • 21. component controller component service controllers set up components and broker communications between them, eliminating the need for direct communication Wednesday, March 7, 12
  • 22. component controller component service services expose an API for controllers to retrieve and persist data Wednesday, March 7, 12
  • 24. controller twitter search Wednesday, March 7, 12
  • 25. components display data, observe input, and broadcast messages that controllers can react to; may also provide an API for updating Wednesday, March 7, 12
  • 26. define([ "components/base" ], function(Component) { return Component({ template : "app/templates/search/input.html", className : 'search-input', events : { "submit form" : "_onSubmit" }, _onSubmit : function(e) { e.preventDefault(); var term = $.trim(this.$el.find('input')[0].value); if (!term) { return; } this.trigger('search', term); } }); }); Wednesday, March 7, 12
  • 27. <form> <input placeholder="enter your search term"> <button>submit</button> </form> Wednesday, March 7, 12
  • 28. controllers set up components and broker communications between them, eliminating the need for direct communication Wednesday, March 7, 12
  • 29. <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Searchr</title> <!-- Application styles --> <link rel="stylesheet" href="/assets/css/index.css"> </head> <body> <!-- Main container --> <div role="main" id="main"></div> <!-- Application source --> <script data-main="app/config" src="/assets/js/libs/require.js"></ script> </body> </html> Wednesday, March 7, 12
  • 30. var Router = Backbone.Router.extend({ routes: { "": "twitter", ":hash": "twitter" }, twitter : function(hash) { SearchController.init(); } }); Wednesday, March 7, 12
  • 31. define([ "components/page", "components/search/input", "components/search/results", "services/twitter" ], function(Page, SearchInput, SearchResults, twitterService) { return { init : function() { this.page = new Page({ template : 'app/templates/pages/search.html' }); this.page.render().then(_.bind(this.setupPage, this)); }, setupPage : function() { var p = this.page; this.searchInput = p.place(new SearchInput(), 'searchInput'); this.searchResults = p.place(new SearchResults(), 'searchResults'); this.searchInput.on('search', _.bind(this.handleSearch, this)); }, handleSearch : function(term) { twitterService.query(term).then(_.bind(this.showResults, this)); }, showResults : function(results) { this.searchResults.show(results); } }; }); Wednesday, March 7, 12
  • 32. services expose an API for controllers to interact with data Wednesday, March 7, 12
  • 33. define([ "use!backbone" ], function(Backbone) { var TwitterResult = Backbone.Model.extend({ // ... }); var TwitterResults = Backbone.Collection.extend({ type : 'twitter', model : TwitterResult }); return { query : function(term) { var req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' + escape(term)), dfd = $.Deferred(); req.then(function(resp) { dfd.resolve(new TwitterResults(resp.results)); }); return dfd.promise(); } }; }); Wednesday, March 7, 12
  • 34. “Writing to be read means writing code ... with the idea that someone else will read it. is fact alone will make you edit and think of better ways to solve the problem you have at hand.” Stoyan Stefanov, “JavaScript Patterns” Wednesday, March 7, 12