New adapter which allows for indexing into a backbone collection.
Showing
8 changed files
with
347 additions
and
0 deletions
.gitignore
0 → 100644
Gruntfile.js
0 → 100644
1 | // Generated on 2014-02-06 using generator-webapp 0.4.7 | ||
2 | /* global module */ | ||
3 | |||
4 | // # Globbing | ||
5 | // for performance reasons we're only matching one level down: | ||
6 | // 'test/spec/{,*/}*.js' | ||
7 | // use this if you want to recursively match all subfolders: | ||
8 | // 'test/spec/**/*.js' | ||
9 | |||
10 | module.exports = function (grunt) { | ||
11 | /* global require */ | ||
12 | 'use strict'; | ||
13 | |||
14 | var config = {}; | ||
15 | config.base = 'src'; | ||
16 | config.jshint = { | ||
17 | options: { | ||
18 | }, | ||
19 | browserOptions: { | ||
20 | }, | ||
21 | }; | ||
22 | config.bower = { | ||
23 | directory: 'lib/bower', | ||
24 | }; | ||
25 | config.jscs = { | ||
26 | options: { | ||
27 | validateIndentation: 4, | ||
28 | reporter: 'console', | ||
29 | maxErrors: -1, | ||
30 | }, | ||
31 | }; | ||
32 | config.jasmine = { | ||
33 | withCoverage: true, | ||
34 | }; | ||
35 | var montyPython = require('grunt-monty-python')(grunt); | ||
36 | montyPython.createConfig(config); | ||
37 | }; |
bower.json
0 → 100644
1 | { | ||
2 | "name": "rivets-backbone-is-required", | ||
3 | "version": "0.0.0", | ||
4 | "authors": [ | ||
5 | "Adam Heath <doogie@brainfood.com>" | ||
6 | ], | ||
7 | "main": [ | ||
8 | "src/scripts/rivets-backbone-is-required.js" | ||
9 | ], | ||
10 | "private": true, | ||
11 | "ignore": [ | ||
12 | "**/.*", | ||
13 | "node_modules", | ||
14 | "src/lib" | ||
15 | ], | ||
16 | "dependencies": { | ||
17 | "backbone": "", | ||
18 | "backbone-validation": "", | ||
19 | "jquery": "", | ||
20 | "requirejs": "", | ||
21 | "rivets": "", | ||
22 | "underscore": "" | ||
23 | }, | ||
24 | "devDependencies": { | ||
25 | "rivets-backbone-adapter": "" | ||
26 | } | ||
27 | } |
package.json
0 → 100644
1 | { | ||
2 | "name": "rivets-backbone-is-required", | ||
3 | "version": "0.0.0", | ||
4 | "main": [ | ||
5 | "src/scripts/rivets-backbone-is-required.js" | ||
6 | ], | ||
7 | "dependencies": { | ||
8 | "rivets": "", | ||
9 | "requirejs": "" | ||
10 | }, | ||
11 | "devDependencies": { | ||
12 | "bower-requirejs": "~0.9.2", | ||
13 | "grunt": "~0", | ||
14 | "grunt-monty-python": "git+ssh://git@gitlab.brainfood.com:brainfood/grunt-monty-python.git" | ||
15 | }, | ||
16 | "engines": { | ||
17 | "node": ">=0.8.0" | ||
18 | } | ||
19 | } | ||
20 |
src/scripts/config.js
0 → 100644
1 | /* global require:true */ | ||
2 | var require; | ||
3 | require = (function() { | ||
4 | 'use strict'; | ||
5 | |||
6 | var require = { | ||
7 | baseUrl: 'scripts', | ||
8 | config: { | ||
9 | 'rivets-error-binder': {} | ||
10 | }, | ||
11 | shim: { | ||
12 | bootstrap: { | ||
13 | deps: [ | ||
14 | 'jquery' | ||
15 | ] | ||
16 | }, | ||
17 | rivets: { | ||
18 | deps: [ | ||
19 | 'jquery' | ||
20 | ] | ||
21 | } | ||
22 | }, | ||
23 | paths: { | ||
24 | 'backbone-validation': '../lib/bower/backbone-validation/dist/backbone-validation-amd', | ||
25 | backbone: '../lib/bower/backbone/backbone', | ||
26 | underscore: '../lib/bower/underscore/underscore', | ||
27 | sightglass: '../lib/bower/sightglass/index', | ||
28 | rivets: '../lib/bower/rivets/dist/rivets', | ||
29 | jquery: '../lib/bower/jquery/dist/jquery', | ||
30 | 'rivets-backbone-adapter': '../lib/bower/rivets-backbone-adapter/rivets-backbone', | ||
31 | } | ||
32 | }; | ||
33 | |||
34 | return require; | ||
35 | })(); |
src/scripts/main.js
0 → 100644
1 | define(function(require) { | ||
2 | 'use strict'; | ||
3 | var module = require('module'); | ||
4 | var Backbone = require('backbone'); | ||
5 | var rivets = require('rivets'); | ||
6 | |||
7 | var separator = module.config().separator || ':'; | ||
8 | var adapter = rivets.adapters[separator] = (function(Model, Collection, collectionEvents) { | ||
9 | var observableFactory = function observableFactory(eventMethodName) { | ||
10 | return function (obj, keypath, callback) { | ||
11 | var eventMethod = obj[eventMethodName]; | ||
12 | if (obj instanceof Collection) { | ||
13 | eventMethod.call(obj, collectionEvents, callback); | ||
14 | } else if (obj instanceof Model) { | ||
15 | eventMethod.call(obj, keypath === '*' ? 'change' : ('change:' + keypath), callback); | ||
16 | if (keypath !== '*') { | ||
17 | var value = obj.get(keypath); | ||
18 | if (value instanceof Collection) { | ||
19 | value[eventMethodName].call(value, collectionEvents, callback); | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 | }; | ||
24 | }; | ||
25 | return { | ||
26 | observe: observableFactory('on'), | ||
27 | unobserve: observableFactory('off'), | ||
28 | get: function get(obj, keypath) { | ||
29 | if (obj instanceof Model) { | ||
30 | if (keypath === '*') { | ||
31 | return obj.attributes; | ||
32 | } | ||
33 | } else if (obj instanceof Collection) { | ||
34 | if (keypath === '*') { | ||
35 | return obj.models; | ||
36 | } | ||
37 | } else { | ||
38 | return; | ||
39 | } | ||
40 | return obj.get(keypath); | ||
41 | }, | ||
42 | set: function set(obj, keypath, value) { | ||
43 | if (obj instanceof Model) { | ||
44 | if (keypath === '*') { | ||
45 | obj.set(value); | ||
46 | } else { | ||
47 | obj.set(keypath, value); | ||
48 | } | ||
49 | } else if (obj instanceof Collection) { | ||
50 | if (keypath === '*') { | ||
51 | obj.set(value); | ||
52 | } else { | ||
53 | var existing = obj.get(keypath); | ||
54 | if (existing) { | ||
55 | obj.set(value, {at: obj.indexOf(existing)}); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | }, | ||
60 | }; | ||
61 | })(Backbone.Model, Backbone.Collection, 'add remove reset sort'); | ||
62 | return adapter; | ||
63 | }); |
1 | define(function(require) { | ||
2 | 'use strict'; | ||
3 | |||
4 | var $ = require('jquery'); | ||
5 | window.jQuery = $; | ||
6 | var RivetsBackboneAdapterBrainfood = require('rivets-backbone-adapter-brainfood'); | ||
7 | var _ = require('underscore'); | ||
8 | var Backbone = require('backbone'); | ||
9 | var rivets = require('rivets'); | ||
10 | require('backbone-validation'); | ||
11 | _.extend(Backbone.Model.prototype, Backbone.Validation.mixin); | ||
12 | //rivets.config.rootInterface = ':'; | ||
13 | /* global console:false */ | ||
14 | |||
15 | describe('RivetsBackboneAdapterBrainfood', function() { | ||
16 | it('returns undefined', function() { | ||
17 | expect(RivetsBackboneAdapterBrainfood).toBeDefined(); | ||
18 | }); | ||
19 | var ContactMech, ContactMechs; | ||
20 | beforeEach(function() { | ||
21 | ContactMech = Backbone.Model.extend({ | ||
22 | defaults: { | ||
23 | contactMechId: '', | ||
24 | contactMechPurposeTypeId: '', | ||
25 | infoString: '', | ||
26 | address1: '', | ||
27 | }, | ||
28 | }); | ||
29 | ContactMechs = Backbone.Collection.extend({ | ||
30 | modelId: function(attrs) { | ||
31 | return attrs.contactMechPurposeTypeId; | ||
32 | }, | ||
33 | }); | ||
34 | }); | ||
35 | var contactMechs, model; | ||
36 | beforeEach(function() { | ||
37 | contactMechs = new ContactMechs([ | ||
38 | new ContactMech({ | ||
39 | contactMechPurposeTypeId: 'PRIMARY_EMAIL', | ||
40 | infoString: 'user@example.com', | ||
41 | }), | ||
42 | new ContactMech({ | ||
43 | contactMechPurposeTypeId: 'PRIMARY_ADDRESS', | ||
44 | address1: '1234 Main St.', | ||
45 | }), | ||
46 | ]); | ||
47 | model = new Backbone.Model({contactMechs: contactMechs, notBackbone: {}}); | ||
48 | }); | ||
49 | function buildTest(path, options) { | ||
50 | it(path, function() { | ||
51 | var inputElement = document.createElement('input'); | ||
52 | inputElement.setAttribute('rv-value', path); | ||
53 | var view = rivets.bind(inputElement, model, { | ||
54 | formatters: { | ||
55 | toJSON: function(value) { | ||
56 | return value.toJSON(); | ||
57 | }, | ||
58 | jsonStringify: { | ||
59 | read: function(value) { | ||
60 | return JSON.stringify(value); | ||
61 | }, | ||
62 | publish: function(value) { | ||
63 | return JSON.parse(value); | ||
64 | }, | ||
65 | }, | ||
66 | }, | ||
67 | }); | ||
68 | function getInputElementValue() { | ||
69 | var rawValue = inputElement.value; | ||
70 | if (options.parse) { | ||
71 | rawValue = options.parse(rawValue); | ||
72 | } | ||
73 | return rawValue; | ||
74 | } | ||
75 | function convertValue(value) { | ||
76 | if (typeof value === 'function') { | ||
77 | return value(); | ||
78 | } else { | ||
79 | return value; | ||
80 | } | ||
81 | } | ||
82 | var value = convertValue(options.value); | ||
83 | expect(getInputElementValue()).toEqual(value); | ||
84 | if (options.get) { | ||
85 | var newValue = convertValue(options.newValue); | ||
86 | inputElement.value = newValue; | ||
87 | $(inputElement).trigger('input').trigger('change'); | ||
88 | expect(options.get()).toEqual(newValue); | ||
89 | if (options.set) { | ||
90 | options.set(value); | ||
91 | expect(getInputElementValue()).toEqual(value); | ||
92 | } | ||
93 | } else if (options.set) { | ||
94 | } | ||
95 | }); | ||
96 | } | ||
97 | buildTest(':contactMechs:PRIMARY_EMAIL:infoString', { | ||
98 | value: 'user@example.com', | ||
99 | newValue: '(user@example.com)', | ||
100 | get: function() { | ||
101 | return contactMechs.get('PRIMARY_EMAIL').get('infoString'); | ||
102 | }, | ||
103 | }); | ||
104 | buildTest(':contactMechs:PRIMARY_ADDRESS:address1', { | ||
105 | value: '1234 Main St.', | ||
106 | newValue: '(1234 Main St.)', | ||
107 | get: function() { | ||
108 | return contactMechs.get('PRIMARY_ADDRESS').get('address1'); | ||
109 | }, | ||
110 | set: function(value) { | ||
111 | contactMechs.get('PRIMARY_ADDRESS').set('address1', value); | ||
112 | }, | ||
113 | }); | ||
114 | buildTest(':contactMechs:PRIMARY_EMAIL:*.infoString', { | ||
115 | value: 'user@example.com', | ||
116 | }); | ||
117 | buildTest(':notBackbone:notValid', { | ||
118 | value: '', | ||
119 | }); | ||
120 | //buildTest(':contactMechs:*.length', '2'); | ||
121 | buildTest(':contactMechs:PRIMARY_EMAIL | toJSON | jsonStringify', { | ||
122 | value: function() { | ||
123 | var primaryEmail = contactMechs.get('PRIMARY_EMAIL'); | ||
124 | return primaryEmail.toJSON(); | ||
125 | }, | ||
126 | parse: function(rawValue) { | ||
127 | return JSON.parse(rawValue); | ||
128 | }, | ||
129 | }); | ||
130 | /* | ||
131 | buildTest(':contactMechs:PRIMARY_EMAIL:* | jsonStringify', { | ||
132 | value: function() { | ||
133 | var primaryEmail = contactMechs.get('PRIMARY_EMAIL'); | ||
134 | return primaryEmail.toJSON(); | ||
135 | }, | ||
136 | newValue: JSON.stringify({ | ||
137 | infoString: 'someone@example.com', | ||
138 | }), | ||
139 | parse: function(rawValue) { | ||
140 | return JSON.parse(rawValue); | ||
141 | }, | ||
142 | get: function() { | ||
143 | var primaryEmail = contactMechs.get('PRIMARY_EMAIL'); | ||
144 | console.log('primaryEmail', JSON.stringify(primaryEmail.toJSON())); | ||
145 | return primaryEmail.toJSON(); | ||
146 | }, | ||
147 | }); | ||
148 | */ | ||
149 | }); | ||
150 | }); |
-
Please register or sign in to post a comment