Skip to content

Instantly share code, notes, and snippets.

@nathggns
Last active December 20, 2015 09:59
Show Gist options
  • Save nathggns/6112138 to your computer and use it in GitHub Desktop.
Save nathggns/6112138 to your computer and use it in GitHub Desktop.
Ideal Templating
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Templating</title>
</head>
<body>
<div id="Item" class="template">
<li class="item">
<input type="text" class="item-edit">
<span class="item-text"></span>
<label>
<input type="checkbox" class="item-checked">
Checked
</label>
<label>
<input type="checkbox" class="item-editing">
Editing
</label>
<button class="remove-item">Remove</button>
</li>
</div>
<div id="Items" class="template">
<ul class="items"></ul>
<button class="add-item">
Add
</button>
</div>
<div class="items-container">
</div>
<script>
// Defines a reusable Item model.
var Item = function(text) {
this.checked = false;
this.editing = false;
this.text = text || '';
};
Item.prototype.name = function() {
// this.index is a magic property made via the View object
return 'data[Items][' + this.index + ']'
};
Item.prototype.remove = function() {
// this.index is a magic property made via the View object
this.parent.items.splice(this.index, 1);
};
// Defines a reusable Items model
var Items = function() {
this.items = [];
};
Items.prototype.add = function() {
this.items.push(new Item());
};
// Now we introduce a View object, which does the
// "logic" for Item the View.
// As we want to keep logic out of the HTML
var ItemView = new View({
template: '#Item',
bindings: {
'.item-checked': {
name: '{{ name }}[checked]', // Embeds the checked property into the name attribute
checked: '{{ checked }}' // Embeds the result of the checked property, toggles attr on /off
},
'.item-editing': {
name: '{{ name}}[editing]', // Embeds the editing property into the name attribute
checked: '{{ editing }}' // Embeds the result of the editing property, toggles attr on / off
},
'.item-edit': {
'style': { // Can do parts of properties, toggle on / off parts
'display: none;': '{{ editing }}'
},
'value': '{{ text }}', // Value of the element, embeds the Item.text property
'name': '{{ name }}[text]' // Name of the element, embeds the result of the Item.name method
},
'.item-text': {
'text': '{{ text }}' // Text of the element, makes it equal to the Item.text property
}
},
eventBindings: {
'.item-delete': {
'click': 'remove' // Refers to the Item.add property, called on click
}
}
});
var ItemsView = new View({
model: Items,
template: '#Items'
bindings: {
'.items': {
property: 'items',
view: ItemView
}
},
eventBindings: {
'.add-item': {
'click': 'add' // Refers to the Items.add method
}
}
});
ItemsView.bindTo('.items-container'); // Render to element
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment