├── LICENSE.txt
├── README.md
├── codes
├── Ch1_Introduction
│ └── Example1
│ │ └── Example-1.html
├── Ch2_Model
│ ├── Examples
│ │ ├── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ │ ├── Example2
│ │ │ ├── Example-2.html
│ │ │ └── example-main-2.js
│ │ ├── Example3
│ │ │ ├── Example-3.html
│ │ │ └── example-main-3.js
│ │ ├── Example4
│ │ │ ├── Example-4.html
│ │ │ └── example-main-4.js
│ │ └── Example5
│ │ │ ├── Example-5.html
│ │ │ └── example-main-5.js
│ └── README.md
├── Ch3_View_Events_Templates
│ ├── Ch3_1_View
│ │ └── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ ├── Ch3_2_Templating
│ │ ├── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ │ ├── Example2
│ │ │ ├── Example-2.html
│ │ │ └── example-main-2.js
│ │ └── Example3
│ │ │ ├── Example-3.html
│ │ │ └── example-main-3.js
│ ├── Ch3_3_Events
│ │ ├── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ │ ├── Example2
│ │ │ ├── Example-2.html
│ │ │ └── example-main-2.js
│ │ ├── Example3
│ │ │ ├── Example-3.html
│ │ │ └── example-main-3.js
│ │ └── Example4
│ │ │ ├── Example-4.html
│ │ │ └── example-main-4.js
│ └── README.md
├── Ch4_Collection
│ ├── Examples
│ │ ├── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ │ ├── Example2
│ │ │ ├── Example-2.html
│ │ │ └── example-main-2.js
│ │ └── Example3
│ │ │ ├── Example-3.html
│ │ │ └── example-main-3.js
│ └── README.md
├── Ch5_Router
│ ├── Examples
│ │ └── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ └── README.md
├── Ch6_Extended-Session
│ ├── Application Examples
│ │ ├── Example1
│ │ │ ├── Example-1.html
│ │ │ └── example-main-1.js
│ │ ├── Example2
│ │ │ ├── Example-2.html
│ │ │ └── example-main-2.js
│ │ ├── Example3
│ │ │ ├── Example-3.html
│ │ │ └── example-main-3.js
│ │ ├── Example4
│ │ │ ├── Example-4.html
│ │ │ └── example-main-4.js
│ │ ├── Example5
│ │ │ ├── Example-5.html
│ │ │ └── example-main-5.js
│ │ └── README.md
│ └── Plugins Examples
│ │ ├── Models
│ │ ├── Deep-Model
│ │ │ └── Example1
│ │ │ │ ├── Example-1.html
│ │ │ │ └── example-main-1.js
│ │ ├── Form
│ │ │ ├── Example1
│ │ │ │ ├── Example-1.html
│ │ │ │ └── example-main-1.js
│ │ │ ├── Example2
│ │ │ │ ├── Example-2.html
│ │ │ │ └── example-main-2.js
│ │ │ └── Example3
│ │ │ │ ├── Example-3.html
│ │ │ │ └── example-main-3.js
│ │ └── README.md
│ │ └── README.md
├── css
│ ├── bootstrap-responsive.min.css
│ └── bootstrap.min.css
├── img
│ ├── glyphicons-halflings-white.png
│ ├── glyphicons-halflings.png
│ └── placeholder.png
└── js
│ ├── backbone-min.js
│ ├── backbone-min.js-1.0
│ ├── bbplugins
│ ├── deep-model
│ │ └── deep-model.min.js
│ ├── forms
│ │ ├── backbone-forms.js
│ │ ├── backbone-forms.min.js
│ │ └── editors
│ │ │ ├── list.js
│ │ │ └── list.min.js
│ └── model-binder
│ │ ├── collectionBinder.min.js
│ │ └── modelBinder.min.js
│ ├── bootstrap.min.js
│ ├── google-map-api.json
│ ├── jquery-min.js
│ ├── json2.js
│ └── underscore-min.js
└── slides
├── Training-Session-1.ppsx
└── Training-Session-8.ppsx
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2018 Ashwin Hegde
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Structuring your web apps with Backbone.js
2 |
3 | This training kit has been developed for those who
4 | * Already have the basic knowledge of JavaScript & jQuery;
5 | * Who wants to write JavaScript in a structured/pattern way;
6 |
7 | This training kit will teach you the basics of Backbone.js and introduction to advanced part;
8 |
9 | ## Prerequisites arranged as per the priority
10 | * Basic understanding of web development concepts like functional programming, templating etc.
11 | * JavaScript, jQuery, Underscore.
12 |
13 | > If you are already know & understand Backbone.js and want to learn Backbone.js Marionette framework then its strongly recommended to skip this training kit and jump to understand the basic to advanced of Backbone.js Marionette from the repository "[Learning Backbone Marionette](https://github.com/hegdeashwin/learning-backbone-marionette)"
14 |
15 | ## Training kit includes below session
16 | * Ch 1 : Getting Started.
17 | * Ch 2 : Backbone Model.
18 | * Ch 3 : Backbone View, Events & Templates.
19 | * Ch 4 : Backbone Collection.
20 | * Ch 5 : Backbone Router.
21 | * Ch 6 : Application DEMO & Plugin examples.
22 |
23 | * For more information on Backbone's coding standards, plugins etc. Please visit [Backbone's training kit Github Wiki documentation](https://github.com/hegdeashwin/Backbone/wiki)
24 |
25 | ## How to use training kit examples
26 |
27 | Clone the repository and start running the examples in your browser and browse the codes with ready commits or
28 | you can also experiment with the code online which is powered by JSFiddle.
29 |
30 | [Download this repository](https://github.com/hegdeashwin/Backbone/archive/master.zip) OR [Experiment online](http://jsfiddle.net/hegdeashwin/TKkMt/show/)
31 |
32 | ## Recommended text editor
33 |
34 | You can used any text editor which ever you are comfortable with on any operating systems.
35 | But when it comes to JavaScript based project I personally recommend the following editors
36 | as per the priority.
37 |
38 | * Sublime Text 2 or above
39 | * Atom
40 | * Bracket
41 | * Notepad++
42 |
43 | ## Development tools
44 |
45 | * Backbone Eye, [Home Site](//dhruvaray.github.io/spa-eye/) | [Git Repository](https://github.com/dhruvaray/spa-eye)
46 | A Mozilla FIrefox - Firebug extension for debugging Backbone.js applications. A way to understand Backbone application behavior without wading through JavaScript code.
47 |
48 | * Backbone Debugger, [Git Repository](//github.com/Maluen/Backbone-Debugger)
49 | A Google Chrome - Developer Tools extension for debugging Backbone.js applications. Displays in real-time all the application views, models, collections and routers, with detailed information such as handled jQuery events, model attributes, collection models, sync status, events triggered and more.
50 |
51 | * Nebula, [Git Repository](//github.com/hegdeashwin/Nebula)
52 | An open source application skeleton for a typical Backbone web apps. You can use it to quickly bootstrap your Backbone web application projects.
53 |
54 | * Nebula-cli, [Git Repository](//github.com/hegdeashwin/Nebula-cli)
55 | Nebula-cli is a command line generator for Nebula. This tool will help to generate a walking application skeleton for a typical Backbone web apps. You can use it to quickly bootstrap your Backbone web application projects.
56 |
57 | * Boneloop, [Git Repository](//github.com/hegdeashwin/Boneloop)
58 | An open source enterprise edition of Nebula based upon Backbone + Marionette - A scalable and composite application architecture for Backbone.js. It provides a client-[server]-side stack for building enterprise grade HTML5/Marionette applications. It could be used with any server side like Node.js, Ruby, PHP, JEE, Spring etc. By default it's server side environment comes with Node.js - Loopback (StrongLoop) stack.
59 |
60 | * Bonegear, [Git Repository](https://github.com/hegdeashwin/Bonegear)
61 | Bonegear is an open source UI components for your Backbone.js projects.
62 |
63 | ## Contributors
64 |
65 | Developed & maintained by author: Ashwin Hegde & [Contributors](//github.com/hegdeashwin/Backbone/graphs/contributors)
66 |
67 | We really appreciate all kind of feedback and contributions. Thank you for using and supporting this project.
68 |
69 | To request a feature or you find any typo errors, enhancements or questions; please feel free to send a pull-request on "develop" branch or post it on following link, or vote for the ones that are already registered.
70 |
71 | [https://github.com/hegdeashwin/Backbone/issues](https://github.com/hegdeashwin/Backbone/issues)
72 |
73 | Visit the following link to know about:
74 |
75 | * [The annotated source code of Backbone.js.](http://backbonejs.org/docs/backbone.html)
76 | * [Online Test Suite](http://backbonejs.org/test/)
77 | * [The Real world Projects](http://backbonejs.org/#examples)
78 |
79 | ## License
80 |
81 | The MIT License (MIT)
82 |
83 | Copyright (c) 2016-2018 Ashwin Hegde
84 |
--------------------------------------------------------------------------------
/codes/Ch1_Introduction/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Introduction
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Introduction to Backbone.js
10 | How to run this example.
11 |
12 | Open Example-1.html in browser.
13 | Press F12, go to console tab.
14 | Goto console and type "Backbone" & understand the Backbone object
15 |
16 |
17 |
24 |
25 |
26 |
34 |
35 |
36 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone Model
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Understanding Backbone Model
10 | How to run this example.
11 |
12 | Open Example-1.html in browser.
13 | Press F12, go to console tab.
14 |
15 |
16 |
23 |
24 |
25 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Create Backbone Model
5 | * 2. Create instance of Backbone Model
6 | * 3. Setting & getting default attributes
7 | * 4. Initialize a constructor
8 | * 5. Setting & getting attributes
9 | * 6. Get the list of all attributes
10 | */
11 |
12 | /**
13 | * Creating a new model called MasterModel by extending Backbone.Model class
14 | * Syntax: Backbone.Model.extend(properties, [classProperties])
15 | */
16 | var MasterModel = Backbone.Model.extend({
17 | /**
18 | * `initialize` is a constructor function which gets called automatically at
19 | * the time of instance creation
20 | */
21 | initialize: function() {
22 | console.log("Your model have been initialize.");
23 | },
24 |
25 | /**
26 | * These are various attributes that will be set by default when the model gets created.
27 | */
28 | defaults: {
29 | companyName: 'Cybage Software Private Limited',
30 | country: 'India',
31 | city: 'Pune'
32 | }
33 | });
34 |
35 | /**
36 | * Creating an instance of MasterModel.
37 | */
38 | var masterModel = new MasterModel();
39 |
40 | /**
41 | * Getting information about Model instance.
42 | */
43 | console.log("Model object: ", masterModel);
44 |
45 | /**
46 | * Getting the default values from attributes using `get` method.
47 | */
48 | console.log("Company Name: " + masterModel.get('companyName'));
49 | console.log("Country: " + masterModel.get('country'));
50 | console.log("City: " + masterModel.get('city'));
51 |
52 | /**
53 | * Setting a single attribute in the model using `set` method.
54 | */
55 | masterModel.set('totalEmployees', '4000');
56 |
57 | /**
58 | * Getting the newly set attribute value using `get` method.
59 | */
60 | console.log("Total Employees: ", masterModel.get('totalEmployees'));
61 |
62 | /**
63 | * Setting multiple attributes in the model using `set` method.
64 | */
65 | masterModel.set({
66 | 'CMMiLevel': 5,
67 | 'totalDevCenters': 4
68 | });
69 |
70 | /**
71 | * Getting the newly set attributes values.
72 | */
73 | console.log("CMMiLevel Standard: ", masterModel.get('CMMiLevel'));
74 | console.log("Total Development Centers in India: ", masterModel.get('totalDevCenters'));
75 |
76 | /**
77 | * Getting information about object previous attributes.
78 | */
79 | console.log("Previous attributes: ", masterModel._previousAttributes);
80 |
81 | /**
82 | * Getting the list of all attributes toJSON
83 | */
84 | console.log("1st Way: ", masterModel.attributes);
85 | console.log("2nd Way: ", masterModel.toJSON());
86 |
87 | })();
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 2: Backbone Model
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Understanding Backbone Model
10 | How to run this example.
11 |
12 | Open Example-2.html in browser.
13 | Press F12, go to console tab.
14 |
15 |
16 |
23 |
24 |
25 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Unset attribute
5 | * 2. Cleaning all attributes
6 | * 3. Setting & getting default attributes
7 | * 4. Initialize a constructor
8 | * 5. Setting & getting attributes
9 | * 6. Get the list of all attributes
10 | */
11 |
12 | /**
13 | * Creating a new model called MasterModel by extending Backbone.Model class
14 | * Syntax: Backbone.Model.extend(properties, [classProperties])
15 | */
16 | var MasterModel = Backbone.Model.extend({});
17 |
18 | /**
19 | * Creating an instance of MasterModel.
20 | */
21 | var masterModel = new MasterModel();
22 |
23 | /**
24 | * Setting the bunch of attributes in the model.
25 | */
26 | masterModel.set({
27 | 'firstName': 'Ashwin',
28 | 'lastName': 'Hegde',
29 | 'designation': 'Web Developer'
30 | });
31 |
32 | /**
33 | * Getting the newly set attributes values.
34 | */
35 | console.log("Getting attributes: ");
36 | console.log(masterModel.toJSON());
37 |
38 | /**
39 | * Check, if the attribute is already set or not
40 | */
41 | if (masterModel.has('city')) {
42 | console.log("City attribute is already set");
43 | } else {
44 | console.log("City attribute is not set");
45 | }
46 |
47 | if (masterModel.has('lastName')) {
48 | console.log("Last name attribute is already set");
49 | } else {
50 | console.log("Last name attribute is not set");
51 | }
52 |
53 | /**
54 | * Unset the `designation` attribute and then try get the data.
55 | */
56 | masterModel.unset('designation');
57 |
58 | /**
59 | * Getting the attribute.
60 | */
61 | console.log("Getting the attributes after unset");
62 | console.log(masterModel.toJSON());
63 |
64 | /**
65 | * Clear will remove all the attributes and then try get the data.
66 | */
67 | masterModel.clear();
68 | /**
69 | * Getting the attribute.
70 | */
71 | console.log("Getting the attributes after clear");
72 | console.log(masterModel.toJSON());
73 |
74 | /**
75 | * Get model client id.
76 | */
77 | console.log("Model Client id: " + masterModel.cid);
78 |
79 | /**
80 | * Creating a model & setting user id to it.
81 | */
82 | var childModel = Backbone.Model.extend({
83 | idAttribute: "_id"
84 | });
85 |
86 | var childmodel = new childModel({
87 | _id: 1,
88 | firstName: 'Vinayak',
89 | lastName: 'Patil'
90 | });
91 | console.log(childmodel.toJSON());
92 |
93 | console.log("Client id still remain: ", childmodel);
94 |
95 | console.log("Getting user id: " + childmodel.id);
96 | })();
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 3: Backbone Model
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Understanding Backbone Model
10 | How to run this example.
11 |
12 | Open Example-3.html in browser.
13 | Press F12, go to console tab.
14 |
15 |
16 |
23 |
24 |
25 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Access JSON data through URL method
5 | * 2. Parse data
6 | * 3. REST operations on JSON data
7 | */
8 |
9 | /**
10 | * Creating a new model called MasterModel by extending Backbone.Model class
11 | * Syntax: Backbone.Model.extend(properties, [classProperties])
12 | */
13 | var MasterModel = Backbone.Model.extend({
14 |
15 | /**
16 | * Whenever 'fetch | save | destroy' is called URL function is needed else it will through error.
17 | */
18 | url: function() {
19 | return "../../../js/google-map-api.json";
20 | },
21 |
22 | /**
23 | * This function gets called automatically if its present in the model; this function helps to parse the
24 | * data and return it to model instance; it takes response as argument and it needs to be return else
25 | * it will return undefined
26 | */
27 | parse: function(response) {
28 | console.log("Parse response: ");
29 | console.log(response);
30 |
31 | return response;
32 | }
33 | });
34 |
35 | var masterModel = new MasterModel();
36 | console.log(masterModel);
37 |
38 | /**
39 | * Getting data from Model fetch method.
40 | */
41 | masterModel.fetch({
42 | success: function() {
43 | console.log("Data coming from fetch success: ");
44 | console.log(masterModel.toJSON());
45 | },
46 | error: function() {
47 | console.log("Some error triggered while accessing data service api.");
48 | }
49 | });
50 |
51 | masterModel.set({
52 | firstName: 'Ashwin',
53 | lastName: 'Hegde'
54 | });
55 |
56 | /**
57 | * Save data to your Model; execute REST POST, PUT operations
58 | * Below is only to show 'save' syntax;
59 | */
60 | // masterModel.save(masterModel.toJSON(), {
61 | // success: function() {
62 | // console.log("Data coming from fetch success: ");
63 | // console.log(masterModel.toJSON());
64 | // },
65 | // error: function() {
66 | // console.log("Some error triggered while accessing Google service api.");
67 | // }
68 | // });
69 |
70 | /**
71 | * Delete data from your Model; execute REST DELETE operation
72 | * Below is only to show 'destroy' syntax;
73 | */
74 | // masterModel.destroy(masterModel.toJSON(), {
75 | // success: function() {
76 | // console.log("Data coming from fetch success: ");
77 | // console.log(masterModel.toJSON());
78 | // },
79 | // error: function() {
80 | // console.log("Some error triggered while accessing Google service api.");
81 | // }
82 | // });
83 |
84 | })();
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example4/Example-4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 4: Backbone Model
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Understanding Backbone Model
10 | How to run this example.
11 |
12 | Open Example-4.html in browser.
13 | Press F12, go to console tab.
14 |
15 |
16 |
23 |
24 |
25 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example4/example-main-4.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Attributes validation
5 | */
6 |
7 | /**
8 | * Creating a new model called MasterModel by extending Backbone.Model class
9 | * Syntax: Backbone.Model.extend(properties, [classProperties])
10 | */
11 | var MasterModel = Backbone.Model.extend({
12 | /**
13 | * model's validate method for attributes validation.
14 | */
15 | validate: function(attrs, options) {
16 | if (attrs.age < 18) {
17 | this.trigger('error', "Your age must be more then 18 years.");
18 | return true;
19 | }
20 | }
21 | });
22 |
23 | var masterModel = new MasterModel({
24 | name: 'Ashwin Hegde'
25 | });
26 |
27 | masterModel.on('error', function(error) {
28 | console.log("Error: ", error);
29 | });
30 |
31 | /**
32 | * This will not set age in the model, due to not passing validation '< 18'
33 | */
34 | masterModel.set({
35 | age: 15
36 | }, {
37 | validate: true
38 | });
39 |
40 |
41 | /**
42 | * This will set age in the model, due to passing validation '< 18';
43 | * Uncomment below to see the model changes
44 | */
45 | //
46 | // masterModel.set({
47 | // age: 20
48 | // }, {
49 | // validate: true
50 | // });
51 |
52 |
53 | /**
54 | * Let verify if age got set or not
55 | */
56 | console.log('Master Model: ', masterModel.toJSON());
57 |
58 | })();
59 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example5/Example-5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 5: Backbone Model
6 |
7 |
8 | Structuring your web apps via Backbone.js
9 | Ch 1: Understanding Backbone Model
10 | How to run this example.
11 |
12 | Open Example-5.html in browser.
13 | Press F12, go to console tab.
14 |
15 |
16 |
23 |
24 |
25 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch2_Model/Examples/Example5/example-main-5.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Access 3rd parth service data through URL method
5 | * 2. Setting attributes to URL;
6 | * 3. Access attributes from within model
7 | */
8 |
9 | var MasterModel = Backbone.Model.extend({
10 |
11 | url: function() {
12 | var _apiUrl = 'http://jsonplaceholder.typicode.com/users';
13 |
14 | if (this.has('id')) {
15 | _apiUrl = 'http://jsonplaceholder.typicode.com/users/' + this.get('id');
16 | }
17 | return _apiUrl;
18 | }
19 | });
20 |
21 | var masterModel1 = new MasterModel();
22 |
23 | /**
24 | * Getting data from Model fetch method.
25 | */
26 | masterModel1.fetch({
27 | success: function() {
28 | console.log("Data coming from fetch success: ");
29 | console.log(masterModel1.toJSON());
30 | },
31 | error: function() {
32 | console.log("Some error triggered while accessing service api.");
33 | }
34 | });
35 |
36 | /**
37 | * Setting id attribute
38 | */
39 | var masterModel2 = new MasterModel({
40 | "id": 1
41 | });
42 |
43 | /**
44 | * Getting data from Model fetch method.
45 | */
46 | masterModel2.fetch({
47 | success: function() {
48 | console.log("Data coming from fetch success: ");
49 | console.log(masterModel2.toJSON());
50 | },
51 | error: function() {
52 | console.log("Some error triggered while accessing service api.");
53 | }
54 | });
55 |
56 | })()
--------------------------------------------------------------------------------
/codes/Ch2_Model/README.md:
--------------------------------------------------------------------------------
1 | # Ch2 - Understanding Backbone Model
2 |
3 | ## Example 1:
4 | * Create Backbone Model
5 | * Create instance of Backbone Model
6 | * Setting & getting default attributes
7 | * Initialize a constructor
8 | * Setting & getting attributes
9 | * Get the list of all attributes
10 |
11 | ## Example 2:
12 | * Unset attribute
13 | * Cleaning all attributes
14 | * Check if attributes is set or not
15 | * Getting & Setting Model id
16 |
17 | ## Example 3:
18 | * Access JSON data through URL method
19 | * Parse data
20 | * REST operations on JSON data
21 |
22 | ## Example 4:
23 | * Attributes validation
24 |
25 | ## Example 5:
26 | * Access 3rd parth service data through URL method
27 | * Setting attributes to URL;
28 | * Access attributes from within model
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_1_View/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone View
6 |
7 |
8 | Ch 3: Understanding Backbone View
9 | How to run this example?
10 |
11 | Open Example-1.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_1_View/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /**
4 | * The goal of this file is to provide the basic understanding of
5 | * 1. Create Backbone View
6 | * 2. Create instance of Backbone View
7 | * 3. Setting default el reference
8 | * 4. Setting classname, id and tagname
9 | * 5. Setting custom el reference
10 | */
11 |
12 | /**
13 | * Creating a new View called MasterView by extending Backbone.View class
14 | * Syntax: Backbone.View.extend(properties, [classProperties])
15 | */
16 | var MasterView = Backbone.View.extend({
17 | /**
18 | * `initialize` is a constructor function which gets called automatically at
19 | * the time of instance creation
20 | */
21 | initialize: function() {
22 | console.log("Your View have been initialize.");
23 | },
24 |
25 | /**
26 | * if `tagName` is not specified then its default to `div`;
27 | * This will set class name for the DOM element to which your view is refering to
28 | * You can also set multiple classes like 'container mainpage centerPanel ...'
29 | * This is optional property;
30 | */
31 | className: 'container',
32 |
33 | /**
34 | * This will set id for the DOM element to which your view is refering to
35 | * This is optional property;
36 | */
37 | id: 'master'
38 |
39 | });
40 |
41 | /**
42 | * Creating an instance of MasterView.
43 | */
44 | var masterView = new MasterView();
45 | console.log(masterView);
46 |
47 | /**
48 | * masterView.el will display
49 | */
50 | console.log(masterView.el);
51 |
52 | /**
53 | * Creating a new view called ChildView by extending Backbone.View class.
54 | */
55 | var ChildView = Backbone.View.extend({
56 |
57 | /**
58 | * tagName is specified as 'ul' will override the default
59 | */
60 | tagName: 'ul',
61 |
62 | className: 'row',
63 |
64 | id: 'child'
65 |
66 | });
67 |
68 | /**
69 | * Creating an instance of ChildView.
70 | */
71 | var childView = new ChildView();
72 |
73 | /**
74 | * childView.el will display
75 | */
76 | console.log(childView.el);
77 |
78 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone Templating
6 |
7 |
8 | Ch 3: Understanding Backbone Templating
9 | How to run this example?
10 |
11 | Open Example-1.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
51 |
52 |
59 |
60 |
61 |
69 |
70 |
71 |
75 |
76 |
77 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Setting DOM reference using `el`
5 | * 2. Compiling Underscore template
6 | * 3. Injecting data to template
7 | * 4. Using this.$el to render template
8 | */
9 |
10 | /**
11 | * Creating a new view called MasterModel by extending Backbone.View class
12 | * Syntax: Backbone.View.extend(properties, [classProperties])
13 | */
14 | var MasterView = Backbone.View.extend({
15 | /**
16 | * `initialize` is a constructor function which gets called automatically at
17 | * the time of instance creation
18 | */
19 | initialize: function() {
20 | this.render();
21 | },
22 |
23 | /**
24 | * `el` is a DOM reference for the view
25 | */
26 | el: "#directionApi",
27 |
28 | /**
29 | * Using underscore _.template method to compile html template
30 | */
31 | template: _.template($("#routesTable").html()),
32 |
33 | /**
34 | * Render function can be used for data injection and rendering purpose;
35 | * Also passing data to template;
36 | */
37 | render: function() {
38 | this.$el.html(this.template({
39 | "ne_lat": "19.09192670",
40 | "ne_lng": "73.85839480",
41 | "sw_lat": "18.52064730",
42 | "sw_lng": "72.87766890"
43 | }));
44 | }
45 |
46 | });
47 |
48 | var masterView = new MasterView();
49 | console.log(masterView.el);
50 |
51 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 2: Backbone Templating
6 |
7 |
8 | Ch 3: Understanding Backbone Templating
9 | How to run this example?
10 |
11 | Open Example-2.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
39 |
40 |
47 |
48 |
49 |
57 |
58 |
59 |
63 |
64 |
65 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Using model for data
5 | * 2. Using model instance from within view constructor
6 | * 3. Parsing data in model
7 | * 4. Rendering underscore template
8 | */
9 |
10 | var MasterModel = Backbone.Model.extend({
11 |
12 | url: function() {
13 | return 'http://jsonplaceholder.typicode.com/users';
14 | },
15 |
16 | parse: function(response) {
17 | var minInfo = [];
18 |
19 | _.each(response, function(data) {
20 | minInfo.push({
21 | "name": data.name,
22 | "email": data.email,
23 | "website": data.website
24 | });
25 | });
26 |
27 | console.log('Parsed Data: ', minInfo);
28 |
29 | return minInfo;
30 | }
31 | });
32 |
33 | var MasterView = Backbone.View.extend({
34 |
35 | initialize: function() {
36 | this.model = new MasterModel();
37 | this.render();
38 | },
39 |
40 | el: "#directionApi",
41 |
42 | template: _.template($("#routesTable").html()),
43 |
44 | render: function() {
45 | var self = this;
46 |
47 | this.model.fetch({
48 | success: function() {
49 | console.log(self.model.toJSON());
50 |
51 | /**
52 | * Passing key:value data to template and template to DOM
53 | */
54 | self.$el.html(self.template({
55 | data: self.model.toJSON()
56 | }));
57 | },
58 | error: function() {
59 | console.log("Some error got triggered while accessing service api.");
60 | }
61 | });
62 |
63 | return this;
64 | }
65 |
66 | });
67 |
68 | var masterView = new MasterView();
69 | console.log(masterView.el);
70 |
71 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 3: Backbone Templating
6 |
7 |
8 | Ch 3: Understanding Backbone Templating
9 | How to run this example?
10 |
11 | Open Example-3.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
43 |
44 |
51 |
52 |
53 |
61 |
62 |
63 |
67 |
68 |
69 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_2_Templating/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Using model for data with id
5 | */
6 |
7 | var MasterModel = Backbone.Model.extend({
8 | url: function() {
9 | var _apiUrl = 'http://jsonplaceholder.typicode.com/users/1';
10 |
11 | if (this.has('id')) {
12 | _apiUrl = 'http://jsonplaceholder.typicode.com/users/' + this.get('id');
13 | }
14 | return _apiUrl;
15 | }
16 | });
17 |
18 | var MasterView = Backbone.View.extend({
19 |
20 | initialize: function() {
21 | this.model = new MasterModel({
22 | "id": 9
23 | });
24 | this.render();
25 | },
26 |
27 | el: "#directionApi",
28 |
29 | template: _.template($("#routesTable").html()),
30 |
31 | render: function() {
32 | var self = this;
33 |
34 | this.model.fetch({
35 | success: function() {
36 | self.$el.html(self.template(self.model.toJSON()));
37 | },
38 | error: function() {
39 | console.log("Some error got triggered while accessing service api.");
40 | }
41 | });
42 | }
43 |
44 | });
45 |
46 | var masterView = new MasterView();
47 | console.log(masterView.el);
48 |
49 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone Events
6 |
7 |
8 | Ch 3: Understanding Backbone Events
9 | How to run this example?
10 |
11 | Open Example-1.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
23 |
24 |
31 |
32 |
33 |
41 |
42 |
43 |
47 |
48 |
49 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Define events hash
5 | * 2. Define event scope for View using el DOM reference
6 | */
7 |
8 | var MasterView = Backbone.View.extend({
9 | /**
10 | * All views have a DOM element at all times (the el property),
11 | * whether they've already been inserted into the page or not.
12 | *
13 | * el also defines your view scope; You can not bind bind in events hash for DOM element out side this view
14 | */
15 | el: '.workspace',
16 |
17 | /**
18 | * Events hash.
19 | */
20 | events: {
21 | 'click input[type=submit]': 'submitForm',
22 | 'click input[type=button]': 'buttonForm'
23 | },
24 |
25 | /**
26 | * Custom function gets fired when specific event gets called.
27 | */
28 | submitForm: function() {
29 | console.log("Submit Button got clicked. Time to validate form data.");
30 | },
31 |
32 | /**
33 | * Won't able to access this function. The element is outside view scope
34 | */
35 | buttonForm: function() {
36 | console.log("Won't able to access this function. This is out of view scope.");
37 | }
38 |
39 | });
40 |
41 | var masterView = new MasterView();
42 |
43 | })();
44 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 2: Backbone Events
6 |
7 |
8 | Ch 3: Understanding Backbone Events
9 | How to run this example?
10 |
11 | Open Example-2.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
28 |
36 |
37 |
38 |
42 |
43 |
44 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Remove view from DOM.
5 | */
6 |
7 | var MasterView = Backbone.View.extend({
8 |
9 | el: '.workspace',
10 |
11 | events: {
12 | 'click input[type=submit]': 'removeView'
13 | },
14 |
15 | removeView: function() {
16 | console.log("This function will remove the current view from DOM.");
17 | this.remove();
18 | }
19 | });
20 |
21 | /**
22 | * Don't save your instance; Just create it
23 | */
24 | new MasterView();
25 |
26 | })();
27 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 3: Backbone Events
6 |
7 |
8 | Ch 3: Understanding Backbone Events
9 | How to run this example?
10 |
11 | Open Example-3.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
31 |
39 |
40 |
41 |
45 |
46 |
47 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Old way to Subscribe/Unsubscribe a custom event
5 | * 2. Old way to Subscribe a custom event onces
6 | * 3. Trigger a subscribed event
7 | */
8 |
9 | var MasterView = Backbone.View.extend({
10 | initialize: function() {
11 |
12 | /**
13 | * Subscribe `alarm` event forever till it is manually off
14 | */
15 | this.on('alarm', this.doSomething);
16 |
17 | /**
18 | * Subscribe `greeting` event once
19 | */
20 | this.once('greeting', this.doSomethingOnce);
21 | },
22 |
23 | doSomething: function(name) {
24 | console.log("Wake up, " + name);
25 | },
26 |
27 | doSomethingOnce: function(name) {
28 | console.log("Good Morning, " + name);
29 | },
30 |
31 | el: '.workspace',
32 |
33 | events: {
34 | 'click input[id=triggerOnAlarm]': 'triggerOnAlarm',
35 | 'click input[id=triggerOffAlarm]': 'triggerOffAlarm',
36 | 'click input[id=triggerOnce]': 'triggerOnce'
37 | },
38 |
39 | triggerOnAlarm: function() {
40 | /**
41 | * Trigger the event by specifing event name
42 | */
43 | this.trigger('alarm', 'Ashwin');
44 | },
45 |
46 | triggerOffAlarm: function() {
47 | /**
48 | * Unsubscribe the event
49 | */
50 | this.off('alarm');
51 | },
52 |
53 | triggerOnce: function() {
54 | this.trigger('greeting', 'Ashwin');
55 | }
56 |
57 | });
58 |
59 | new MasterView();
60 |
61 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example4/Example-4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 4: Backbone Events
6 |
7 |
8 | Ch 3: Understanding Backbone Events
9 | How to run this example?
10 |
11 | Open Example-4.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
31 |
39 |
40 |
41 |
45 |
46 |
47 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/Ch3_3_Events/Example4/example-main-4.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. New way to Subscribe/Unsubscribe a custom event
5 | * 2. New way to Subscribe a custom event onces
6 | * 3. Trigger a subscribed event
7 | */
8 |
9 | var MasterView = Backbone.View.extend({
10 | initialize: function() {
11 |
12 | this.listenTo(this, 'alarm', this.doSomething);
13 |
14 | this.listenToOnce(this, 'greeting', this.doSomethingOnce);
15 | },
16 |
17 | el: '.workspace',
18 |
19 | events: {
20 | 'click input[id=triggerOnAlarm]': 'triggerOnAlarm',
21 | 'click input[id=triggerOffAlarm]': 'triggerOffAlarm',
22 | 'click input[id=triggerOnce]': 'triggerOnce'
23 | },
24 |
25 | doSomething: function(name) {
26 | console.log("Wake up, " + name);
27 | },
28 |
29 | doSomethingOnce: function(name) {
30 | console.log("Good Morning, " + name);
31 | },
32 |
33 | triggerOnAlarm: function() {
34 | /**
35 | * Trigger the event by specifing event name
36 | */
37 | this.trigger('alarm', 'Ashwin');
38 | },
39 |
40 | triggerOffAlarm: function() {
41 | /**
42 | * Unsubscribe the event
43 | */
44 | this.stopListening(this, 'alarm');
45 | },
46 |
47 | triggerOnce: function() {
48 | this.trigger('greeting', 'Ashwin');
49 | }
50 |
51 | });
52 |
53 | new MasterView();
54 |
55 | })();
--------------------------------------------------------------------------------
/codes/Ch3_View_Events_Templates/README.md:
--------------------------------------------------------------------------------
1 | # Ch3 - Understanding Backbone View, Events, Templating
2 |
3 | ## View
4 |
5 | ### Example 1:
6 | * Create Backbone View
7 | * Create instance of Backbone View
8 | * Setting default `el` reference
9 | * Setting classname, id and tagname
10 | * Setting custom el reference
11 |
12 | ## Templating
13 |
14 | ### Example 1:
15 | * Setting DOM reference using `el`
16 | * Compiling Underscore template
17 | * Injecting data to template
18 | * Using this.$el to render template
19 |
20 | ### Example 2:
21 | * Using model for data
22 | * Using model instance from within view constructor
23 | * Parsing data in model
24 | * Rendering underscore template
25 |
26 | ### Example 3:
27 | * Using model for data with id
28 |
29 | ## Events
30 |
31 | ### Example 1:
32 | * Define events hash
33 | * Define event scope for View using el DOM reference
34 |
35 | ### Example 2:
36 | * Remove view from DOM.
37 |
38 | ### Example 3:
39 | * Subscribe/Unsubscribe a custom event
40 | * Subscribe a custom event onces
41 | * Trigger a subscribed event
42 |
43 | ### Example 4:
44 | * New way to Subscribe/Unsubscribe a custom event
45 | * New way to Subscribe a custom event onces
46 | * Trigger a subscribed event
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone Collection
6 |
7 |
8 | Ch 4: Understanding Backbone Collection
9 | How to run this example?
10 |
11 | Open Example-1.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
22 |
23 |
24 |
32 |
33 |
34 |
38 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Create a Collection
5 | * 2. Passing Model to Collection
6 | * 3. Setting build-in Collection events
7 | * 4. Add/Remove Model from collection at the end
8 | * 5. Add/Remove Model from collection at the start
9 | * 6. Get the length of collection
10 | */
11 |
12 | var MasterModel = Backbone.Model.extend({
13 | /**
14 | * `initialize` is a constructor function which gets called automatically at
15 | * the time of instance creation
16 | */
17 | initialize: function() {
18 | console.log("Your model have been initialize");
19 | }
20 | });
21 |
22 | var MasterCollection = Backbone.Collection.extend({
23 | initialize: function() {
24 | console.log("Your collection have been initialize.");
25 |
26 | /**
27 | * Subscribe collection events
28 | */
29 | this.listenTo(this, 'add', this.onModelAdded);
30 | this.listenTo(this, 'remove', this.onModelRemoved);
31 | },
32 |
33 | /**
34 | * Used to specify the model class that the collection contains.
35 | */
36 | model: MasterModel,
37 |
38 | onModelAdded: function() {
39 | console.log("Add model event got fired");
40 | },
41 |
42 | onModelRemoved: function() {
43 | console.log("Remove model event got fired");
44 | }
45 | });
46 |
47 | var masterCollection = new MasterCollection();
48 |
49 | /**
50 | * Add a model (or an array of models) to the collection.
51 | * Firing an "add" event.
52 | */
53 | masterCollection.add(new MasterModel({
54 | name: 'Ashwin Hegde'
55 | }));
56 | masterCollection.add(new MasterModel({
57 | name: 'Vinayak Patil'
58 | }));
59 | masterCollection.add(new MasterModel({
60 | name: 'Pavan Solanki'
61 | }));
62 |
63 | /**
64 | * Display the data currently added in the collection.
65 | */
66 | console.log("Data in Collection :: Add ")
67 | console.log(masterCollection.toJSON());
68 |
69 | /**
70 | * Remove a model (or an array of models) from the collection. Fires a "remove" event,
71 | *
72 | * `at` is used to get a model from a collection, specified by index.
73 | * Note: index starts from 0
74 | */
75 | masterCollection.remove(masterCollection.at(1));
76 |
77 | /**
78 | * Display the data after removing model from the collection.
79 | */
80 | console.log("Remove data from Collection :: Remove ")
81 | console.log(masterCollection.toJSON());
82 |
83 | /**
84 | * Collection maintains a length property, counting the number of models it contains.
85 | */
86 | console.log("Collection length: " + masterCollection.length);
87 |
88 | /**
89 | * Add a model at the end of a collection.
90 | */
91 | masterCollection.push(new MasterModel({
92 | name: 'Kumar Kundan'
93 | }));
94 |
95 | /**
96 | * Display the data currently added in the collection.
97 | */
98 | console.log("Data in Collection :: Push");
99 | console.log(masterCollection.toJSON());
100 |
101 | /**
102 | * Remove and return the last model from a collection
103 | */
104 | masterCollection.pop();
105 |
106 | /**
107 | * Display the data after removing last model from the collection.
108 | */
109 | console.log("Data in Collection :: POP");
110 | console.log(masterCollection.toJSON());
111 |
112 | /**
113 | * Add a model at the beginning of a collection.
114 | */
115 | masterCollection.unshift(new MasterModel({
116 | name: 'Ajay Sajwan'
117 | }));
118 |
119 | /**
120 | * Display the data currently added in the collection.
121 | */
122 | console.log("Data in Collection :: unshift");
123 | console.log(masterCollection.toJSON());
124 |
125 | /**
126 | * Remove and return the first model from a collection.
127 | */
128 | masterCollection.shift();
129 |
130 | /**
131 | * Display the data after removing first model from the collection.
132 | */
133 | console.log("Data in Collection :: Shift");
134 | console.log(masterCollection.toJSON());
135 |
136 | })();
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 2: Backbone Collection
6 |
7 |
8 | Ch 4: Understanding Backbone Collection
9 | How to run this example?
10 |
11 | Open Example-2.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
22 |
23 |
24 |
32 |
33 |
34 |
38 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Using pluck
5 | * 2. Using where
6 | */
7 |
8 | var MasterModel = Backbone.Model.extend({});
9 |
10 | var masterCollection = new Backbone.Collection([
11 | {name: "Ashwin Hegde", job: "Software Engineer"},
12 | {name: "Kumar Kundan", job: "Engineering Manager"},
13 | {name: "Saju Sasidharan", job: "Team Lead"}
14 | ]);
15 |
16 | /**
17 | * Pluck an attribute from each model in the collection.
18 | */
19 | var names = masterCollection.pluck("name");
20 | /**
21 | * Data in Object format
22 | */
23 | console.log("Data in Object format :: Pluck");
24 | console.log(names);
25 |
26 | /**
27 | * Data in string format
28 | */
29 | console.log("Data in String format :: Pluck")
30 | console.log(JSON.stringify(names));
31 |
32 | /**
33 | * Return an array of all the models in a collection that match the passed attributes.
34 | * Useful for simple cases of filter.
35 | */
36 | console.log(masterCollection.where({job: "Software Engineer"}));
37 | console.log(masterCollection.where({job: "Engineering Manager"}));
38 | console.log(masterCollection.where({job: "Team Lead"}));
39 |
40 | })();
41 |
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 3: Backbone Collection
6 |
7 |
8 | Ch 4: Understanding Backbone Collection
9 | How to run this example?
10 |
11 | Open Example-3.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
22 |
23 |
24 |
32 |
33 |
34 |
38 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/codes/Ch4_Collection/Examples/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Sorting data & respected events
5 | */
6 |
7 | var MasterModel = Backbone.Model.extend({});
8 |
9 | var MasterCollection = Backbone.Collection.extend({
10 | initialize: function() {
11 | console.log("Your collection have been initialize.");
12 | },
13 |
14 | model: MasterModel,
15 |
16 | comparator: function(sortby) {
17 | return (this._order_by === 'offers') ? sortby.get('offers') : sortby.id;
18 | },
19 |
20 | order_by_offers: function() {
21 | this._order_by = 'offers';
22 | this.sort();
23 | },
24 |
25 | order_by_default: function() {
26 | this._order_by = 'id';
27 | this.sort();
28 | },
29 |
30 | _order_by: 'id'
31 |
32 | });
33 |
34 | var masterCollection = new MasterCollection();
35 | console.log(masterCollection);
36 |
37 | /**
38 | * This function will only display id & Offers in different sorted order.
39 | */
40 | function dump(masterCollection) {
41 | masterCollection.each(function(object) {
42 | console.log("id:" + object.id + ' ' + "Offers:" + object.get('offers'));
43 | });
44 | }
45 |
46 | masterCollection.add([{
47 | id: 1,
48 | offers: 6
49 | }, {
50 | id: 2,
51 | offers: 11
52 | }, {
53 | id: 3,
54 | offers: 1
55 | }]);
56 |
57 | /*
58 | Passing object to dump file
59 | */
60 | console.log("No Sorting: ");
61 | dump(masterCollection);
62 |
63 | console.log("\nSort by Offers: ");
64 | masterCollection.order_by_offers();
65 | dump(masterCollection);
66 |
67 | console.log("\nSort by id (Default): ");
68 | masterCollection.order_by_default();
69 | dump(masterCollection);
70 |
71 | })();
--------------------------------------------------------------------------------
/codes/Ch4_Collection/README.md:
--------------------------------------------------------------------------------
1 | # Ch3 - Understanding Backbone Collection
2 |
3 | ## Example 1:
4 | * Create a Collection
5 | * Passing Model to Collection
6 | * Setting build-in Collection events
7 | * Add/Remove Model from collection at the end
8 | * Add/Remove Model from collection at the start
9 | * Get the length of collection
10 |
11 | ## Example 2:
12 | * Using pluck
13 | * Using where
14 |
15 | ## Example 3:
16 | * Sorting data & respected events
--------------------------------------------------------------------------------
/codes/Ch5_Router/Examples/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Example 1: Backbone Router
6 |
7 |
8 | Ch 5: Understanding Backbone Router
9 | How to run this example?
10 |
11 | Open Example-1.html in browser.
12 | Press F12, go to console tab.
13 |
14 |
15 |
23 |
24 |
31 |
32 |
33 |
41 |
42 |
43 |
47 |
48 |
49 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/codes/Ch5_Router/Examples/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /**
3 | * The goal of this file is to provide the basic understanding of
4 | * 1. Create a Router
5 | * 2. Backbone history
6 | * 3. Routes hash
7 | * 4. Simple route
8 | * 5. Route parameters
9 | * 6. Getting current route
10 | */
11 |
12 | var MasterRouter = Backbone.Router.extend({
13 | /**
14 | * `initialize` is a constructor function which gets called automatically at
15 | * the time of instance creation
16 | */
17 | initialize: function() {
18 | console.log("Your router have been initialize");
19 |
20 | /**
21 | * During page load, after your application has finished creating all of its routers,
22 | * be sure to call Backbone.history.start(), or
23 | * Backbone.history.start({pushState: true}) to route the initial URL.
24 | */
25 | Backbone.history.start()
26 |
27 | /**
28 | * Manually create a route for the router,
29 | * The route argument may be a routing string or regular expression.
30 | */
31 | // Matches #page/8, passing "8"
32 | this.route("page/:number", function(number) {
33 | console.log("Route Callback: Page/{number}");
34 | console.log("Get @param{number}: " + number);
35 | });
36 |
37 | // Matches /117-a/b/c/open, passing /117-a/b/c to open function.
38 | this.route(/^(.*?)\/open$/, "open");
39 |
40 | },
41 |
42 | /**
43 | * The routes hash maps URLs with parameters to functions on your router
44 | * (or just direct function definitions, if you prefer).
45 | */
46 | routes: {
47 | "": "home", // #help
48 | "about": "about", // #about
49 | "search/:query/p:page": "search", // #search/book/p7
50 | "contact": function() {
51 | console.log("Route Callback: Contact Us");
52 | this.getCurrentRoutes();
53 | },
54 | "help": "help"
55 | },
56 |
57 | home: function() {
58 | console.log("Route Callback: Home");
59 | this.getCurrentRoutes();
60 | },
61 |
62 | about: function() {
63 | console.log("Route Callback: About Us");
64 | this.getCurrentRoutes();
65 | },
66 |
67 | search: function(query, page) {
68 | console.log("Route Callback: Search");
69 | console.log(" => Search Query: " + query);
70 | console.log(" => Page No: " + page);
71 | },
72 |
73 | open: function(id) {
74 | console.log("Route Callback: Open (Redirect to Help Callback)");
75 | console.log("Get @param {id}: " + id);
76 |
77 | /**
78 | * Whenever you reach a point in your application that you'd like to save as a URL,
79 | * call navigate in order to update the URL. If you wish to also call the route function,
80 | * set the trigger option to true.
81 | * To update the URL without creating an entry in the browser's history, set the replace option to true.
82 | */
83 | this.navigate("help", {
84 | trigger: true,
85 | replace: true
86 | });
87 | },
88 |
89 | help: function() {
90 | console.log("Route Callback: Help");
91 | this.getCurrentRoutes();
92 | },
93 |
94 | getCurrentRoutes: function() {
95 | console.log("Backbone History Fragment (Current Route): " + Backbone.history.fragment);
96 | }
97 | });
98 |
99 | new MasterRouter();
100 |
101 | })();
--------------------------------------------------------------------------------
/codes/Ch5_Router/README.md:
--------------------------------------------------------------------------------
1 | # Ch5 - Understanding Backbone Router
2 |
3 | ## Example 1:
4 | * Create a Router
5 | * Backbone history
6 | * Routes hash
7 | * Simple route
8 | * Route parameters
9 | * Getting current route
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Under Training Session 5: Application Example 1
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Application Example 1
20 |
21 |
22 |
Scope of the Application
23 |
24 | Perform read operation (CR UD, R = Read) on data.
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
62 |
63 |
64 |
65 |
72 |
73 |
74 |
82 |
83 |
84 |
91 |
92 |
93 |
97 |
98 |
99 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*
4 | The goal of this file is to provide the basic understanding
5 | 1. Understanding how to integrate Backbone's Collection, Model & View.
6 | 2. Understanding how to use Underkscore's micro-templating feature.
7 | 3. Perform read operation (CRUD, R = Read) on data.
8 | */
9 |
10 | /*
11 | This is JavaScript object holding some amount of data used for data-manipulation.
12 | */
13 | var people = [
14 | { name: "ABC", address: "Pune, India", tel: "0123456789", email: "abc@cybage.com", type: "family" },
15 | { name: "PQR", address: "Canada, USA", tel: "0123456987", email: "pqr@blackberry.com", type: "friend" },
16 | { name: "XYZ", address: "Mumbai, India", tel: "0123456584", email: "xyz@infosys.com", type: "family" },
17 | { name: "DEF", address: "New York, USA", tel: "0123465645", email: "def@wipro.com", type: "colleague" },
18 | { name: "GHI", address: "New York, USA", tel: "0123465645", email: "ghi@wipro.com", type: "family" }
19 | ];
20 |
21 | /*
22 | Creating a new model called Contact by extending Backbone.Model class.
23 | */
24 | var Contact = Backbone.Model.extend({
25 | /*
26 | These are various attributes that will be set by default when the model gets created.
27 | */
28 | defaults: {
29 | photo: "../../../img/placeholder.png",
30 | name: "",
31 | address: "",
32 | tel: "",
33 | email: "",
34 | type: ""
35 | }
36 | });
37 |
38 | /*
39 | Creating a new collection called Contacts by extending Backbone.Collection class.
40 | */
41 | var Contacts = Backbone.Collection.extend({
42 | /*
43 | Used to specify the model class that the collection contains.
44 | */
45 | model: Contact
46 | });
47 |
48 | /*
49 | Creating a new view called ContactView by extending Backbone.View class.
50 | */
51 | var ContactView = Backbone.View.extend({
52 | /*
53 | tagName & className property will create following HTML markup.
54 |
55 | */
56 |
57 | className: "contact-container",
58 |
59 | template: _.template($("#contactTemplate").html()),
60 |
61 | render: function () {
62 | console.log("Model data 1 by 1: ");
63 | console.log(this.model.toJSON());
64 | /*
65 | Passing the model data to template and then to this.$el.html which has article tag.
66 | Thus, the updated template with all the data rendered gets appended to article tag.
67 | */
68 | this.$el.html(this.template(this.model.toJSON()));
69 | return this;
70 | }
71 |
72 | });
73 |
74 | /*
75 | Creating a new view called DirectoryView by extending Backbone.View class.
76 | */
77 | var ContactsView = Backbone.View.extend({
78 |
79 | el: $("#contacts"),
80 |
81 | /*
82 | This initialize function will get called when the view is first created.
83 | */
84 | initialize: function () {
85 | /*
86 | Creating an object from Contacts which calls initialize function.
87 | */
88 | this.collection = new Contacts(people);
89 |
90 | this.render();
91 |
92 | this.collection.on("reset", this.render, this);
93 | this.collection.on("add", this.renderContact, this);
94 | },
95 |
96 | render: function () {
97 | _.each(this.collection.models, function (item) {
98 | this.renderContact(item);
99 | }, this);
100 | },
101 |
102 | renderContact: function (item) {
103 | /*
104 | Creating an object from ContactView which calls initialize function.
105 |
106 | Passing the model to ContactView.
107 | */
108 | var contactView = new ContactView({
109 | model: item
110 | });
111 |
112 | /*
113 | Calling the render function and getting the updated el content and
114 | append it to this.$el which content div#contacts.
115 | */
116 | this.$el.append(contactView.render().el);
117 | }
118 |
119 | });
120 |
121 | /*
122 | Creating an object from DirectoryView which calls initialize function.
123 | */
124 | var contacts = new ContactsView();
125 |
126 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Under Training Session 5: Application Example 2
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Application Example 2
20 |
21 |
22 |
Scope of Application
23 |
24 | Perform Create operation (C RUD, C = Create) on data
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
43 |
72 |
73 |
74 |
75 |
76 |
83 |
84 |
85 |
93 |
94 |
95 |
102 |
103 |
104 |
108 |
109 |
110 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*
4 | The goal of this file is to provide the basic understanding
5 | 1. Perform Create operation (CRUD, C = Create) on data.
6 | */
7 |
8 | /*
9 | This is JavaScript object holding some amount of data used for data-manipulation.
10 | */
11 | var people = [
12 | { name: "ABC", address: "Pune, India", tel: "0123456789", email: "abc@cybage.com", type: "family" },
13 | { name: "PQR", address: "Canada, USA", tel: "0123456987", email: "pqr@blackberry.com", type: "friend" },
14 | { name: "XYZ", address: "Mumbai, India", tel: "0123456584", email: "xyz@infosys.com", type: "family" },
15 | { name: "DEF", address: "New York, USA", tel: "0123465645", email: "def@wipro.com", type: "colleague" },
16 | { name: "GHI", address: "New York, USA", tel: "0123465645", email: "ghi@wipro.com", type: "family" }
17 | ];
18 |
19 | /*
20 | Creating a new model called Contact by extending Backbone.Model class.
21 | */
22 | var Contact = Backbone.Model.extend({
23 | /*
24 | This initialize function will get called when the model is first created.
25 | */
26 | initialize: function() {
27 | console.log("Contact model got initialized");
28 | },
29 |
30 | /*
31 | These are various attributes that will be set by default when the model gets created.
32 | */
33 | defaults: {
34 | photo: "../../../img/placeholder.png",
35 | name: "",
36 | address: "",
37 | tel: "",
38 | email: "",
39 | type: ""
40 | }
41 | });
42 |
43 | /*
44 | Creating a new collection called Contacts by extending Backbone.Collection class.
45 | */
46 | var Contacts = Backbone.Collection.extend({
47 | /*
48 | This initialize function will get called when the collection is first created.
49 | */
50 | initialize: function() {
51 | console.log("Contacts collection got initialized");
52 | },
53 | /*
54 | Used to specify the model class that the collection contains.
55 | */
56 | model: Contact
57 | });
58 |
59 | /*
60 | Creating a new view called ContactView by extending Backbone.View class.
61 | */
62 | var ContactView = Backbone.View.extend({
63 | /*
64 | This initialize function will get called when the view is first created.
65 | */
66 | initialize: function() {
67 | console.log("ContactView view got initialized");
68 | },
69 |
70 | /*
71 | tagName & className property will create following HTML markup.
72 |
73 | */
74 | tagName: "article",
75 | className: "contact-container",
76 |
77 | template: _.template($("#contactTemplate").html()),
78 |
79 | render: function () {
80 | /*
81 | Passing the model data to template and then to this.$el.html which has article tag.
82 | Thus, the updated template with all the data rendered gets appended to article tag.
83 | */
84 | this.$el.html(this.template(this.model.toJSON()));
85 | return this;
86 | }
87 |
88 | });
89 |
90 | /*
91 | Creating a new view called DirectoryView by extending Backbone.View class.
92 | */
93 | var ContactsView = Backbone.View.extend({
94 |
95 | el: $("#contacts"),
96 |
97 | /*
98 | This initialize function will get called when the view is first created.
99 | */
100 | initialize: function () {
101 | /*
102 | Creating an object from Contacts which calls initialize function.
103 | */
104 | this.collection = new Contacts(people);
105 |
106 | this.render();
107 |
108 | /*
109 | This event gets fired when a model is added.
110 | */
111 | this.collection.on("add", this.renderContact, this);
112 | },
113 |
114 | /*
115 | Event hash will handle all the event listener.
116 | */
117 | events: {
118 | "click #add": "addContact"
119 | },
120 |
121 | /*
122 | This method gets fired when add button is clicked.
123 | */
124 | addContact: function (e) {
125 | e.preventDefault();
126 |
127 | var formData = {};
128 | $("#addContact").children("input").each(function (i, el) {
129 | if ($(el).val() !== "") {
130 | formData[el.id] = $(el).val();
131 | }
132 | });
133 |
134 | /*
135 | Used to push form data object to people object.
136 | */
137 | people.push(formData);
138 |
139 | /*
140 | This will fire add event.
141 | */
142 | this.collection.add(new Contact(formData));
143 |
144 | },
145 |
146 | render: function () {
147 | _.each(this.collection.models, function (item) {
148 | this.renderContact(item);
149 | }, this);
150 | },
151 |
152 | renderContact: function (item) {
153 | /*
154 | Creating an object from ContactView which calls initialize function.
155 |
156 | Passing the model to ContactView.
157 | */
158 | var contactView = new ContactView({
159 | model: item
160 | });
161 |
162 | /*
163 | Calling the render function and getting the updated el content and
164 | append it to this.$el which content div#contacts.
165 | */
166 | this.$el.append(contactView.render().el);
167 | }
168 |
169 | });
170 |
171 | /*
172 | Creating an object from DirectoryView which calls initialize function.
173 | */
174 | var contacts = new ContactsView();
175 |
176 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Under Training Session 5: Application Example 3
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Application Example 3
20 |
21 |
22 |
Scope of Application
23 |
24 | Perform Delete operation (CRUD , D = Delete) on data
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
67 |
68 |
69 |
70 |
77 |
78 |
79 |
87 |
88 |
89 |
96 |
97 |
98 |
102 |
103 |
104 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*
4 | The goal of this file is to provide the basic understanding
5 | 1. Perform Delete operation (CRUD, D = Delete) on data.
6 | */
7 |
8 | /*
9 | This is JavaScript object holding some amount of data used for data-manipulation.
10 | */
11 | var people = [
12 | { name: "ABC", address: "Pune, India", tel: "0123456789", email: "abc@cybage.com", type: "family" },
13 | { name: "PQR", address: "Canada, USA", tel: "0123456987", email: "pqr@blackberry.com", type: "friend" },
14 | { name: "XYZ", address: "Mumbai, India", tel: "0123456584", email: "xyz@infosys.com", type: "family" },
15 | { name: "DEF", address: "New York, USA", tel: "0123465645", email: "def@wipro.com", type: "colleague" },
16 | { name: "GHI", address: "New York, USA", tel: "0123465645", email: "ghi@wipro.com", type: "family" }
17 | ];
18 |
19 | /*
20 | Creating a new model called Contact by extending Backbone.Model class.
21 | */
22 | var Contact = Backbone.Model.extend({
23 | /*
24 | These are various attributes that will be set by default when the model gets created.
25 | */
26 | defaults: {
27 | photo: "../../../img/placeholder.png",
28 | name: "",
29 | address: "",
30 | tel: "",
31 | email: "",
32 | type: ""
33 | }
34 | });
35 |
36 | /*
37 | Creating a new collection called Contacts by extending Backbone.Collection class.
38 | */
39 | var Contacts = Backbone.Collection.extend({
40 | /*
41 | Used to specify the model class that the collection contains.
42 | */
43 | model: Contact
44 | });
45 |
46 | /*
47 | Creating a new view called ContactView by extending Backbone.View class.
48 | */
49 | var ContactView = Backbone.View.extend({
50 | /*
51 | tagName & className property will create following HTML markup.
52 |
53 | */
54 | className: "contact-container",
55 |
56 | /*
57 | Template for display mode.
58 | */
59 | template: _.template($("#contactTemplate").html()),
60 |
61 | /*
62 | Event hash will handle all the event listener.
63 | */
64 | events: {
65 | "click button.delete": "deleteContact"
66 | },
67 |
68 | /*
69 | This method will get fired when user clicks delete button.
70 | */
71 | deleteContact: function () {
72 | // remove view from page
73 | this.remove();
74 | },
75 |
76 | /*
77 | This method will have all the rendering process.
78 | */
79 | render: function () {
80 | /*
81 | Passing the model data to template and then to this.$el.html which has article tag.
82 | Thus, the updated template with all the data rendered gets appended to article tag.
83 | */
84 | this.$el.html(this.template(this.model.toJSON()));
85 | return this;
86 | }
87 |
88 | });
89 |
90 | /*
91 | Creating a new view called DirectoryView by extending Backbone.View class.
92 | */
93 | var ContactsView = Backbone.View.extend({
94 |
95 | el: $("#contacts"),
96 |
97 | /*
98 | This initialize function will get called when the view is first created.
99 | */
100 | initialize: function () {
101 | /*
102 | Creating an object from Contacts which calls initialize function.
103 | */
104 | this.collection = new Contacts(people);
105 |
106 | this.render();
107 |
108 | this.collection.on("reset", this.render, this);
109 | this.collection.on("add", this.renderContact, this);
110 | },
111 |
112 | render: function () {
113 | _.each(this.collection.models, function (item) {
114 | this.renderContact(item);
115 | }, this);
116 | },
117 |
118 | renderContact: function (item) {
119 | /*
120 | Creating an object from ContactView which calls initialize function.
121 |
122 | Passing the model to ContactView.
123 | */
124 | var contactView = new ContactView({
125 | model: item
126 | });
127 |
128 | /*
129 | Calling the render function and getting the updated el content and
130 | append it to this.$el which content div#contacts.
131 | */
132 | this.$el.append(contactView.render().el);
133 | }
134 |
135 | });
136 |
137 | /*
138 | Creating an object from DirectoryView which calls initialize function.
139 | */
140 | var contacts = new ContactsView();
141 |
142 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example4/Example-4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Under Training Session 5: Application Example 4
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Application Example 4
20 |
21 |
22 |
Scope of Application
23 |
24 | Perform Edit/Save operation (CRU D, U = Update) on data
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
67 |
68 |
69 |
102 |
103 |
104 |
105 |
112 |
113 |
114 |
122 |
123 |
124 |
131 |
132 |
133 |
137 |
138 |
139 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example4/example-main-4.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*
4 | The goal of this file is to provide the basic understanding
5 | 1. Perform Edit/Save operation (CRUD, U = Update) on data.
6 | */
7 |
8 | /*
9 | This is JavaScript object holding some amount of data used for data-manipulation.
10 | */
11 | var people = [
12 | { name: "ABC", address: "Pune, India", tel: "0123456789", email: "abc@cybage.com", type: "family" },
13 | { name: "PQR", address: "Canada, USA", tel: "0123456987", email: "pqr@blackberry.com", type: "friend" },
14 | { name: "XYZ", address: "Mumbai, India", tel: "0123456584", email: "xyz@infosys.com", type: "family" },
15 | { name: "DEF", address: "New York, USA", tel: "0123465645", email: "def@wipro.com", type: "colleague" },
16 | { name: "GHI", address: "New York, USA", tel: "0123465645", email: "ghi@wipro.com", type: "family" }
17 | ];
18 |
19 | /*
20 | Creating a new model called Contact by extending Backbone.Model class.
21 | */
22 | var Contact = Backbone.Model.extend({
23 | /*
24 | These are various attributes that will be set by default when the model gets created.
25 | */
26 | defaults: {
27 | photo: "../../../img/placeholder.png",
28 | name: "",
29 | address: "",
30 | tel: "",
31 | email: "",
32 | type: ""
33 | }
34 | });
35 |
36 | /*
37 | Creating a new collection called Contacts by extending Backbone.Collection class.
38 | */
39 | var Contacts = Backbone.Collection.extend({
40 | /*
41 | Used to specify the model class that the collection contains.
42 | */
43 | model: Contact
44 | });
45 |
46 | /*
47 | Creating a new view called ContactView by extending Backbone.View class.
48 | */
49 | var ContactView = Backbone.View.extend({
50 | /*
51 | tagName & className property will create following HTML markup.
52 |
53 | */
54 | className: "contact-container",
55 |
56 | /*
57 | Template for display mode.
58 | */
59 | template: _.template($("#contactTemplate").html()),
60 |
61 | /*
62 | Template for edit mode.
63 | */
64 | editTemplate: _.template($("#contactEditTemplate").html()),
65 |
66 | /*
67 | Event hash will handle all the event listener.
68 | */
69 | events: {
70 | "click button.edit": "editContact",
71 | "click button.save": "saveEdits",
72 | "click button.cancel": "cancelEdit"
73 | },
74 |
75 | /*
76 | This method will get fired when user clicks edit button.
77 | The goal is to switch to display mode to edit mode.
78 | */
79 | editContact: function () {
80 | this.$el.html(this.editTemplate(this.model.toJSON()));
81 | },
82 |
83 | /*
84 | This method will get fired when user clicks save button.
85 | The goal is to switch to edit mode to display mode WITH saving updated data.
86 | */
87 | saveEdits: function (e) {
88 | e.preventDefault();
89 |
90 | var formData = {},
91 | prev = this.model.previousAttributes();
92 |
93 | // get form data
94 | $(e.target).closest("form").find(":input").not("button").each(function () {
95 | var el = $(this);
96 | formData[el.attr("class")] = el.val();
97 | });
98 |
99 | // update model
100 | this.model.set(formData);
101 |
102 | // render view
103 | this.render();
104 |
105 | // update contacts array
106 | _.each(contacts, function (contact) {
107 | if (_.isEqual(contact, prev)) {
108 | contacts.splice(_.indexOf(contacts, contact), 1, formData);
109 | }
110 | });
111 | },
112 |
113 | /*
114 | This method will get fired when user clicks cancel button.
115 | The goal is to switch to edit mode to display mode WITHOUT saving data.
116 | */
117 | cancelEdit: function () {
118 | this.render();
119 | },
120 |
121 | /*
122 | This method will have all the rendering process.
123 | */
124 | render: function () {
125 | /*
126 | Passing the model data to template and then to this.$el.html which has article tag.
127 | Thus, the updated template with all the data rendered gets appended to article tag.
128 | */
129 | this.$el.html(this.template(this.model.toJSON()));
130 | return this;
131 | }
132 |
133 | });
134 |
135 | /*
136 | Creating a new view called DirectoryView by extending Backbone.View class.
137 | */
138 | var ContactsView = Backbone.View.extend({
139 |
140 | el: $("#contacts"),
141 |
142 | /*
143 | This initialize function will get called when the view is first created.
144 | */
145 | initialize: function () {
146 | /*
147 | Creating an object from Contacts which calls initialize function.
148 | */
149 | this.collection = new Contacts(people);
150 |
151 | this.render();
152 |
153 | this.collection.on("reset", this.render, this);
154 | this.collection.on("add", this.renderContact, this);
155 | },
156 |
157 | render: function () {
158 | _.each(this.collection.models, function (item) {
159 | this.renderContact(item);
160 | }, this);
161 | },
162 |
163 | renderContact: function (item) {
164 | /*
165 | Creating an object from ContactView which calls initialize function.
166 |
167 | Passing the model to ContactView.
168 | */
169 | var contactView = new ContactView({
170 | model: item
171 | });
172 |
173 | /*
174 | Calling the render function and getting the updated el content and
175 | append it to this.$el which content div#contacts.
176 | */
177 | this.$el.append(contactView.render().el);
178 | }
179 |
180 | });
181 |
182 | /*
183 | Creating an object from DirectoryView which calls initialize function.
184 | */
185 | var contacts = new ContactsView();
186 |
187 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example5/Example-5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Under Training Session 5: Application Example 5
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Application Example 5
20 |
21 |
22 |
Scope of Application
23 |
24 | Perform routing operation based on type
25 |
26 |
27 |
28 |
29 |
30 |
35 |
36 |
37 |
66 |
67 |
68 |
69 |
70 |
77 |
78 |
79 |
87 |
88 |
89 |
96 |
97 |
98 |
102 |
103 |
104 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/Example5/example-main-5.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*
4 | The goal of this file is to provide the basic understanding
5 | 1. Understanding how Backbone Router works.
6 | */
7 |
8 | /*
9 | This is JavaScript object holding some amount of data used for data-manipulation.
10 | */
11 | var people = [
12 | { name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
13 | { name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
14 | { name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
15 | { name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
16 | { name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
17 | { name: "Contact 6", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
18 | { name: "Contact 7", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
19 | { name: "Contact 8", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
20 | ];
21 |
22 | /*
23 | Creating a new model called Contact by extending Backbone.Model class.
24 | */
25 | var Contact = Backbone.Model.extend({
26 | defaults: {
27 | photo: "../../../img/placeholder.png",
28 | name: "",
29 | address: "",
30 | tel: "",
31 | email: "",
32 | type: ""
33 | }
34 | });
35 |
36 | /*
37 | Creating a new collection called Contacts by extending Backbone.Collection class.
38 | */
39 | var Contacts = Backbone.Collection.extend({
40 | model: Contact
41 | });
42 |
43 | /*
44 | Creating a new view called ContactView by extending Backbone.View class.
45 | */
46 | var ContactView = Backbone.View.extend({
47 | tagName: "article",
48 | className: "contact-container",
49 | template: _.template($("#contactTemplate").html()),
50 |
51 | render: function () {
52 | this.$el.html(this.template(this.model.toJSON()));
53 | return this;
54 | }
55 | });
56 |
57 | /*
58 | Creating a new view called ContactsView by extending Backbone.View class.
59 | */
60 | var ContactsView = Backbone.View.extend({
61 | el: $("#contacts"),
62 |
63 | /*
64 | This initialize function will get called when the view is first created.
65 | */
66 | initialize: function () {
67 | /*
68 | Creating an object from Contacts which calls initialize function.
69 | */
70 | this.collection = new Contacts(people);
71 |
72 | this.render();
73 | this.$el.find("#filter").append(this.createSelect());
74 |
75 | this.on("change:filterType", this.filterByType, this);
76 | this.collection.on("reset", this.render, this);
77 | this.collection.on("add", this.renderContact, this);
78 |
79 | },
80 |
81 | render: function () {
82 | this.$el.find("article").remove();
83 |
84 | _.each(this.collection.models, function (item) {
85 | this.renderContact(item);
86 | }, this);
87 | },
88 |
89 | renderContact: function (item) {
90 | /*
91 | Creating an object from ContactView which calls initialize function.
92 | Passing the model to ContactView.
93 | */
94 | var contactView = new ContactView({
95 | model: item
96 | });
97 |
98 | /*
99 | Calling the render function and getting the updated el content and
100 | append it to this.$el which content div#contacts.
101 | */
102 | this.$el.append(contactView.render().el);
103 | },
104 |
105 | // Pluck the type from the object people.
106 | getTypes: function () {
107 | return _.uniq(this.collection.pluck("type"), false, function (type) {
108 | return type.toLowerCase();
109 | });
110 | },
111 |
112 | /*
113 | Create a select html tag and fillup it with options & values.
114 | */
115 | createSelect: function () {
116 | var filter = this.$el.find("#filter"),
117 | select = $(" ", {
118 | html: "All "
119 | });
120 |
121 | _.each(this.getTypes(), function (item) {
122 | var option = $(" ", {
123 | value: item.toLowerCase(),
124 | text: item.toLowerCase()
125 | }).appendTo(select);
126 | });
127 |
128 | return select;
129 | },
130 |
131 | /*
132 | Event hash
133 | */
134 | events: {
135 | "change #filter select": "setFilter"
136 | },
137 |
138 | // Set filter property and fire change event
139 | setFilter: function (e) {
140 | this.filterType = e.currentTarget.value;
141 | this.trigger("change:filterType");
142 | },
143 |
144 | // Filter the view
145 | filterByType: function () {
146 | if (this.filterType === "all") {
147 | this.collection.reset(people);
148 | contactsRouter.navigate("filter/all");
149 | } else {
150 | this.collection.reset(people, { silent: true });
151 |
152 | var filterType = this.filterType,
153 | filtered = _.filter(this.collection.models, function (item) {
154 | return item.get("type").toLowerCase() === filterType;
155 | });
156 |
157 | this.collection.reset(filtered);
158 |
159 | contactsRouter.navigate("filter/" + filterType);
160 | }
161 | }
162 |
163 | });
164 |
165 | /*
166 | Creating a new router called ContactsRouter by extending Backbone.Router class.
167 | */
168 | var ContactsRouter = Backbone.Router.extend({
169 | routes: {
170 | "filter/:type": "urlFilter"
171 | },
172 |
173 | urlFilter: function (type) {
174 | contacts.filterType = type;
175 | contacts.trigger("change:filterType");
176 | }
177 | });
178 |
179 | /*
180 | Creating an object from ContactsView which calls initialize function.
181 | */
182 | var contacts = new ContactsView();
183 |
184 | /*
185 | Creating an object from ContactsRouter which calls initialize function.
186 | */
187 | var contactsRouter = new ContactsRouter();
188 |
189 | //start history service
190 | Backbone.history.start();
191 |
192 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Application Examples/README.md:
--------------------------------------------------------------------------------
1 | # Ch6 - Backbone Application Examples
2 |
3 | This idea behind these application examples have been taken from "Net-Tutsplus". So the credit goes to Nettuts website which provided the backbone application example.
4 |
5 | You can have a look here .
6 |
7 | The goal of this directory is to provide the basic understanding of the working application of Backbone.js Application.
8 |
9 | ## Example 1:
10 | * Perform Read operation (CR UD, R = Retrieve) on data.
11 |
12 | ## Example 2:
13 | * Perform Create operation (C RUD, C = Create) on data.
14 |
15 | ## Example 3:
16 | * Perform Delete operation (CRUD , D = Delete) on data.
17 |
18 | ## Example 4:
19 | * Perform Edit/Save operation (CRU D, U = Update) on data.
20 |
21 | ## Example 5:
22 | * Understanding the working of Backbone Router.
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Deep-Model/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Extended Training Session: Plugin Example 1
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Plugin Example 1
20 |
21 |
22 |
Scope of the Application
23 |
24 | Understanding how to Backbone-Deep-Model Plugins used.
25 | Get and set nested attributes with path syntax.
26 | Triggers change events for changes on nested attributes.
27 |
28 |
29 |
How to run this example.
30 |
31 | Open Example-1.html in browser recommended Google Chrome.
32 | Press F12, go to console tab.
33 | See the message get displayed on that console tab.
34 |
35 |
36 |
37 | Link to Backbone-deep-model plugin:
38 | Backbone Deep-Model
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
53 |
54 |
55 |
58 |
59 |
60 |
63 |
64 |
65 |
68 |
69 |
70 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Deep-Model/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*** READ-ME
4 | * The goal of this file is to provide the basic understanding
5 | * 1. Understanding how to Backbone-Deep-Model Plugins used.
6 | * 2. Get and set nested attributes with path syntax.
7 | * 3. Triggers change events for changes on nested attributes.
8 | */
9 |
10 | /*** NOTE
11 | * Creating a new model called MasterModel by extending Backbone.Model class.
12 | * Syntax: Backbone.DeepModel.extend(properties, [classProperties])
13 | *
14 | * As our models has nested attributes; we are going to use Deep-Model plugin for
15 | * improved support for models with nested attributes,
16 | * allows you to get and set nested attributes with path syntax, e.g. email.to, email.form etc.
17 | * triggers change events for changes on nested attributes.
18 | */
19 | var MasterModel = Backbone.DeepModel.extend({
20 | /*
21 | This initialize function will get called when the model is first created.
22 | */
23 | initialize: function() {
24 | console.log("Your deep-model has been initialize.");
25 | this.on('change:contacts.mobile', this.updates());
26 | },
27 |
28 | /*
29 | These are various attributes that will be set when the model gets created.
30 | */
31 | defaults: {
32 | name: {
33 | firstname:'Ashwin',
34 | lastname:'Hegde'
35 | },
36 | companyname: 'Cybage Software Private Limited',
37 | contacts: {
38 | mobile: '9822769479',
39 | ext: '8621',
40 | email: {
41 | 'company': 'ashwinh@cybage.com',
42 | 'personal': 'ashwin.hegde3@gmail.com',
43 | }
44 | },
45 | networks: [
46 | { name: 'Bhavik', company: 'Blackberry' },
47 | { name: 'Nakool', company: 'Infosys' }
48 | ]
49 | },
50 |
51 | /*
52 | This event gets fired when contacts.mobile value get changed.
53 | */
54 | updates: function() {
55 | console.log("Change event get called.");
56 | }
57 | });
58 |
59 | /*
60 | Creating an object from MasterModel which calls initialize function.
61 | */
62 | var masterModel = new MasterModel();
63 | console.log("Model class object: ");
64 | console.log(masterModel);
65 |
66 | console.log("Get nested attributes level 1:");
67 | console.log(masterModel.get('name'));
68 | console.log(masterModel.get('companyname'));
69 | console.log(masterModel.get('contacts'));
70 |
71 | console.log("Get nested attributes level 2:")
72 | console.log(masterModel.get('name.firstname'));
73 | console.log(masterModel.get('contacts.ext'));
74 |
75 | console.log("Get nested attributes level 3:")
76 | console.log(masterModel.get('contacts.email.personal'));
77 |
78 | console.log("Get nested attrbutes array level 3: ")
79 | console.log(masterModel.get('networks.1.name'));
80 |
81 | console.log("Set nested attributes at level 3");
82 | masterModel.set({
83 | 'contacts.email.personal': 'ashwinh.cybage@gmail.com',
84 | 'contacts.email.webmail': 'ashwinh@yahoo.com'
85 | });
86 | console.log("Get new nested attributes array level 3:")
87 | console.log(masterModel.get('contacts.email.personal'));
88 | console.log(masterModel.get('contacts.email.webmail'));
89 |
90 | console.log("Set nested attrbutes array level 3: ")
91 | masterModel.set({
92 | 'networks.1.name': 'Nakul',
93 | 'networks.2.name': 'Yogi',
94 | 'networks.2.company': 'Wipro'
95 | });
96 |
97 | console.log("Get nested attrbutes array level 3: ")
98 | console.log(masterModel.get('networks.1.name'));
99 | console.log(masterModel.get('networks.2.name'));
100 |
101 | masterModel.set({
102 | 'contacts.mobile': '9822256473'
103 | });
104 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example1/Example-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Extended Training Session: Plugin Example 1
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Plugin Example 1
20 |
21 |
22 |
Scope of the Application
23 |
24 | Understanding how to Backbone-Forms Plugins used.
25 | Using Schema property in Backbone.Model & Backbone.Form
26 |
27 |
28 |
29 | Link to Backbone-Forms plugin:
30 | Backbone Forms
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
63 |
64 |
65 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example1/example-main-1.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*** READ-ME
4 | * The goal of this file is to provide the basic understanding
5 | * 1. Understanding how to Backbone-Forms Plugins used.
6 | * 2. Using Schema property in Backbone.Model & Backbone.Form
7 | */
8 |
9 | var MasterModel = Backbone.Model.extend({
10 | /*
11 | Schema property is used to create the form.
12 | Either you can include it in model or in Backbone.Form
13 |
14 | NOTE: If are in camelCased will leave 1 space &
15 | if all small letters are used there will be no space between labels.
16 | E.g. Firstname becomes Firstname.
17 | E.g. lastName becomes Last Name.
18 | */
19 | schema: {
20 | Firstname: 'Text',
21 | LastName: 'Text'
22 | }
23 | });
24 |
25 | /*
26 | Creating an object from MasterModel1 which calls initialize function.
27 | */
28 | var masterModel = new MasterModel();
29 |
30 | var form = new Backbone.Form({
31 | /*
32 | Setting model's object to get the model schema and build the form.
33 | */
34 | model: masterModel,
35 |
36 | /*
37 | If schema property defined in Backbone.Form will override the schema property defined in Model
38 | if model is specified.
39 |
40 | NOTE: uncomment below schema code and see the effects. Thus either toy can specify schama in our
41 | Backbone.Model or Backbone.Form
42 | */
43 | // schema: {
44 | // MiddleName: 'Text'
45 | // }
46 |
47 | }).render();
48 |
49 | $('#form-container').append(form.el);
50 |
51 |
52 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example2/Example-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Extended Training Session: Plugin Example 2
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Plugin Example 2
20 |
21 |
22 |
Scope of the Application
23 |
24 | Form elements - input[Text, Password, Hidden, Number].
25 | Recommended way of using data property with schema property.
26 |
27 |
28 |
29 | Link to Backbone-Forms plugin:
30 | Backbone Forms
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
47 |
48 |
49 |
52 |
53 |
54 |
57 |
58 |
59 |
63 |
64 |
65 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example2/example-main-2.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*** READ-ME
4 | * The goal of this file is to provide the basic understanding
5 | * 1. Form elements - input[Text, Password, Hidden, Number].
6 | * 2. Recommended way of using data property with schema property.
7 | */
8 |
9 | var form = new Backbone.Form({
10 | /*
11 | Schema property is used to create the form.
12 | Either you can include it in Backbone.Model or in Backbone.Form
13 |
14 | NOTE: data property does not works with Backbone.Model.
15 | Thus your form includes default values; Schema property needs to be defined in Backbone.Form.
16 | */
17 | schema: {
18 | /* Text Input */
19 | InputText: 'Text', // or { type:'Text' },
20 |
21 | /* Password Input */
22 | InputPassword: 'Password', // or { type:'Password' },
23 |
24 | /* TextArea */
25 | TextArea: 'TextArea',
26 |
27 | /* Hidden Input */
28 | InputHidden: 'Hidden',
29 |
30 | /* Number */
31 | InputNumber: 'Number'
32 | },
33 |
34 | data: {
35 | InputText: 'Default Text',
36 | InputPassword: 'Password',
37 | TextArea: 'Hello, Backbone-Form'
38 | }
39 |
40 | }).render();
41 |
42 | $('#form-container').append(form.el);
43 |
44 |
45 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example3/Example-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Extended Training Session: Plugin Example 3
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Structuring your web apps via Backbone.JS
17 |
18 |
19 |
Part of Extended Training Session: Plugin Example 3
20 |
21 |
22 |
Scope of the Application
23 |
24 | Using Form list
25 |
26 |
27 |
28 | Link to Backbone-Forms plugin:
29 | Backbone Forms
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
46 |
47 |
48 |
51 |
52 |
53 |
56 |
57 |
58 |
65 |
66 |
67 |
68 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/Form/Example3/example-main-3.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 |
3 | /*** READ-ME
4 | * The goal of this file is to provide the basic understanding
5 | * 1. Using list.
6 | */
7 |
8 | var form = new Backbone.Form({
9 | schema: {
10 | todoList: {
11 | type: 'List',
12 | itemType: 'Text',
13 | confirmDelete: 'Are you sure you want to delete this item?'
14 | }
15 | }
16 | }).render();
17 |
18 | $('#form-container').append(form.el);
19 |
20 |
21 | } (jQuery));
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/Models/README.md:
--------------------------------------------------------------------------------
1 | Models Plugins
2 | ==============
3 | The goal of this directory is to provide the basic understanding of the Backbone's model based plugins used with Backbone applications.
4 |
5 | List of Backbone's Model Plugins
6 | =================================
7 |
8 |
9 | Backbone Deep Model:
10 | Plugin Issues: https://github.com/powmedia/backbone-deep-model/issues
11 |
12 |
13 | Backbone Forms:
14 | Plugin Issues: https://github.com/powmedia/backbone-forms/issues
15 |
16 |
17 |
--------------------------------------------------------------------------------
/codes/Ch6_Extended-Session/Plugins Examples/README.md:
--------------------------------------------------------------------------------
1 | Plugins Examples
2 | ================
3 | The goal of this directory is to provide the basic understanding of the different plugins used with Backbone applications to make developers life easy.
4 | There are large number of plugins but following are the choosen few plugins list which I found to be very useful.
5 |
6 |
7 | NOTE: Before using these plugins into your projects; please have a look into following details
8 |
9 | Limitations
10 | Features support
11 | Issues raised in their respected git issue tracker
12 |
13 |
14 | Plugins List
15 | ============
16 |
17 |
18 | Models
19 |
20 | Backbone Deep Model
21 | Backbone Forms
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/codes/css/bootstrap-responsive.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.1.1
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade.in{top:auto}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
10 |
--------------------------------------------------------------------------------
/codes/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hegdeashwin/Backbone/05f032b2ea8ad4d484ebf793b5bf96fd52302f1b/codes/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/codes/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hegdeashwin/Backbone/05f032b2ea8ad4d484ebf793b5bf96fd52302f1b/codes/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/codes/img/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hegdeashwin/Backbone/05f032b2ea8ad4d484ebf793b5bf96fd52302f1b/codes/img/placeholder.png
--------------------------------------------------------------------------------
/codes/js/bbplugins/deep-model/deep-model.min.js:
--------------------------------------------------------------------------------
1 | /*jshint expr:true eqnull:true */
2 | /**
3 | *
4 | * Backbone.DeepModel v0.10.4
5 | *
6 | * Copyright (c) 2013 Charles Davison, Pow Media Ltd
7 | *
8 | * https://github.com/powmedia/backbone-deep-model
9 | * Licensed under the MIT License
10 | */
11 |
12 | (function(){var e,t,n,r,i,s,o=[].slice;n=function(e){var t,r;return!_.isObject(e)||_.isFunction(e)?e:e instanceof Backbone.Collection||e instanceof Backbone.Model?e:_.isDate(e)?new Date(e.getTime()):_.isRegExp(e)?new RegExp(e.source,e.toString().replace(/.*\//,"")):(r=_.isArray(e||_.isArguments(e)),t=function(e,t,i){return r?e.push(n(t)):e[i]=n(t),e},_.reduce(e,t,r?[]:{}))},s=function(e){return e==null?!1:(e.prototype==={}.prototype||e.prototype===Object.prototype)&&_.isObject(e)&&!_.isArray(e)&&!_.isFunction(e)&&!_.isDate(e)&&!_.isRegExp(e)&&!_.isArguments(e)},t=function(e){return _.filter(_.keys(e),function(t){return s(e[t])})},e=function(e){return _.filter(_.keys(e),function(t){return _.isArray(e[t])})},i=function(n,r,s){var o,u,a,f,l,c,h,p,d,v;s==null&&(s=20);if(s<=0)return console.warn("_.deepExtend(): Maximum depth of recursion hit."),_.extend(n,r);c=_.intersection(t(n),t(r)),u=function(e){return r[e]=i(n[e],r[e],s-1)};for(h=0,d=c.length;h0)e=i(e,n(r.shift()),t);return e},_.mixin({deepClone:n,isBasicObject:s,basicObjects:t,arrays:e,deepExtend:r})}).call(this),function(e){typeof define=="function"&&define.amd?define(["underscore","backbone"],e):e(_,Backbone)}(function(e,t){function n(t){var r={},i=o.keyPathSeparator;for(var s in t){var u=t[s];if(u&&u.constructor===Object&&!e.isEmpty(u)){var a=n(u);for(var f in a){var l=a[f];r[s+i+f]=l}}else r[s]=u}return r}function r(t,n,r){var i=o.keyPathSeparator,s=n.split(i),u=t;r||r===!1;for(var a=0,f=s.length;a0;E--){var S=e.first(w,E).join(g),x=S+g+"*";this.trigger("change:"+x,this,r(m,S),a)}}}if(d)return this;if(!p)while(this._pending)this._pending=!1,this.trigger("change",this,a);return this._pending=!1,this._changing=!1,this},clear:function(t){var r={},i=n(this.attributes);for(var s in i)r[s]=void 0;return this.set(r,e.extend({},t,{unset:!0}))},hasChanged:function(t){return t==null?!e.isEmpty(this.changed):r(this.changed,t)!==undefined},changedAttributes:function(t){if(!t)return this.hasChanged()?n(this.changed):!1;var r=this._changing?this._previousAttributes:this.attributes;t=n(t),r=n(r);var i,s=!1;for(var o in t){if(e.isEqual(r[o],i=t[o]))continue;(s||(s={}))[o]=i}return s},previous:function(e){return e==null||!this._previousAttributes?null:r(this._previousAttributes,e)},previousAttributes:function(){return e.deepClone(this._previousAttributes)}});return o.keyPathSeparator=".",t.DeepModel=o,typeof module!="undefined"&&(module.exports=o),t})
13 |
--------------------------------------------------------------------------------
/codes/js/bbplugins/forms/editors/list.min.js:
--------------------------------------------------------------------------------
1 | (function(e){e.editors.List=e.editors.Base.extend({events:{'click [data-action="add"]':function(e){e.preventDefault(),this.addItem(null,!0)}},initialize:function(t){t=t||{};var n=e.editors;n.Base.prototype.initialize.call(this,t);var r=this.schema;if(!r)throw"Missing required option 'schema'";this.template=t.template||this.constructor.template,this.Editor=function(){var e=r.itemType;return e?n.List[e]?n.List[e]:n[e]:n.Text}(),this.items=[]},render:function(){var e=this,t=this.value||[],n=$($.trim(this.template()));return this.$list=n.is("[data-items]")?n:n.find("[data-items]"),t.length?_.each(t,function(t){e.addItem(t)}):this.Editor.isAsync||this.addItem(),this.setElement(n),this.$el.attr("id",this.id),this.$el.attr("name",this.key),this.hasFocus&&this.trigger("blur",this),this},addItem:function(t,n){var r=this,i=e.editors,s=(new i.List.Item({list:this,form:this.form,schema:this.schema,value:t,Editor:this.Editor,key:this.key})).render(),o=function(){r.items.push(s),r.$list.append(s.el),s.editor.on("all",function(e){if(e==="change")return;var t=_.toArray(arguments);t[0]="item:"+e,t.splice(1,0,r),i.List.prototype.trigger.apply(this,t)},r),s.editor.on("change",function(){s.addEventTriggered||(s.addEventTriggered=!0,this.trigger("add",this,s.editor)),this.trigger("item:change",this,s.editor),this.trigger("change",this)},r),s.editor.on("focus",function(){if(this.hasFocus)return;this.trigger("focus",this)},r),s.editor.on("blur",function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(_.find(e.items,function(e){return e.editor.hasFocus}))return;e.trigger("blur",e)},0)},r);if(n||t)s.addEventTriggered=!0;n&&(r.trigger("add",r,s.editor),r.trigger("change",r))};return this.Editor.isAsync?s.editor.on("readyToAdd",o,this):(o(),s.editor.focus()),s},removeItem:function(e){var t=this.schema.confirmDelete;if(t&&!confirm(t))return;var n=_.indexOf(this.items,e);this.items[n].remove(),this.items.splice(n,1),e.addEventTriggered&&(this.trigger("remove",this,e.editor),this.trigger("change",this)),!this.items.length&&!this.Editor.isAsync&&this.addItem()},getValue:function(){var e=_.map(this.items,function(e){return e.getValue()});return _.without(e,undefined,"")},setValue:function(e){this.value=e,this.render()},focus:function(){if(this.hasFocus)return;this.items[0]&&this.items[0].editor.focus()},blur:function(){if(!this.hasFocus)return;var e=_.find(this.items,function(e){return e.editor.hasFocus});e&&e.editor.blur()},remove:function(){_.invoke(this.items,"remove"),e.editors.Base.prototype.remove.call(this)},validate:function(){if(!this.validators)return null;var e=_.map(this.items,function(e){return e.validate()}),t=_.compact(e).length?!0:!1;if(!t)return null;var n={type:"list",message:"Some of the items in the list failed validation",errors:e};return n}},{template:_.template(' ',null,e.templateSettings)}),e.editors.List.Item=e.editors.Base.extend({events:{'click [data-action="remove"]':function(e){e.preventDefault(),this.list.removeItem(this)},"keydown input[type=text]":function(e){if(e.keyCode!==13)return;e.preventDefault(),this.list.addItem(),this.list.$list.find("> li:last input").focus()}},initialize:function(t){this.list=t.list,this.schema=t.schema||this.list.schema,this.value=t.value,this.Editor=t.Editor||e.editors.Text,this.key=t.key,this.template=t.template||this.schema.itemTemplate||this.constructor.template,this.errorClassName=t.errorClassName||this.constructor.errorClassName,this.form=t.form},render:function(){this.editor=(new this.Editor({key:this.key,schema:this.schema,value:this.value,list:this.list,item:this,form:this.form})).render();var e=$($.trim(this.template()));return e.find("[data-editor]").append(this.editor.el),this.setElement(e),this},getValue:function(){return this.editor.getValue()},setValue:function(e){this.editor.setValue(e)},focus:function(){this.editor.focus()},blur:function(){this.editor.blur()},remove:function(){this.editor.remove(),Backbone.View.prototype.remove.call(this)},validate:function(){var e=this.getValue(),t=this.list.form?this.list.form.getValue():{},n=this.schema.validators,r=this.getValidator;if(!n)return null;var i=null;return _.every(n,function(n){return i=r(n)(e,t),i?!1:!0}),i?this.setError(i):this.clearError(),i?i:null},setError:function(e){this.$el.addClass(this.errorClassName),this.$el.attr("title",e.message)},clearError:function(){this.$el.removeClass(this.errorClassName),this.$el.attr("title",null)}},{template:_.template(' ×
',null,e.templateSettings),errorClassName:"error"}),e.editors.List.Modal=e.editors.Base.extend({events:{click:"openEditor"},initialize:function(t){t=t||{},e.editors.Base.prototype.initialize.call(this,t);if(!e.editors.List.Modal.ModalAdapter)throw"A ModalAdapter is required";this.form=t.form;if(!t.form)throw'Missing required option: "form"';this.template=t.template||this.constructor.template},render:function(){var e=this;return _.isEmpty(this.value)?this.openEditor():(this.renderSummary(),setTimeout(function(){e.trigger("readyToAdd")},0)),this.hasFocus&&this.trigger("blur",this),this},renderSummary:function(){this.$el.html($.trim(this.template({summary:this.getStringValue()})))},itemToString:function(t){var n=function(t){var n={key:t};return e.Field.prototype.createTitle.call(n)};t=t||{};var r=[];return _.each(this.nestedSchema,function(e,i){var s=e.title?e.title:n(i),o=t[i];if(_.isUndefined(o)||_.isNull(o))o="";r.push(s+": "+o)}),r.join(" ")},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?"[Empty]":e.itemToString?e.itemToString(t):this.itemToString(t)},openEditor:function(){var t=this,n=this.form.constructor,r=this.modalForm=new n({schema:this.nestedSchema,data:this.value}),i=this.modal=new e.editors.List.Modal.ModalAdapter({content:r,animate:!0});i.open(),this.trigger("open",this),this.trigger("focus",this),i.on("cancel",this.onModalClosed,this),i.on("ok",_.bind(this.onModalSubmitted,this))},onModalSubmitted:function(){var e=this.modal,t=this.modalForm,n=!this.value,r=t.validate();if(r)return e.preventClose();this.value=t.getValue(),this.renderSummary(),n&&this.trigger("readyToAdd"),this.trigger("change",this),this.onModalClosed()},onModalClosed:function(){this.modal=null,this.modalForm=null,this.trigger("close",this),this.trigger("blur",this)},getValue:function(){return this.value},setValue:function(e){this.value=e},focus:function(){if(this.hasFocus)return;this.openEditor()},blur:function(){if(!this.hasFocus)return;this.modal&&this.modal.trigger("cancel")}},{template:_.template(" <%= summary %>
",null,e.templateSettings),ModalAdapter:Backbone.BootstrapModal,isAsync:!0}),e.editors.List.Object=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.subSchema)throw'Missing required option "schema.subSchema"';this.nestedSchema=t.subSchema}}),e.editors.List.NestedModel=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.model)throw'Missing required option "schema.model"';var n=t.model.prototype.schema;this.nestedSchema=_.isFunction(n)?n():n},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?null:e.itemToString?e.itemToString(t):(new e.model(t)).toString()}})})(Backbone.Form)
--------------------------------------------------------------------------------
/codes/js/bbplugins/model-binder/collectionBinder.min.js:
--------------------------------------------------------------------------------
1 | // Backbone.CollectionBinder v1.0.2
2 | // (c) 2013 Bart Wood
3 | // Distributed Under MIT License
4 |
5 | (function(){if(!Backbone){throw"Please include Backbone.js before Backbone.ModelBinder.js"}if(!Backbone.ModelBinder){throw"Please include Backbone.ModelBinder.js before Backbone.CollectionBinder.js"}Backbone.CollectionBinder=function(e,t){_.bindAll.apply(_,[this].concat(_.functions(this)));this._elManagers={};this._elManagerFactory=e;if(!this._elManagerFactory)throw"elManagerFactory must be defined.";this._elManagerFactory.trigger=this.trigger;this._options=t||{}};Backbone.CollectionBinder.VERSION="1.0.1";_.extend(Backbone.CollectionBinder.prototype,Backbone.Events,{bind:function(e,t){this.unbind();if(!e)throw"collection must be defined";if(!t)throw"parentEl must be defined";this._collection=e;this._elManagerFactory.setParentEl(t);this._onCollectionReset();this._collection.on("add",this._onCollectionAdd,this);this._collection.on("remove",this._onCollectionRemove,this);this._collection.on("reset",this._onCollectionReset,this);this._collection.on("sort",this._onCollectionSort,this)},unbind:function(){if(this._collection!==undefined){this._collection.off("add",this._onCollectionAdd);this._collection.off("remove",this._onCollectionRemove);this._collection.off("reset",this._onCollectionReset);this._collection.off("sort",this._onCollectionSort)}this._removeAllElManagers()},getManagerForEl:function(e){var t,n,r=_.values(this._elManagers);for(t=0;t0},getModel:function(){return this._model},getEl:function(){return this._el}};_.extend(t,this);return t}});Backbone.CollectionBinder.ViewManagerFactory=function(e){_.bindAll.apply(_,[this].concat(_.functions(this)));this._viewCreator=e;if(!_.isFunction(this._viewCreator))throw"viewCreator must be a valid function that accepts a model and returns a backbone view"};_.extend(Backbone.CollectionBinder.ViewManagerFactory.prototype,{setParentEl:function(e){this._parentEl=e},getParentEl:function(){return this._parentEl},makeElManager:function(e){var t={_model:e,createEl:function(){this._view=this._viewCreator(e);$(this._parentEl).append(this._view.render(this._model).el);this.trigger("elCreated",this._model,this._view)},removeEl:function(){if(this._view.close!==undefined){this._view.close()}else{this._view.$el.remove();console.log("warning, you should implement a close() function for your view, you might end up with zombies")}this.trigger("elRemoved",this._model,this._view)},isElContained:function(e){return this._view.el===e||this._view.$el.has(e).length>0},getModel:function(){return this._model},getView:function(){return this._view},getEl:function(){return this._view.$el}};_.extend(t,this);return t}})}).call(this)
--------------------------------------------------------------------------------
/codes/js/bbplugins/model-binder/modelBinder.min.js:
--------------------------------------------------------------------------------
1 | // Backbone.ModelBinder v1.0.4
2 | // (c) 2013 Bart Wood
3 | // Distributed Under MIT License
4 | (function(e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","backbone"],e)}else{e(_,$,Backbone)}})(function(e,t,n){if(!n){throw"Please include Backbone.js before Backbone.ModelBinder.js"}n.ModelBinder=function(){e.bindAll.apply(e,[this].concat(e.functions(this)))};n.ModelBinder.SetOptions=function(e){n.ModelBinder.options=e};n.ModelBinder.VERSION="1.0.3";n.ModelBinder.Constants={};n.ModelBinder.Constants.ModelToView="ModelToView";n.ModelBinder.Constants.ViewToModel="ViewToModel";e.extend(n.ModelBinder.prototype,{bind:function(e,n,r,i){this.unbind();this._model=e;this._rootEl=n;this._setOptions(i);if(!this._model)this._throwException("model must be specified");if(!this._rootEl)this._throwException("rootEl must be specified");if(r){this._attributeBindings=t.extend(true,{},r);this._initializeAttributeBindings();this._initializeElBindings()}else{this._initializeDefaultBindings()}this._bindModelToView();this._bindViewToModel()},bindCustomTriggers:function(e,t,n,r,i){this._triggers=n;this.bind(e,t,r,i)},unbind:function(){this._unbindModelToView();this._unbindViewToModel();if(this._attributeBindings){delete this._attributeBindings;this._attributeBindings=undefined}},_setOptions:function(t){this._options=e.extend({boundAttribute:"name"},n.ModelBinder.options,t);if(!this._options["modelSetOptions"]){this._options["modelSetOptions"]={}}this._options["modelSetOptions"].changeSource="ModelBinder";if(!this._options["changeTriggers"]){this._options["changeTriggers"]={"":"change","[contenteditable]":"blur"}}if(!this._options["initialCopyDirection"]){this._options["initialCopyDirection"]=n.ModelBinder.Constants.ModelToView}},_initializeAttributeBindings:function(){var t,n,r,i,s;for(t in this._attributeBindings){n=this._attributeBindings[t];if(e.isString(n)){r={elementBindings:[{selector:n}]}}else if(e.isArray(n)){r={elementBindings:n}}else if(e.isObject(n)){r={elementBindings:[n]}}else{this._throwException("Unsupported type passed to Model Binder "+r)}for(i=0;i0;for(n=0;n=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this);
6 | //# sourceMappingURL=underscore-min.map
--------------------------------------------------------------------------------
/slides/Training-Session-1.ppsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hegdeashwin/Backbone/05f032b2ea8ad4d484ebf793b5bf96fd52302f1b/slides/Training-Session-1.ppsx
--------------------------------------------------------------------------------
/slides/Training-Session-8.ppsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hegdeashwin/Backbone/05f032b2ea8ad4d484ebf793b5bf96fd52302f1b/slides/Training-Session-8.ppsx
--------------------------------------------------------------------------------