ampersand-dom-bindings
Advanced tools
Comparing version 3.8.0 to 3.9.0
@@ -8,9 +8,14 @@ /*$AMPERSAND_VERSION*/ | ||
function getMatches(el, selector) { | ||
function getMatches(el, selector, firstOnly) { | ||
if (selector === '') return [el]; | ||
var matches = []; | ||
if (matchesSelector(el, selector)) matches.push(el); | ||
return matches.concat(slice.call(el.querySelectorAll(selector))); | ||
if (!selector) return matches; | ||
if (firstOnly) { | ||
if (matchesSelector(el, selector)) return [el]; | ||
return el.querySelector(selector) ? [el.querySelector(selector)] : []; | ||
} else { | ||
if (matchesSelector(el, selector)) matches.push(el); | ||
return matches.concat(slice.call(el.querySelectorAll(selector))); | ||
} | ||
} | ||
function setAttributes(el, attrs) { | ||
@@ -35,7 +40,11 @@ for (var name in attrs) { | ||
var showValue = binding.cases[value]; | ||
var firstMatchOnly = binding.firstMatchOnly; | ||
// hide all the other elements with a different value | ||
for (var item in binding.cases) { | ||
var curValue = binding.cases[item]; | ||
if (value !== item && curValue !== showValue) { | ||
getMatches(el, curValue).forEach(function (match) { | ||
getMatches(el, curValue, firstMatchOnly).forEach(function (match) { | ||
dom.hide(match); | ||
@@ -45,3 +54,3 @@ }); | ||
} | ||
getMatches(el, showValue).forEach(function (match) { | ||
getMatches(el, showValue, firstMatchOnly).forEach(function (match) { | ||
dom.show(match); | ||
@@ -65,2 +74,3 @@ }); | ||
var selector = getSelector(binding); | ||
var firstMatchOnly = binding.firstMatchOnly; | ||
var yes = binding.yes; | ||
@@ -75,3 +85,3 @@ var no = binding.no; | ||
return function (el, value) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
type.call(context, match, value, previousValue); | ||
@@ -83,3 +93,3 @@ }); | ||
return function (el, value) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
dom.text(match, value); | ||
@@ -90,3 +100,3 @@ }); | ||
return function (el, value) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
dom.switchClass(match, previousValue, value); | ||
@@ -100,3 +110,3 @@ }); | ||
var names = makeArray(binding.name); | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
names.forEach(function (name) { | ||
@@ -110,3 +120,3 @@ dom.setAttribute(match, name, value); | ||
return function (el, value) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
if (!value && value !== 0) value = ''; | ||
@@ -126,3 +136,3 @@ // only apply bindings if element is not currently focused | ||
var newClass = value ? yes : no; | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
prevClass.forEach(function (pc) { | ||
@@ -141,3 +151,3 @@ dom.removeClass(match, pc); | ||
value = (invert ? (value ? false : true) : value); | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
name.forEach(function (className) { | ||
@@ -157,3 +167,3 @@ dom[value ? 'addClass' : 'removeClass'](match, className); | ||
var newAttribute = value ? yes : no; | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
prevAttribute.forEach(function (pa) { | ||
@@ -176,3 +186,3 @@ if (pa) { | ||
value = (invert ? (value ? false : true) : value); | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
name.forEach(function (attr) { | ||
@@ -190,6 +200,6 @@ dom[value ? 'addAttribute' : 'removeAttribute'](match, attr); | ||
return function (el, value) { | ||
getMatches(el, yes).forEach(function (match) { | ||
getMatches(el, yes, firstMatchOnly).forEach(function (match) { | ||
dom[value ? 'show' : 'hide'](match, mode); | ||
}); | ||
getMatches(el, no).forEach(function (match) { | ||
getMatches(el, no, firstMatchOnly).forEach(function (match) { | ||
dom[value ? 'hide' : 'show'](match, mode); | ||
@@ -201,3 +211,3 @@ }); | ||
value = (invert ? (value ? false : true) : value); | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
dom[value ? 'show' : 'hide'](match, mode); | ||
@@ -212,3 +222,3 @@ }); | ||
return function (el, value) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
dom.html(match, value); | ||
@@ -222,3 +232,3 @@ }); | ||
for (var item in binding.cases) { | ||
getMatches(el, binding.cases[item]).forEach(function (match) { | ||
getMatches(el, binding.cases[item], firstMatchOnly).forEach(function (match) { | ||
name.forEach(function (className) { | ||
@@ -233,3 +243,3 @@ dom[value === item ? 'addClass' : 'removeClass'](match, className); | ||
return function (el, value, keyName) { | ||
getMatches(el, selector).forEach(function (match) { | ||
getMatches(el, selector, firstMatchOnly).forEach(function (match) { | ||
if (previousValue) { | ||
@@ -236,0 +246,0 @@ removeAttributes(match, previousValue); |
{ | ||
"name": "ampersand-dom-bindings", | ||
"description": "Takes binding declarations and returns key-tree-store of functions that can be used to apply those bindings.", | ||
"version": "3.8.0", | ||
"version": "3.9.0", | ||
"author": "'Henrik Joreteg' <henrik@andyet.net>", | ||
@@ -6,0 +6,0 @@ "browserify": { |
@@ -342,2 +342,30 @@ # ampersand-dom-bindings | ||
## firstMatchOnly | ||
As an option you can add `firstMatchOnly: true` to the binding declaration. It will cause | ||
the selector matcher to grab only the first match. | ||
Useful for cases when a view renders a collection with several elements with the same | ||
class/data-hook. | ||
```js | ||
module.exports = View.extend({ | ||
template: '<div><span data-hook="foo"></span><span data-hook="foo"></span>', | ||
props: { | ||
someText: 'string' | ||
}, | ||
initialize: function(){ | ||
this.someText = 'hello'; | ||
}, | ||
bindings: { | ||
'someText': { | ||
type: 'text', | ||
hook: 'foo', | ||
firstMatchOnly: true | ||
} | ||
} | ||
}); | ||
// will render <div><span data-hook="foo">hello</span><span data-hook="foo"></span></div> | ||
``` | ||
## changelog | ||
@@ -344,0 +372,0 @@ |
23391
257
377