f1d4a2c9 by Michael Richards

Implement wildcard attribute bindings so that it's possible to bind to any arbitrary attribute.

1 parent d1af20dd
......@@ -24,7 +24,7 @@ No contrived example here yet, but the `rivets` module is simple. It exposes a s
- **data-unchecked**: two-way inverse binding that sets the node's checked state.
- **data-selected**: two-way binding that sets the node's selected state.
- **data-unselected**: two-way inverse binding that sets the node's checked state.
- **data-[attribute]**: one-way binding that sets the node's attribute value (currently only for a few select attributes).
- **data-[attribute]**: one-way binding that sets the node's attribute value.
## Adapters
......
......@@ -3,11 +3,13 @@
var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
window.rivets = (function() {
var attr, bidirectionalBindings, bindableAttributes, bindings, getInputValue, registerBinding, setAttribute, _fn, _i, _len;
var attributeBinding, bidirectionalBindings, bindings, getInputValue, registerBinding, setAttribute;
registerBinding = function(el, adapter, type, context, keypath) {
bindings[type](el, adapter.read(context, keypath));
var bind;
bind = bindings[type] || attributeBinding(type);
bind(el, adapter.read(context, keypath));
adapter.subscribe(context, keypath, function(value) {
return bindings[type](el, value);
return bind(el, value);
});
if (__indexOf.call(bidirectionalBindings, type) >= 0) {
return $(el).bind('change', function() {
......@@ -76,42 +78,35 @@
return $(el).val(value);
}
};
bidirectionalBindings = ['value', 'checked', 'unchecked', 'selected', 'unselected'];
bindableAttributes = ['id', 'class', 'name', 'src', 'href', 'alt', 'title', 'placeholder'];
_fn = function(attr) {
return bindings[attr] = function(el, value) {
attributeBinding = function(attr) {
return function(el, value) {
return setAttribute(el, attr, value);
};
};
for (_i = 0, _len = bindableAttributes.length; _i < _len; _i++) {
attr = bindableAttributes[_i];
_fn(attr);
}
bidirectionalBindings = ['value', 'checked', 'unchecked', 'selected', 'unselected'];
return {
bind: function(el, adapter, contexts) {
if (contexts == null) {
contexts = {};
}
return $(el).add($('*', el)).each(function() {
var nodeMap, target, _j, _ref, _results;
var nodeMap, target, _i, _ref, _results;
target = this;
nodeMap = target.attributes;
if (nodeMap.length > 0) {
return (function() {
_results = [];
for (var _j = 0, _ref = nodeMap.length - 1; 0 <= _ref ? _j <= _ref : _j >= _ref; 0 <= _ref ? _j++ : _j--){ _results.push(_j); }
for (var _i = 0, _ref = nodeMap.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this).forEach(function(n) {
var context, keypath, node, path, type;
node = nodeMap[n];
if (/^data-/.test(node.name)) {
type = node.name.replace('data-', '');
if (type in bindings) {
path = node.value.split('.');
context = path.shift();
keypath = path.join('.');
return registerBinding($(target), adapter, type, contexts[context], keypath);
}
path = node.value.split('.');
context = path.shift();
keypath = path.join('.');
return registerBinding($(target), adapter, type, contexts[context], keypath);
}
});
}
......
......@@ -5,14 +5,15 @@
window.rivets = do ->
registerBinding = (el, adapter, type, context, keypath) ->
bindings[type] el, adapter.read(context, keypath)
bind = bindings[type] || attributeBinding type
bind el, adapter.read context, keypath
adapter.subscribe context, keypath, (value) ->
bindings[type] el, value
bind el, value
if type in bidirectionalBindings
$(el).bind 'change', ->
adapter.publish context, keypath, getInputValue(this)
adapter.publish context, keypath, getInputValue this
setAttribute = (el, attr, value, mirrored=false) ->
if value
......@@ -47,13 +48,11 @@ window.rivets = do ->
value: (el, value) ->
$(el).val value
bidirectionalBindings = ['value', 'checked', 'unchecked', 'selected', 'unselected']
bindableAttributes = ['id', 'class', 'name', 'src', 'href', 'alt', 'title', 'placeholder']
attributeBinding = (attr) ->
(el, value) ->
setAttribute el, attr, value
for attr in bindableAttributes
do (attr) ->
bindings[attr] = (el, value) ->
setAttribute el, attr, value
bidirectionalBindings = ['value', 'checked', 'unchecked', 'selected', 'unselected']
bind: (el, adapter, contexts={}) ->
$(el).add($('*', el)).each ->
......@@ -66,9 +65,7 @@ window.rivets = do ->
if /^data-/.test node.name
type = node.name.replace 'data-', ''
if type of bindings
path = node.value.split '.'
context = path.shift()
keypath = path.join '.'
registerBinding $(target), adapter, type, contexts[context], keypath
path = node.value.split '.'
context = path.shift()
keypath = path.join '.'
registerBinding $(target), adapter, type, contexts[context], keypath
......