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
describe('Rivets.Binding', function() {
var model, el, view, binding;
var model, el, view, binding, opts;
beforeEach(function() {
rivets.configure({
......@@ -13,7 +13,8 @@ describe('Rivets.Binding', function() {
el = document.createElement('div');
el.setAttribute('data-text', 'obj.name');
view = rivets.bind(el, {obj: {}});
opts = {};
view = rivets.bind(el, {obj: {}}, opts);
binding = view.bindings[0];
model = binding.model;
});
......@@ -103,7 +104,7 @@ describe('Rivets.Binding', function() {
binding.unbind();
expect(binding.binder.unbind).toHaveBeenCalled();
});
describe('with the bypass option set to true', function() {
beforeEach(function() {
binding.options.bypass = true;
......@@ -240,11 +241,11 @@ describe('Rivets.Binding', function() {
it("should apply read binders left to right, and write binders right to left", function() {
rivets.formatters.totally = {
rivets.formatters.totally = {
publish: function(value) { return value + ' totally'; },
read: function(value) { return value + ' totally'; }
};
rivets.formatters.awesome = {
rivets.formatters.awesome = {
publish: function(value) { return value + ' is awesome'; },
read: function(value) { return value + ' is awesome'; }
};
......@@ -268,7 +269,7 @@ describe('Rivets.Binding', function() {
});
it("binders in a chain should be skipped if they're not there", function() {
rivets.formatters.totally = {
rivets.formatters.totally = {
publish: function(value) { return value + ' totally'; },
read: function(value) { return value + ' totally'; }
};
......@@ -310,6 +311,12 @@ describe('Rivets.Binding', function() {
expect(binding.formattedValue('hat')).toBe('model awesome hat');
});
it('uses formatters from the bind options', function() {
opts.formatters = { optAwesome: function(value) { return 'option awesome ' + value; } };
binding.formatters.push("optAwesome");
expect(binding.formattedValue('hat')).toBe('option awesome hat');
});
describe('with a multi-argument formatter string', function() {
beforeEach(function() {
rivets.formatters.awesome = function(value, prefix) {
......
......@@ -40,6 +40,8 @@ class Rivets.Binding
formatter = if @model[id] instanceof Function
@model[id]
else if @options?.bindingOptions?.formatters?[id] instanceof Function
@options.bindingOptions.formatters[id]
else
Rivets.formatters[id]
......@@ -68,7 +70,7 @@ class Rivets.Binding
Rivets.config.adapter.read @model, @keypath
# Publishes the value currently set on the input element back to the model.
publish: =>
publish: =>
value = getInputValue @el
for formatter in @formatters.slice(0).reverse()
......@@ -127,7 +129,7 @@ class Rivets.Binding
class Rivets.View
# The DOM elements and the model objects for binding are passed into the
# constructor.
constructor: (@els, @models) ->
constructor: (@els, @models, @options) ->
@els = [@els] unless (@els.jquery || @els instanceof Array)
@build()
......@@ -166,6 +168,9 @@ class Rivets.View
if bindingRegExp.test attribute.name
options = {}
if @options? and typeof @options is 'object'
options.bindingOptions = @options
type = attribute.name.replace bindingRegExp, ''
pipes = (pipe.trim() for pipe in attribute.value.split '|')
context = (ctx.trim() for ctx in pipes.shift().split '<')
......@@ -411,8 +416,8 @@ factory = (exports) ->
# Binds a set of model objects to a parent DOM element. Returns a Rivets.View
# instance.
exports.bind = (el, models = {}) ->
view = new Rivets.View(el, models)
exports.bind = (el, models = {}, options = {}) ->
view = new Rivets.View(el, models, options)
view.bind()
view
......