23246382 by Michael Richards

Merge pull request #134 from zowens/master

Allow formatters to be passed in as an option to rivets.bind
2 parents 7311b968 a022aef3
1 describe('Rivets.Binding', function() { 1 describe('Rivets.Binding', function() {
2 var model, el, view, binding; 2 var model, el, view, binding, opts;
3 3
4 beforeEach(function() { 4 beforeEach(function() {
5 rivets.configure({ 5 rivets.configure({
...@@ -13,7 +13,8 @@ describe('Rivets.Binding', function() { ...@@ -13,7 +13,8 @@ describe('Rivets.Binding', function() {
13 13
14 el = document.createElement('div'); 14 el = document.createElement('div');
15 el.setAttribute('data-text', 'obj.name'); 15 el.setAttribute('data-text', 'obj.name');
16 view = rivets.bind(el, {obj: {}}); 16 opts = {};
17 view = rivets.bind(el, {obj: {}}, opts);
17 binding = view.bindings[0]; 18 binding = view.bindings[0];
18 model = binding.model; 19 model = binding.model;
19 }); 20 });
...@@ -103,7 +104,7 @@ describe('Rivets.Binding', function() { ...@@ -103,7 +104,7 @@ describe('Rivets.Binding', function() {
103 binding.unbind(); 104 binding.unbind();
104 expect(binding.binder.unbind).toHaveBeenCalled(); 105 expect(binding.binder.unbind).toHaveBeenCalled();
105 }); 106 });
106 107
107 describe('with the bypass option set to true', function() { 108 describe('with the bypass option set to true', function() {
108 beforeEach(function() { 109 beforeEach(function() {
109 binding.options.bypass = true; 110 binding.options.bypass = true;
...@@ -240,11 +241,11 @@ describe('Rivets.Binding', function() { ...@@ -240,11 +241,11 @@ describe('Rivets.Binding', function() {
240 241
241 242
242 it("should apply read binders left to right, and write binders right to left", function() { 243 it("should apply read binders left to right, and write binders right to left", function() {
243 rivets.formatters.totally = { 244 rivets.formatters.totally = {
244 publish: function(value) { return value + ' totally'; }, 245 publish: function(value) { return value + ' totally'; },
245 read: function(value) { return value + ' totally'; } 246 read: function(value) { return value + ' totally'; }
246 }; 247 };
247 rivets.formatters.awesome = { 248 rivets.formatters.awesome = {
248 publish: function(value) { return value + ' is awesome'; }, 249 publish: function(value) { return value + ' is awesome'; },
249 read: function(value) { return value + ' is awesome'; } 250 read: function(value) { return value + ' is awesome'; }
250 }; 251 };
...@@ -268,7 +269,7 @@ describe('Rivets.Binding', function() { ...@@ -268,7 +269,7 @@ describe('Rivets.Binding', function() {
268 }); 269 });
269 270
270 it("binders in a chain should be skipped if they're not there", function() { 271 it("binders in a chain should be skipped if they're not there", function() {
271 rivets.formatters.totally = { 272 rivets.formatters.totally = {
272 publish: function(value) { return value + ' totally'; }, 273 publish: function(value) { return value + ' totally'; },
273 read: function(value) { return value + ' totally'; } 274 read: function(value) { return value + ' totally'; }
274 }; 275 };
...@@ -310,6 +311,12 @@ describe('Rivets.Binding', function() { ...@@ -310,6 +311,12 @@ describe('Rivets.Binding', function() {
310 expect(binding.formattedValue('hat')).toBe('model awesome hat'); 311 expect(binding.formattedValue('hat')).toBe('model awesome hat');
311 }); 312 });
312 313
314 it('uses formatters from the bind options', function() {
315 opts.formatters = { optAwesome: function(value) { return 'option awesome ' + value; } };
316 binding.formatters.push("optAwesome");
317 expect(binding.formattedValue('hat')).toBe('option awesome hat');
318 });
319
313 describe('with a multi-argument formatter string', function() { 320 describe('with a multi-argument formatter string', function() {
314 beforeEach(function() { 321 beforeEach(function() {
315 rivets.formatters.awesome = function(value, prefix) { 322 rivets.formatters.awesome = function(value, prefix) {
......
...@@ -40,6 +40,8 @@ class Rivets.Binding ...@@ -40,6 +40,8 @@ class Rivets.Binding
40 40
41 formatter = if @model[id] instanceof Function 41 formatter = if @model[id] instanceof Function
42 @model[id] 42 @model[id]
43 else if @options?.bindingOptions?.formatters?[id] instanceof Function
44 @options.bindingOptions.formatters[id]
43 else 45 else
44 Rivets.formatters[id] 46 Rivets.formatters[id]
45 47
...@@ -68,7 +70,7 @@ class Rivets.Binding ...@@ -68,7 +70,7 @@ class Rivets.Binding
68 Rivets.config.adapter.read @model, @keypath 70 Rivets.config.adapter.read @model, @keypath
69 71
70 # Publishes the value currently set on the input element back to the model. 72 # Publishes the value currently set on the input element back to the model.
71 publish: => 73 publish: =>
72 value = getInputValue @el 74 value = getInputValue @el
73 75
74 for formatter in @formatters.slice(0).reverse() 76 for formatter in @formatters.slice(0).reverse()
...@@ -127,7 +129,7 @@ class Rivets.Binding ...@@ -127,7 +129,7 @@ class Rivets.Binding
127 class Rivets.View 129 class Rivets.View
128 # The DOM elements and the model objects for binding are passed into the 130 # The DOM elements and the model objects for binding are passed into the
129 # constructor. 131 # constructor.
130 constructor: (@els, @models) -> 132 constructor: (@els, @models, @options) ->
131 @els = [@els] unless (@els.jquery || @els instanceof Array) 133 @els = [@els] unless (@els.jquery || @els instanceof Array)
132 @build() 134 @build()
133 135
...@@ -166,6 +168,9 @@ class Rivets.View ...@@ -166,6 +168,9 @@ class Rivets.View
166 if bindingRegExp.test attribute.name 168 if bindingRegExp.test attribute.name
167 options = {} 169 options = {}
168 170
171 if @options? and typeof @options is 'object'
172 options.bindingOptions = @options
173
169 type = attribute.name.replace bindingRegExp, '' 174 type = attribute.name.replace bindingRegExp, ''
170 pipes = (pipe.trim() for pipe in attribute.value.split '|') 175 pipes = (pipe.trim() for pipe in attribute.value.split '|')
171 context = (ctx.trim() for ctx in pipes.shift().split '<') 176 context = (ctx.trim() for ctx in pipes.shift().split '<')
...@@ -411,8 +416,8 @@ factory = (exports) -> ...@@ -411,8 +416,8 @@ factory = (exports) ->
411 416
412 # Binds a set of model objects to a parent DOM element. Returns a Rivets.View 417 # Binds a set of model objects to a parent DOM element. Returns a Rivets.View
413 # instance. 418 # instance.
414 exports.bind = (el, models = {}) -> 419 exports.bind = (el, models = {}, options = {}) ->
415 view = new Rivets.View(el, models) 420 view = new Rivets.View(el, models, options)
416 view.bind() 421 view.bind()
417 view 422 view
418 423
......