From 2cbbc4502c91e72648caf159e40182f387f21753 Mon Sep 17 00:00:00 2001 From: brandon flowers Date: Sat, 10 Nov 2012 15:29:44 -0500 Subject: [PATCH] update to the modular backbone tutorial to give data from github and replace users with contributors --- .gitignore | 2 + css/reset.css | 4 +- examples/modular-backbone/css/style.css | 328 +++++++++++++++++- .../modular-backbone/imgs/backbone_logo.png | Bin 0 -> 22227 bytes .../modular-backbone/imgs/require_logo.png | Bin 0 -> 6305 bytes examples/modular-backbone/index.html | 8 +- .../contributors/ContributorsCollection.js | 51 +++ .../js/collections/projects.js | 16 - .../projects/ProjectsCollection.js | 25 ++ .../js/collections/template.js | 8 - .../js/models/contributor/ContributorModel.js | 18 + .../js/models/owner/OwnerModel.js | 28 ++ .../js/models/project/ProjectModel.js | 10 + .../modular-backbone/js/models/projects.js | 15 - examples/modular-backbone/js/router.js | 53 +-- .../contributors/ContributorsListView.js | 64 ++++ .../js/views/contributors/ContributorsView.js | 60 ++++ .../contributor/ContributorView.js | 50 +++ .../js/views/footer/FooterView.js | 42 +++ .../js/views/home/HomeView.js | 25 ++ .../modular-backbone/js/views/home/main.js | 15 - .../js/views/projects/ProjectsListView.js | 27 ++ .../js/views/projects/ProjectsView.js | 43 +++ .../js/views/projects/list.js | 33 -- .../js/views/sidebar/SidebarView.js | 38 ++ .../modular-backbone/js/views/users/list.js | 19 - .../contributorsListTemplate.html | 20 ++ .../contributors/contributorsTemplate.html | 8 + .../templates/footer/footerTemplate.html | 9 + .../templates/home/homeTemplate.html | 19 + .../modular-backbone/templates/home/main.html | 7 - .../templates/projects/list.html | 5 - .../projects/projectsListTemplate.html | 5 + .../templates/projects/projectsTemplate.html | 15 + .../templates/sidebar/sidebarTemplate.html | 18 + .../templates/users/list.html | 3 - .../css/normalize.css | 4 +- 37 files changed, 942 insertions(+), 153 deletions(-) create mode 100644 examples/modular-backbone/imgs/backbone_logo.png create mode 100644 examples/modular-backbone/imgs/require_logo.png create mode 100644 examples/modular-backbone/js/collections/contributors/ContributorsCollection.js delete mode 100644 examples/modular-backbone/js/collections/projects.js create mode 100644 examples/modular-backbone/js/collections/projects/ProjectsCollection.js delete mode 100644 examples/modular-backbone/js/collections/template.js create mode 100644 examples/modular-backbone/js/models/contributor/ContributorModel.js create mode 100644 examples/modular-backbone/js/models/owner/OwnerModel.js create mode 100644 examples/modular-backbone/js/models/project/ProjectModel.js delete mode 100644 examples/modular-backbone/js/models/projects.js create mode 100644 examples/modular-backbone/js/views/contributors/ContributorsListView.js create mode 100644 examples/modular-backbone/js/views/contributors/ContributorsView.js create mode 100644 examples/modular-backbone/js/views/contributors/contributor/ContributorView.js create mode 100644 examples/modular-backbone/js/views/footer/FooterView.js create mode 100644 examples/modular-backbone/js/views/home/HomeView.js delete mode 100644 examples/modular-backbone/js/views/home/main.js create mode 100644 examples/modular-backbone/js/views/projects/ProjectsListView.js create mode 100644 examples/modular-backbone/js/views/projects/ProjectsView.js delete mode 100644 examples/modular-backbone/js/views/projects/list.js create mode 100644 examples/modular-backbone/js/views/sidebar/SidebarView.js delete mode 100644 examples/modular-backbone/js/views/users/list.js create mode 100644 examples/modular-backbone/templates/contributors/contributorsListTemplate.html create mode 100644 examples/modular-backbone/templates/contributors/contributorsTemplate.html create mode 100644 examples/modular-backbone/templates/footer/footerTemplate.html create mode 100644 examples/modular-backbone/templates/home/homeTemplate.html delete mode 100644 examples/modular-backbone/templates/home/main.html delete mode 100644 examples/modular-backbone/templates/projects/list.html create mode 100644 examples/modular-backbone/templates/projects/projectsListTemplate.html create mode 100644 examples/modular-backbone/templates/projects/projectsTemplate.html create mode 100644 examples/modular-backbone/templates/sidebar/sidebarTemplate.html delete mode 100644 examples/modular-backbone/templates/users/list.html diff --git a/.gitignore b/.gitignore index e14e9fee..f8852f79 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *config.js *node_modules/ .DS_Store +*.sublime-project +*.sublime-workspace \ No newline at end of file diff --git a/css/reset.css b/css/reset.css index 5b41bb7b..7d70d025 100644 --- a/css/reset.css +++ b/css/reset.css @@ -130,8 +130,8 @@ input:invalid, textarea:invalid { /* These selection declarations have to be separate No text-shadow: twitter.com/miketaylr/status/12228805301 Also: hot pink! */ -::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; } -::selection { background:#FF5E99; color:#fff; text-shadow: none; } +::-moz-selection{ background: #666; color:#fff; text-shadow: none; } +::selection { background:#666; color:#fff; text-shadow: none; } /* j.mp/webkit-tap-highlight-color */ a:link { -webkit-tap-highlight-color: #FF5E99; } diff --git a/examples/modular-backbone/css/style.css b/examples/modular-backbone/css/style.css index 7631f592..86fe9755 100644 --- a/examples/modular-backbone/css/style.css +++ b/examples/modular-backbone/css/style.css @@ -41,8 +41,8 @@ body, button, input, select, textarea { font-family: sans-serif; color: #222; } * Also: hot pink! */ -::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; } -::selection { background: #fe57a1; color: #fff; text-shadow: none; } +::-moz-selection { background: #666; color: #fff; text-shadow: none; } +::selection { background: #666; color: #fff; text-shadow: none; } /* ============================================================================= @@ -245,11 +245,333 @@ h1{ border-bottom: 1px solid #ebebeb; min-height: 400px; padding: 20px; + overflow: hidden; } +#page { + +} + + #page .main { + display: block; + position:relative; + top: 0px; + left: 0px; + padding: 0px; + margin: 0px; + width: 500px; + float: left; + overflow: hidden; + } + + #page .sidebar { + display: block; + position:relative; + top: 0px; + left: 0px; + padding: 10px; + margin: 0px; + width: 400px; + height: 300px; + background-color:#FFF; + float: left; + } + + #page .sidebar .ad { + clear:both; + } + + #page .sidebar .ad .pic { + display: block; + position: relative; + margin: 0px; + padding: 0px; + float: left; + top: 0px; + left: 0px; + width: 150px; + } + + #page .sidebar .ad .info { + display: block; + position: relative; + margin: 0px; + padding: 0px; + float: left; + top: 0px; + left: 0px; + width: 250px; + } + + #page .sidebar .ad .info h4 { + font-size: 16px; + color:#666; + } + + #page .sidebar .ad .info p { + font-size: 10px; + color:#999; + } + +#page .contributors-stats ul { + list-style: none; +} + +#page .contributors-stats ul li { + display:block; + position: relative; + height: 20px; +} + +#page .contributors-stats ul li p { + font-size: 20px; + color:#999; + font-weight: bold; + margin: 0px; + padding: 0px; +} + +#page #contributors-list { + +} + +#page #contributors-list ul.contributors { + list-style: none; + margin: 0px; + padding: 0px; + } + + #page #contributors-list ul.contributors li { + display: block; + position: relative; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + float: left; + } + + #page #contributors-list ul.contributors li div.contributor { + display: block; + position: relative; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + border: 1px solid #CCC; + } + + #page #contributors-list ul.contributors li div.contributor ul { + list-style: none; + margin: 0px; + padding: 0px; + + } + + #page #contributors-list ul.contributors li div.contributor ul li { + display: block; + position: absolute; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + } + + #page #contributors-list ul.contributors li div.contributor ul li.username { + z-index: 2; + height: 14px; + border: none; + } + + #page #contributors-list ul.contributors li div.contributor ul li.username p { + display:block; + position: absolute; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + width: 100%; + height: 14px; + background-color: #CCC; + text-align: center; + font-size: 10px; + font-weight: bold; + color:#999; + } + + #page #contributors-list ul.contributors li div.contributor ul li.username p a { + color:#999; + text-decoration: none; + } + + #page #contributors-list ul.contributors li div.contributor ul li.username p a:hover { + color:#334231; + } + + #page #contributors-list ul.contributors li div.contributor ul li.pic { + z-index: 1; + } + + #page #contributors-list ul.contributors li div.contributor ul li.pic a { + display:block; + position: absolute; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + width: 100%; + border: none; + } + + #page #contributors-list ul.contributors li div.contributor ul li.pic p { + display: block; + position: absolute; + margin: 0px; + padding: 0px; + top: 0px; + left: 0px; + width: 100%; + } + + #page #contributors-list ul.contributors li div.contributor ul li.contributions { + z-index: 3; + pointer-events:none; + } + + #page #contributors-list ul.contributors li div.contributor ul li.contributions p { + display:block; + position: absolute; + left:0px; + width:100%; + height: 15%; + top: 85%; + background-color: #333; + text-align: center; + font-size: 10px; + font-weight: bold; + color:#666; + margin:0px; + padding:0px; + } + + #footer { - text-align: center; + display: block; + position:relative; + text-align: left; + background-color:#CCC; + height: 100px; + margin:0px; + padding:0px; + -webkit-box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.35); + box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.35); +} + +#footer ul { + list-style-type: none; + margin:0px; + padding:0px; +} + +#footer ul li { + display:block; + position:relative; + width: 100%; + height: 20px; + margin: 0px; + padding: 0px; +} + +#footer p { + font-size: 20px; + font-weight: bold; + color: rgba(153, 153, 153, 0.35); + margin: 0px; + padding: 0px; +} + +#footer .pic { + display:block; + position:absolute; + float: left; + margin:5px; + padding:0px; + width: 90px; + height: 90px; + top: 0px; + left: 0px; +} + +#footer .pic a { + display:block; + position:absolute; + margin:0px; + padding:0px; + width: 90px; + height: 90px; + top: 0px; + left: 0px; + border: 1px #999 solid; +} + +#footer .pic a img { + display:block; + position:absolute; + margin:0px; + padding:0px; + width: 90px; + height: 90px; + top: 0px; + left: 0px; + filter: grayscale(100%); + /*filter: url(filters.svg#grayscale); + filter: gray;*/ + -webkit-filter: grayscale(100%); + -moz-filter: grayscale(100%); + -ms-filter: grayscale(100%); + -o-filter: grayscale(100%); +} + +#footer .info { + display:block; + position:relative; + float: left; + margin:0px; + padding:0px; + width: 100%; + height: 100px; + top: 10px; + left: 120px; +} + + + +/* ============================================================================= + Page styles + ========================================================================== */ + +#home { + } + +#home .main { + +} + +#home #sidebar { + +} + +#projects { + +} + +#contributors { + +} + + + /* ============================================================================= Non-semantic helper classes Please define your styles before this section. diff --git a/examples/modular-backbone/imgs/backbone_logo.png b/examples/modular-backbone/imgs/backbone_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b98d878d1c10cccb7280a76aa5278f45111b4793 GIT binary patch literal 22227 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
>a0`` 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 XX^(OwG$CXo00000NkvXXu0mjfx6mc9 literal 0 HcmV?d00001 diff --git a/examples/modular-backbone/index.html b/examples/modular-backbone/index.html index 149f05bb..b9a123ee 100644 --- a/examples/modular-backbone/index.html +++ b/examples/modular-backbone/index.html @@ -26,16 +26,14 @@

Modular Backbone

Loading....
- + diff --git a/examples/modular-backbone/js/collections/contributors/ContributorsCollection.js b/examples/modular-backbone/js/collections/contributors/ContributorsCollection.js new file mode 100644 index 00000000..78a9b4d0 --- /dev/null +++ b/examples/modular-backbone/js/collections/contributors/ContributorsCollection.js @@ -0,0 +1,51 @@ +define([ + 'underscore', + 'backbone', + 'models/contributor/ContributorModel' +], function(_, Backbone, ContributorModel){ + + var ContributorsCollection = Backbone.Collection.extend({ + + model: ContributorModel, + + initialize : function(models, options) {}, + + url : function() { + return 'https://api.github.com/repos/thomasdavis/backbonetutorials/contributors'; + }, + + parse : function(data) { + var uniqueArray = this.removeDuplicates(data); + return uniqueArray; + }, + + removeDuplicates: function(myArray) { + + //credit: http://newcodeandroll.blogspot.ca/2012/01/how-to-find-duplicates-in-array-in.html + // I was hoping underscore's _uniq would work here but it only seems to work for single values not objects + var length = myArray.length; + var ArrayWithUniqueValues = []; + + var objectCounter = {}; + + for (i = 0; i < length; i++) { + + var currentMemboerOfArrayKey = JSON.stringify(myArray[i]); + var currentMemboerOfArrayValue = myArray[i]; + + if (objectCounter[currentMemboerOfArrayKey] === undefined){ + ArrayWithUniqueValues.push(currentMemboerOfArrayValue); + objectCounter[currentMemboerOfArrayKey] = 1; + }else{ + objectCounter[currentMemboerOfArrayKey]++; + } + } + + return ArrayWithUniqueValues; + } + + }); + + return ContributorsCollection; + +}); \ No newline at end of file diff --git a/examples/modular-backbone/js/collections/projects.js b/examples/modular-backbone/js/collections/projects.js deleted file mode 100644 index ae7c7b72..00000000 --- a/examples/modular-backbone/js/collections/projects.js +++ /dev/null @@ -1,16 +0,0 @@ -define([ - 'jquery', - 'underscore', - 'backbone', - 'models/projects' -], function($, _, Backbone, ProjectsModel){ - var ProjectsCollection = Backbone.Collection.extend({ - model: ProjectsModel, - initialize: function(){ - - } - - }); - - return ProjectsCollection; -}); diff --git a/examples/modular-backbone/js/collections/projects/ProjectsCollection.js b/examples/modular-backbone/js/collections/projects/ProjectsCollection.js new file mode 100644 index 00000000..a8b0676b --- /dev/null +++ b/examples/modular-backbone/js/collections/projects/ProjectsCollection.js @@ -0,0 +1,25 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'models/project/ProjectModel' +], function($, _, Backbone, ProjectModel){ + var ProjectsCollection = Backbone.Collection.extend({ + model: ProjectModel, + + initialize: function(){ + + var project0 = new ProjectModel('Cross Domain', 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/cross-domain'); + var project1 = new ProjectModel('Infinite Scroll', 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/infinite-scroll'); + var project2 = new ProjectModel('Modular Backbone','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/modular-backbone'); + var project3 = new ProjectModel('Node MongoDB Mongoose Restify','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify'); + var project4 = new ProjectModel('Todo App','https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/todo-app'); + + //this.add([project0, project1, project2, project3, project4]); + + } + + }); + + return ProjectsCollection; +}); diff --git a/examples/modular-backbone/js/collections/template.js b/examples/modular-backbone/js/collections/template.js deleted file mode 100644 index 0b3ccfc5..00000000 --- a/examples/modular-backbone/js/collections/template.js +++ /dev/null @@ -1,8 +0,0 @@ -define([ - 'jquery', - 'underscore', - 'backbone' -], function($, _, Backbone){ - - return {}; -}); diff --git a/examples/modular-backbone/js/models/contributor/ContributorModel.js b/examples/modular-backbone/js/models/contributor/ContributorModel.js new file mode 100644 index 00000000..6bd95a40 --- /dev/null +++ b/examples/modular-backbone/js/models/contributor/ContributorModel.js @@ -0,0 +1,18 @@ +define([ + 'underscore', + 'backbone', +], function(_, Backbone) { + + var ContributorModel = Backbone.Model.extend({ + + defaults : { + medalHex : '#A67D3D', + picWidth : '100px', + githubPath : 'concat github and login' + } + + }); + + return ContributorModel; + +}); diff --git a/examples/modular-backbone/js/models/owner/OwnerModel.js b/examples/modular-backbone/js/models/owner/OwnerModel.js new file mode 100644 index 00000000..0867f566 --- /dev/null +++ b/examples/modular-backbone/js/models/owner/OwnerModel.js @@ -0,0 +1,28 @@ +define([ + 'underscore', + 'backbone', +], function(_, Backbone) { + + var OwnerModel = Backbone.Model.extend({ + + defaults : { + query : "unknown" + }, + + initialize: function( options ) { + this.query = options.query; + }, + + url : function() { + return 'https://api.github.com/users/' + this.query; + }, + + parse : function(data) { + return data; + } + + }); + + return OwnerModel; + +}); diff --git a/examples/modular-backbone/js/models/project/ProjectModel.js b/examples/modular-backbone/js/models/project/ProjectModel.js new file mode 100644 index 00000000..ffbc25dc --- /dev/null +++ b/examples/modular-backbone/js/models/project/ProjectModel.js @@ -0,0 +1,10 @@ +define([ + 'underscore', + 'backbone' +], function(_, Backbone) { + + var ProjectModel = Backbone.Model.extend({}); + + return ProjectModel; + +}); diff --git a/examples/modular-backbone/js/models/projects.js b/examples/modular-backbone/js/models/projects.js deleted file mode 100644 index 63ce123c..00000000 --- a/examples/modular-backbone/js/models/projects.js +++ /dev/null @@ -1,15 +0,0 @@ -define([ - 'underscore', - 'backbone' -], function(_, Backbone) { - var ProjectsModel = Backbone.Model.extend({ - defaults: { - score: 10 - }, - initialize: function(){ - } - - }); - return ProjectsModel; - -}); diff --git a/examples/modular-backbone/js/router.js b/examples/modular-backbone/js/router.js index 4175c59d..9239cb2f 100644 --- a/examples/modular-backbone/js/router.js +++ b/examples/modular-backbone/js/router.js @@ -2,13 +2,17 @@ define([ 'jquery', 'underscore', - 'backbone' -], function($, _, Backbone ){ + 'backbone', + 'views/home/HomeView', + 'views/projects/ProjectsView', + 'views/contributors/ContributorsView', + 'views/footer/FooterView' +], function($, _, Backbone, HomeView, ProjectsView, ContributorsView, FooterView) { var AppRouter = Backbone.Router.extend({ routes: { // Define some URL routes 'projects': 'showProjects', - 'users': 'showUsers', + 'users': 'showContributors', // Default '*actions': 'defaultAction' @@ -16,29 +20,38 @@ define([ }); var initialize = function(){ var app_router = new AppRouter; + app_router.on('route:showProjects', function(){ - require(['views/projects/list'], function(ProjectListView) { + // Call render on the module we loaded in via the dependency array - // 'views/projects/list' - var projectListView = new ProjectListView(); - projectListView.render(); - }) + var projectsView = new ProjectsView(); + projectsView.render(); + }); - app_router.on('route:showUsers', function () { - require(['views/users/list'], function(UserListView) { - // As above, call render on our loaded module - // 'views/users/list' - var userListView = new UserListView(); - userListView.render(); - }); + + app_router.on('route:showContributors', function () { + + // Like above, call render but know that this view has nested sub views which + // handle loading and displaying data from the GitHub API + var contributorsView = new ContributorsView(); + //contributorsView.initialize(); + //contributorsView.render(); + }); + app_router.on('route:defaultAction', function (actions) { - require(['views/home/main'], function(MainHomeView) { - // We have no matching route, lets display the home page - var mainHomeView = new MainHomeView(); - mainHomeView.render(); - }); + + // We have no matching route, lets display the home page + var homeView = new HomeView(); + homeView.render(); + + // unlike the above, we don't call render on this view + // as it will handle the render call internally after it + // loads data + var footerView = new FooterView(); + }); + Backbone.history.start(); }; return { diff --git a/examples/modular-backbone/js/views/contributors/ContributorsListView.js b/examples/modular-backbone/js/views/contributors/ContributorsListView.js new file mode 100644 index 00000000..629e96fc --- /dev/null +++ b/examples/modular-backbone/js/views/contributors/ContributorsListView.js @@ -0,0 +1,64 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'collections/contributors/ContributorsCollection', + 'text!templates/contributors/contributorsListTemplate.html' +], function($, _, Backbone, ContributorsCollection, contributorListTemplate){ + + var ContributorsListView = Backbone.View.extend({ + el : $("#contributors-list"), + tagName:"ul", + render : function() { + + var that = this; + that.awardMedals(this.collection.models); + + var data = { + contributors: this.collection.models, + _: _ + }; + + var compiledTemplate = _.template( contributorListTemplate, data ); + $("#contributors-list").html( compiledTemplate ); + + return this; + }, + + awardMedals : function(aModels) { + var goldMedalHex = '#CFB52B'; + var silverMedalHex = '#E6E8FA'; + var bronzeMedalHex = '#A67D3D'; + var githubPath; + + _.each(aModels, function(contributor) { + + var contributions = Number ( contributor.get( 'contributions' ) ); + var medalHex; + var picWidth; + + if ( contributions >= 50 ) { + medalHex = goldMedalHex; + picWidth = '160px'; + } else if ( contributions < 50 && contributions >= 5) { + medalHex = silverMedalHex; + picWidth = '120px'; + } else { + medalHex = bronzeMedalHex; + picWidth = '80px'; + } + + githubPath = "https://github.com/" + contributor.get('login'); + + contributor.set( 'medalHex', medalHex); + contributor.set( 'picWidth', picWidth); + contributor.set( 'githubPath', githubPath); + + }); + } + + }); + + return ContributorsListView; + +}); diff --git a/examples/modular-backbone/js/views/contributors/ContributorsView.js b/examples/modular-backbone/js/views/contributors/ContributorsView.js new file mode 100644 index 00000000..24644c92 --- /dev/null +++ b/examples/modular-backbone/js/views/contributors/ContributorsView.js @@ -0,0 +1,60 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'collections/contributors/ContributorsCollection', + 'views/contributors/ContributorsListView', + 'text!templates/contributors/contributorsTemplate.html' +], function($, _, Backbone, ContributorsCollection, ContributorsListView, contributorsTemplate){ + + var ContributorsView = Backbone.View.extend({ + + el: $("#page"), + + initialize:function() { + + var that = this; + + var onDataHandler = function(collection) { + that.render(); + } + + this.collection = new ContributorsCollection([]); + this.collection.fetch({ success : onDataHandler }); + + }, + + render: function(){ + + var total_contributions = this.getTotalContributions(this.collection.models); + var total_contributors = this.collection.models.length; + + var data = { total_contributions : total_contributions, + total_contributors : total_contributors}; + + // main view + var compiledTemplate = _.template( contributorsTemplate, data ); + this.$el.html( compiledTemplate ); + + // sub view + var contributorsListView = new ContributorsListView({ collection: this.collection}); + contributorsListView.render(); + + }, + + getTotalContributions:function( aModels ){ + + var total = 0; + + _.each(aModels, function(contributorModel) { + var contributorContributions = Number ( contributorModel.get("contributions") ); + total += contributorContributions; + }); + + return total; + } + + + }); + return ContributorsView; +}); diff --git a/examples/modular-backbone/js/views/contributors/contributor/ContributorView.js b/examples/modular-backbone/js/views/contributors/contributor/ContributorView.js new file mode 100644 index 00000000..299153dd --- /dev/null +++ b/examples/modular-backbone/js/views/contributors/contributor/ContributorView.js @@ -0,0 +1,50 @@ +define([ + 'underscore', + 'backbone', + 'models/contributor/ContributorModel' +], function(_, Backbone, ContributorModel){ + + var ContributorView = Backbone.View.extend({ + tagName : "li", + render : function() { + + var contributor = { avatar_url : this.model.get("avatar_url"), + login : this.model.get("login"), + url : this.model.get("url"), + contributions: this.model.get("contributions")}; + + //console.log("view created"); + + /* + var contributorTemplate = '
' + + '
    ' + + '
  • ' + + '' + + '
  • ' + + '
  • ' + + '

    <%= login %>

    ' + + '
  • ' + + '
  • ' + + '

    <%= contributions %>

    ' + + '
  • ' + + '
' + + '
'; + + //var contributorTemplate = $('#contributor-underscore-template').html(); hmmmmm???? + + var rendered_template = _.template(contributorTemplate, contributor); + //console.log(rendered_template,contributor); + + $(this.el).append(rendered_template); + */ + + + + return this; + } + + }); + + return ContributorModel; + +}); \ No newline at end of file diff --git a/examples/modular-backbone/js/views/footer/FooterView.js b/examples/modular-backbone/js/views/footer/FooterView.js new file mode 100644 index 00000000..ed4412d1 --- /dev/null +++ b/examples/modular-backbone/js/views/footer/FooterView.js @@ -0,0 +1,42 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'models/owner/OwnerModel', + 'text!templates/footer/footerTemplate.html' +], function($, _, Backbone, OwnerModel, footerTemplate){ + + var FooterView = Backbone.View.extend({ + el: $("#footer"), + + initialize: function() { + + var that = this; + var options = {query: 'thomasdavis'} + + + var onDataHandler = function(collection) { + that.render(); + } + + this.model = new OwnerModel(options); + this.model.fetch({ success : onDataHandler }); + + }, + + render: function(){ + + var data = { + owner: this.model.toJSON(), + _: _ + }; + + var compiledTemplate = _.template( footerTemplate, data ); + this.$el.html(compiledTemplate); + } + + }); + + return FooterView; + +}); diff --git a/examples/modular-backbone/js/views/home/HomeView.js b/examples/modular-backbone/js/views/home/HomeView.js new file mode 100644 index 00000000..6c884f48 --- /dev/null +++ b/examples/modular-backbone/js/views/home/HomeView.js @@ -0,0 +1,25 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'views/sidebar/SidebarView', + 'text!templates/home/homeTemplate.html' +], function($, _, Backbone, SidebarView, homeTemplate){ + + var HomeView = Backbone.View.extend({ + el: $("#page"), + + render: function(){ + + this.$el.html(homeTemplate); + + var sidebarView = new SidebarView(); + sidebarView.render(); + + } + + }); + + return HomeView; + +}); diff --git a/examples/modular-backbone/js/views/home/main.js b/examples/modular-backbone/js/views/home/main.js deleted file mode 100644 index 9ccffaff..00000000 --- a/examples/modular-backbone/js/views/home/main.js +++ /dev/null @@ -1,15 +0,0 @@ -define([ - 'jquery', - 'underscore', - 'backbone', - 'text!templates/home/main.html' -], function($, _, Backbone, mainHomeTemplate){ - - var MainHomeView = Backbone.View.extend({ - el: $("#page"), - render: function(){ - this.$el.html(mainHomeTemplate); - } - }); - return MainHomeView; -}); diff --git a/examples/modular-backbone/js/views/projects/ProjectsListView.js b/examples/modular-backbone/js/views/projects/ProjectsListView.js new file mode 100644 index 00000000..9eedea33 --- /dev/null +++ b/examples/modular-backbone/js/views/projects/ProjectsListView.js @@ -0,0 +1,27 @@ +// Filename: views/projects/list +define([ + 'jquery', + 'underscore', + 'backbone', + // Pull in the Collection module from above, + 'models/project/ProjectModel', + 'collections/projects/ProjectsCollection', + 'text!templates/projects/projectsListTemplate.html' + +], function($, _, Backbone, ProjectModel, ProjectsCollection, projectsListTemplate){ + var ProjectListView = Backbone.View.extend({ + el: $("#projects-list"), + + render: function(){ + + var data = { + projects: this.collection.models, + _: _ + }; + + var compiledTemplate = _.template( projectsListTemplate, data ); + $("#projects-list").html( compiledTemplate ); + } + }); + return ProjectListView; +}); diff --git a/examples/modular-backbone/js/views/projects/ProjectsView.js b/examples/modular-backbone/js/views/projects/ProjectsView.js new file mode 100644 index 00000000..64d268ca --- /dev/null +++ b/examples/modular-backbone/js/views/projects/ProjectsView.js @@ -0,0 +1,43 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'views/sidebar/SidebarView', + 'models/project/ProjectModel', + 'collections/projects/ProjectsCollection', + 'views/projects/ProjectsListView', + 'text!templates/projects/projectsTemplate.html' +], function($, _, Backbone, SidebarView, ProjectModel, ProjectsCollection, ProjectsListView, projectsTemplate){ + + var ProjectsView = Backbone.View.extend({ + el: $("#page"), + render: function(){ + + this.$el.html(projectsTemplate); + + var project0 = new ProjectModel({title: 'Cross Domain', url: 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/cross-domain'}); + var project1 = new ProjectModel({title:'Infinite Scroll', url: 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/infinite-scroll'}); + var project2 = new ProjectModel({title:'Modular Backbone', url: 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/modular-backbone'}); + var project3 = new ProjectModel({title:'Node MongoDB Mongoose Restify', url: 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/nodejs-mongodb-mongoose-restify'}); + var project4 = new ProjectModel({title:'Todo App', url: 'https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/todo-app'}); + + var aProjects = [project0, + project1, + project2, + project3, + project4]; + + var projectsCollection = new ProjectsCollection(aProjects); + var projectsListView = new ProjectsListView({ collection: projectsCollection}); + + projectsListView.render(); + + // add the sidebar + var sidebarView = new SidebarView(); + sidebarView.render(); + + } + }); + + return ProjectsView; +}); diff --git a/examples/modular-backbone/js/views/projects/list.js b/examples/modular-backbone/js/views/projects/list.js deleted file mode 100644 index f0f01794..00000000 --- a/examples/modular-backbone/js/views/projects/list.js +++ /dev/null @@ -1,33 +0,0 @@ -// Filename: views/projects/list -define([ - 'jquery', - 'underscore', - 'backbone', - // Pull in the Collection module from above - 'collections/projects', - 'text!templates/projects/list.html' - -], function($, _, Backbone, ProjectsCollection, projectListTemplate){ - var projectListView = Backbone.View.extend({ - el: $("#page"), - initialize: function(){ - this.collection = new ProjectsCollection(); - this.collection.bind("add", this.exampleBind); - this.collection = this.collection.add({ name: "Twitter"}); - this.collection = this.collection.add({ name: "Facebook"}); - this.collection = this.collection.add({ name: "Myspace", score: 20}); - }, - exampleBind: function( model ){ - //console.log(model); - }, - render: function(){ - var data = { - projects: this.collection.models, - _: _ - }; - var compiledTemplate = _.template( projectListTemplate, data ); - this.$el.html( compiledTemplate ); - } - }); - return projectListView; -}); diff --git a/examples/modular-backbone/js/views/sidebar/SidebarView.js b/examples/modular-backbone/js/views/sidebar/SidebarView.js new file mode 100644 index 00000000..ba6babb6 --- /dev/null +++ b/examples/modular-backbone/js/views/sidebar/SidebarView.js @@ -0,0 +1,38 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'text!templates/sidebar/sidebarTemplate.html' +], function($, _, Backbone, sidebarTemplate){ + + var SidebarView = Backbone.View.extend({ + el: $(".sidebar"), + + render: function(){ + + var that = this; + + var backbone_ad = { site_url : "http://www.backbonejs.org" , + image_url : "./imgs/backbone_logo.png", + title : "Backbone.js", + description: "Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface." }; + + var require_ad = { site_url : "http://www.requirejs.org" , + image_url : "./imgs/require_logo.png", + title : "Require.js", + description: "RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node." }; + + var data = { + ads: [backbone_ad, require_ad] + }; + + var compiledTemplate = _.template( sidebarTemplate, data ); + + $(".sidebar").append(compiledTemplate); + } + + }); + + return SidebarView; + +}); diff --git a/examples/modular-backbone/js/views/users/list.js b/examples/modular-backbone/js/views/users/list.js deleted file mode 100644 index 4348fa1b..00000000 --- a/examples/modular-backbone/js/views/users/list.js +++ /dev/null @@ -1,19 +0,0 @@ -// Filename: views/projects/list -define([ - 'jquery', - 'underscore', - 'backbone', - 'text!templates/users/list.html' -], function($, _, Backbone, userListTemplate){ - var UserListView = Backbone.View.extend({ - el: $("#page"), - initialize: function(){ - }, - render: function(){ - var data = {}; - var compiledTemplate = _.template( userListTemplate, data ); - this.$el.html( compiledTemplate ); - } - }); - return UserListView; -}); diff --git a/examples/modular-backbone/templates/contributors/contributorsListTemplate.html b/examples/modular-backbone/templates/contributors/contributorsListTemplate.html new file mode 100644 index 00000000..5b809ec3 --- /dev/null +++ b/examples/modular-backbone/templates/contributors/contributorsListTemplate.html @@ -0,0 +1,20 @@ + + diff --git a/examples/modular-backbone/templates/contributors/contributorsTemplate.html b/examples/modular-backbone/templates/contributors/contributorsTemplate.html new file mode 100644 index 00000000..db9a834e --- /dev/null +++ b/examples/modular-backbone/templates/contributors/contributorsTemplate.html @@ -0,0 +1,8 @@ +
+
    +
  • total contributions: <%= total_contributions %>

  • +
  • total contributors: <%= total_contributors %>

  • +
+
+
+ diff --git a/examples/modular-backbone/templates/footer/footerTemplate.html b/examples/modular-backbone/templates/footer/footerTemplate.html new file mode 100644 index 00000000..61a25ff3 --- /dev/null +++ b/examples/modular-backbone/templates/footer/footerTemplate.html @@ -0,0 +1,9 @@ +
+
+
    +
  • OWNER <%= owner.name %>

  • +
  • LOCATION <%= owner.location %>

  • +
  • PUBLIC REPOS <%= owner.public_repos %>

  • +
  • PUBLIC GISTS <%= owner.public_gists %>

  • +
+
diff --git a/examples/modular-backbone/templates/home/homeTemplate.html b/examples/modular-backbone/templates/home/homeTemplate.html new file mode 100644 index 00000000..472410f4 --- /dev/null +++ b/examples/modular-backbone/templates/home/homeTemplate.html @@ -0,0 +1,19 @@ +
+

Organizing your application using Modules (require.js)

+

+ Unfortunately Backbone.js does not tell you how to organize your code, leaving many developers in the dark regarding how to load scripts and lay out their development environments. +

+

+ This was quite a different decision to other JavaScript MVC frameworks who were more in favor of setting a development philosophy. Hopefully this tutorial will allow you to build a much more robust project with great separation of concerns between design and code. +

+

+ This tutorial will get you started on combining Backbone.js with AMD (Asynchronous Module Definitions) through Require.js. In addition to Require.js, Text.js plays a significant role by loading the html templates and preparing them for the underscore templating process. +

+ read full article +

+

+ Take advantage of Require.js compiler! My dying words would be to tell you to try r.js +

+
+ + diff --git a/examples/modular-backbone/templates/home/main.html b/examples/modular-backbone/templates/home/main.html deleted file mode 100644 index ce01a39c..00000000 --- a/examples/modular-backbone/templates/home/main.html +++ /dev/null @@ -1,7 +0,0 @@ -Welcome to the Modular Backbone homepage. - -There are many benefits of combining Require.js with Backbone.js - -
    -
  • Take advantage of Require.js compiler! My dying words would be to tell you to try r.js
  • -
diff --git a/examples/modular-backbone/templates/projects/list.html b/examples/modular-backbone/templates/projects/list.html deleted file mode 100644 index 03f16094..00000000 --- a/examples/modular-backbone/templates/projects/list.html +++ /dev/null @@ -1,5 +0,0 @@ -
    - <% _.each(projects, function(project){ %> -
  • <%= project.get("name") %> - <%= project.get("score") %>
  • - <% }); %> -
diff --git a/examples/modular-backbone/templates/projects/projectsListTemplate.html b/examples/modular-backbone/templates/projects/projectsListTemplate.html new file mode 100644 index 00000000..2f248586 --- /dev/null +++ b/examples/modular-backbone/templates/projects/projectsListTemplate.html @@ -0,0 +1,5 @@ + diff --git a/examples/modular-backbone/templates/projects/projectsTemplate.html b/examples/modular-backbone/templates/projects/projectsTemplate.html new file mode 100644 index 00000000..3b0203c6 --- /dev/null +++ b/examples/modular-backbone/templates/projects/projectsTemplate.html @@ -0,0 +1,15 @@ +
+

Projects

+

+ This site is by no means the definite guide to backbone.js and all corrections and contributions are welcome. About Backbone Tutorials +

+

+ As single page apps and large scale javascript applications become more prominent on the web, useful resources for those developers who are jumping the ship are crucial +

+

+ I started this site to not only consolidate my understanding of backbone.js but to also document what I have learned thus far for myself and others. +

+
+
+ + diff --git a/examples/modular-backbone/templates/sidebar/sidebarTemplate.html b/examples/modular-backbone/templates/sidebar/sidebarTemplate.html new file mode 100644 index 00000000..664b6d2e --- /dev/null +++ b/examples/modular-backbone/templates/sidebar/sidebarTemplate.html @@ -0,0 +1,18 @@ +
+
+ +
+
+

<%= ads[0].title %>

+

<%= ads[0].description %>

+
+
+
+
+ +
+
+

<%= ads[1].title %>

+

<%= ads[1].description %>

+
+
diff --git a/examples/modular-backbone/templates/users/list.html b/examples/modular-backbone/templates/users/list.html deleted file mode 100644 index 12d06fee..00000000 --- a/examples/modular-backbone/templates/users/list.html +++ /dev/null @@ -1,3 +0,0 @@ -
    -
  • User 1
  • -
diff --git a/examples/nodejs-mongodb-mongoose-restify/css/normalize.css b/examples/nodejs-mongodb-mongoose-restify/css/normalize.css index 8dba8d22..cfb73ab9 100644 --- a/examples/nodejs-mongodb-mongoose-restify/css/normalize.css +++ b/examples/nodejs-mongodb-mongoose-restify/css/normalize.css @@ -41,8 +41,8 @@ body, button, input, select, textarea { font-family: sans-serif; color: #222; } * Also: hot pink! */ -::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; } -::selection { background: #fe57a1; color: #fff; text-shadow: none; } +::-moz-selection { background: #666; color: #fff; text-shadow: none; } +::selection { background: #666; color: #fff; text-shadow: none; } /* =============================================================================