Skip to content

Instantly share code, notes, and snippets.

@dkordik
Last active December 21, 2015 11:18
Show Gist options
  • Save dkordik/6297484 to your computer and use it in GitHub Desktop.
Save dkordik/6297484 to your computer and use it in GitHub Desktop.
can.js mustache declarative bindings for value, visible, class, and click. working jsfiddle: http://jsfiddle.net/dkordik/ZjZ8s/13/
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.js"></script>
<script src="http://canjs.us/release/latest/can.jquery.js"></script>
<script src="http://canjs.com/release/latest/can.view.mustache.js"></script>
<script src="can.mustache.defaultBindings.js"></script>
<script id="template" type="text/mustache">
<h1>Knockout-esque <code>value</code> binding</h1>
{{#newAnimal}}
<input type="text" {{value name }} placeholder="Name of animal">
<input type="text" {{value favoriteFood}} placeholder="Favorite food">
<button {{click control.addAnimal}}>Add animal</button>
{{/newAnimal}}
<h1><code>visible</code>, <code>class</code>, <code>click</code> bindings</h1>
{{#animals}}
<div class="animal" {{visible isAlive}} {{class "selected" selected}} {{click toggleSelection }}>
<strong>{{name}}</strong> eats <strong>{{favoriteFood}}</strong>
<button {{click toggleAlive }}>hide</button>
</div>
{{/animals}}
</script>
<div id="container"></div>
<script src="app.js">
Animal = can.Model({
name: "",
favoriteFood: "",
isAlive: true,
selected: false
}, {
toggleSelection: function () {
this.attr("selected", !this.selected);
},
toggleAlive: function () {
this.attr("isAlive", !this.isAlive);
},
clear: function () {
this.attr("name", "");
this.attr("favoriteFood", "");
this.attr("isAlive", true);
this.attr("selected", false);
}
});
AnimalListControl = can.Control({
defaults: {
animals: new Animal.List([])
}
},{
init: function () {
this.element.html(can.view("#template", {
newAnimal: new Animal({isAlive: true}),
animals: this.options.animals,
control: this
}));
},
addAnimal: function (animal) {
this.options.animals.push(new Animal(animal.attr()));
animal.clear();
}
})
new AnimalListControl("#container", {
animals: new Animal.List([
{ name: "dog", favoriteFood: "bacon" , isAlive: true },
{ name: "cat", favoriteFood: "tuna", isAlive: true, selected: true },
{ name: "bird", favoriteFood: "sunflower seeds", isAlive: true }
])
});
var Value = can.Control({
init: function(){
this.set()
},
"{value} change": "set",
set: function(){
this.element.val(this.options.value())
},
"change": function(){
this.options.value(this.element.val())
},
"keydown": function(){
//setTimeout? yeah, that's how knockout does it in afterkeydown, too.
//for the uninitiated: normally, the latest el value isn't available from keydown.
//some may say "hey dummy, just use keyup!" but if we want DAT SPEED, keydown's the only way.
//if you want to see this in action, remove the setTimeout and watch.
setTimeout(can.proxy(function () {
this.options.value(this.element.val())
}, this), 0)
}
});
can.Mustache.registerHelper("value", function (obs) {
return function (el) {
new Value(el, { value: obs })
}
});
var Visible = can.Control({
init: function(){
this.set()
},
"{value} change": "set",
set: function(){
if (this.options.value() === true) {
this.element.show();
} else {
this.element.hide();
}
}
});
can.Mustache.registerHelper("visible", function (obs) {
return function (el) {
new Visible(el, { value: obs })
}
});
var CSSClass = can.Control({
init: function(){
this.set()
},
"{value} change": "set",
set: function(){
if (this.options.value() == true) {
this.element.addClass(this.options.className);
} else {
this.element.removeClass(this.options.className);
}
}
});
can.Mustache.registerHelper("class", function (className, obs) {
return function (el) {
new CSSClass(el, { className: className, value: obs })
}
});
var Click = can.Control({
"click": function(){
this.options.clickFunc(this.options.model);
}
});
can.Mustache.registerHelper("click", function (clickFunc) {
var context = this;
return function (el) {
new Click(el, { clickFunc: clickFunc, model: context })
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment