Skip to content

Instantly share code, notes, and snippets.

@tj
Created July 7, 2011 00:47
Show Gist options
  • Save tj/1068691 to your computer and use it in GitHub Desktop.
Save tj/1068691 to your computer and use it in GitHub Desktop.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script>
window.onload = function(){
function View(name) {
if (!(this instanceof View)) return new View(name);
var html;
if (~name.indexOf('<')) html = name;
else html = $('#' + name + '-template').html();
this.el = $(html);
this.visit(this.el, true);
}
View.prototype.visit = function(el, root){
var self = this
, type = el.get(0).nodeName
, classes = el.attr('class').split(/ +/)
, method = 'visit' + type;
if (this[method] && !root) this[method](el, classes[0]);
el.children().each(function(i, el){
self.visit($(el));
});
};
View.prototype.visitP =
View.prototype.visitTD =
View.prototype.visitSPAN =
View.prototype.visitDIV = function(el, name){
var self = this;
this[name] = function(val){
if (0 == arguments.length) return el.children();
el.empty().append(val.el || val);
return this;
}
};
View.prototype.visitUL = function(el, name){
var self = this;
this.children = [];
this[name] = {
add: function(val){
var li = $('<li>');
self.children.push(val);
el.append(li.append(val.el || val));
return this;
},
list: function(){
return self.children;
},
length: function(){
return this.list().length;
},
each: function(fn){
for (var i = 0, len = self.children.length; i < len; ++i) {
fn(self.children[i], i);
}
return this;
},
map: function(fn){
var ret = []
, name = fn;
if ('string' == typeof fn) {
fn = function(obj){ return obj[name](); };
};
for (var i = 0, len = self.children.length; i < len; ++i) {
ret.push(fn(self.children[i], i));
}
return ret;
}
};
};
View.prototype.visitH1 =
View.prototype.visitH2 =
View.prototype.visitH3 = function(el, name){
var self = this;
this[name] = function(val){
if (0 == arguments.length) return el.text();
el.text(val.el || val);
return this;
};
};
View.prototype.appendTo = function(val){
this.el.appendTo(val.el || val);
return this;
};
var tobi = View('pet')
, loki = View('pet')
, jane = View('pet');
var user = View('user');
tobi.name('Tobi')
.description('is a small beige ferret')
.traits
.add('awesome')
.add('programmer');
loki.name('Loki')
.description('is a fat brown ferret')
.traits
.add('fat')
.add('lazy')
.add('awesome');
jane.name('Jane')
.description('is a small brown ferret')
.traits
.add('lame')
.add('bitchy');
user.name('TJ')
.occupation('software engineer')
.pets
.add(tobi)
.add(loki)
.add(jane);
console.log(user.pets.length());
// => 3
var names = user.pets.map(function(pet){
return pet.name();
});
console.log(names);
// => ['Tobi', 'Loki', 'Jane']
console.log(user.pets.map('name'));
// => ['Tobi', 'Loki', 'Jane']
user.appendTo('body');
}
</script>
</head>
<body>
<script type="text/template" id="pet-template">
<div class="pet">
<h2 class="name">Name</h2>
<p class="description"></p>
<h3>Traits:</h3>
<ul class="traits"></ul>
</div>
</script>
<script type="text/template" id="user-template">
<div class="user">
<h2 class="name">Name</h2>
<table>
<tr>
<td>Occupation:</td>
<td class="occupation"></td>
</tr>
</table>
<ul class="pets"></ul>
</div>
</script>
<script type="text/template" id="dialog-template">
<div class="dialog">
<h2 class="title"></h2>
<a href="#" class="close">Close</a>
<div class="content"></div>
</div>
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment