Skip to content

Instantly share code, notes, and snippets.

@rgthree
Created August 21, 2013 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgthree/6295699 to your computer and use it in GitHub Desktop.
Save rgthree/6295699 to your computer and use it in GitHub Desktop.
Quick MooVeeStar View/Template system
<!DOCTYPE html>
<html lang="en">
<head>
<title>MooVeeStar Templates</title>
<meta charset="utf-8">
<style>
.app-view > ul > li {margin-bottom:5px; border:1px solid #009;}
.app-view > ul > li [data-bind*="tags"] {display:none;}
.app-view > ul > li.-has-tags {border-color:#F00;}
.app-view > ul > li.-has-tags [data-bind*="tags"] {display:block;}
</style>
</head>
<body>
<script type="text/x-tpl" id="app-view">
<div class="app-view">
<h1 data-bind="title"></h1>
<p data-bind="description"></p>
<hr>
<button data-action="add">Add Item</button>
<button data-action="clear">Clear List</button>
<ul></ul>
</div>
</script>
<script type="text/x-tpl" id="item-view">
<li data-bind="id" data-bind-id="data-id">
<b data-bind="name"></b><br />
<small><a data-bind="url" data-bind-url="text href" target="_blank"></a></small><br />
<small data-bind="tags-label"></small>
<ul data-bind="tags" data-bind-tags="tpl:tag"></ul>
</li>
</script>
<script type="text/x-tpl" id="tag">
<li></li>
</script>
<script src="http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mootools-more/1.4.0.1/mootools-more-yui-compressed.js"></script>
<script src="https://rawgithub.com/rgthree/mooveestar/tests/src/mooveestar.js"></script>
<script>
(function(){
"use strict";
// Quick word generator for our items
var getRandomWord, getRandomHost;
getRandomWord = function(){
return 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tincidunt pellentesque dolor nec convallis. Aenean suscipit facilisis dui. Donec sit amet tincidunt urna. Maecenas at vulputate velit. Aliquam ut quam sit amet urna semper malesuada.'.split(' ').getRandom();
};
getRandomHost = function(){
return 'http://'+('springpad google imdb espn abc nbc cnn lipsum'.split(' ').getRandom())+'.com';
};
var AppView, ItemView;
ItemView = new Class({
Extends: MooVeeStar.View,
template: 'item-view',
// Render is a MooVeeStar.View method that get binds the passed data (or the model.toJSON) to the template
// We can override it to allow us to sanitize the data bound to the template, as well as other things you may want
// to take care of (like changing classnames, attributes, etc.)
render: function(){
var data;
// Create a JSON map of our model
data = this.model.toJSON();
// We have a presentation binding in our template we need to figure out.
data['tags-label'] = this.model.get('tags').length + ' Tag'+(this.model.get('tags').length !== 1 ? 's':'')+':';
// Apply our cleaned presentation map to the template
this.parent(data);
// Additionally, let's say in addition to binding data, we want to toggle a classname to style tagged items differently
this.element.toggleClass('-has-tags', this.model.get('tags').length > 0);
}
});
AppView = new Class({
Extends: MooVeeStar.View,
template: 'app-view',
events:{
'click:relay([data-action])':'onActionClick',
'collection:change':'onCollectionChange'
},
initialize: function(){
// Setup anything we want before we call the parent/super MooVeeStar.View.initialize
// In this case, a collection since we are listening to its events in our events map above
this.collection = new MooVeeStar.Collection();
this.parent.apply(this, arguments); // Apply the passed arguments
// MooVeeStar.View.initialize sets up a bunch of things for us. 'element' is set to the templates
// container. Additionally, there is an 'elements' field that contains the same element as
// 'elements.container' and we can use for organization. We'll put our list there to use later.
this.elements.list = this.element.getFirst('ul');
},
onCollectionChange: function(){
// Here we'll just clear and regenerate the entire list when the collection changes
// Alternatively, we could listen for add/remove and simply change the views affected
var self, frag;
self = this;
this.empty(this.elements.list);
frag = document.createDocumentFragment();
this.collection.getAll().forEach(function(model){
frag.appendChild($(new ItemView(model)));
});
this.elements.list.appendChild(frag);
},
onActionClick: function(e, target){
// Using MooTools relay event delegation, we get the target that matches as the 2nd argument.
// In this case, the element with the [data-action] attr
var action;
action = target.get('data-action');
if(action === 'add'){
// Create a random item
var tags = [];
if(Number.random(0,10) > 4)
for(var i = 0, l = Number.random(0,6); i < l; i++) {tags.include(getRandomWord()); }
this.collection.add({
name: getRandomWord(),
id: String.uniqueID(),
url: getRandomHost(),
tags: tags
});
}else if(action === 'clear'){
this.collection.remove(this.collection.getAll());
}
}
});
var app = new AppView(new MooVeeStar.Model({
title: 'My Awesome App',
description: 'This is an awesome app'
}));
document.body.grab(app);
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment