$('ul#todos li').live('click', function(e) {
if ($(e.target).is('.readonly')) { readonly(); }
else {
if ($(e.target).is('.warning') { warning(); }
original();
}
});
$('ul#todos li').entwine({
onclick: function(){ original(); }
});
$('ul#todos li.readonly').entwine({
onclick: function(){ readonly(); }
});
$('ul#todos li.warning').entwine({
onclick: function(){ warning(); this._super(); }
});
class Memo extends DataObject {
static $db = array(
'Title' => 'Varchar',
'Tags' => 'Varchar'
);
}
class TextMemo extends Memo {
static $db = array(
'Note' => 'Text'
);
}
class MemoAdmin extends ModelAdmin {
public static $managed_models = array('Memo');
public static $url_segment = 'memo-admin';
public static $menu_title = 'Memo Admin';
}
class Memo extends DataObject {
use RESTItem;
static $default_fields = array('ID', 'Title', 'Tags');
...
}
class Memo_Handler extends RESTItem_Handler {
static $allowed_actions = array('GET');
function GET($request) { return $this->respondWith('*'); }
}
class Memos extends ViewableData {
use RESTCollection;
function getItems() { return Memo::get()->toArray(); }
function getItem($id) { return Memo::get()->byID($id); }
}
class Memos_handler extends RESTCollection_Handler {
static $allowed_actions = array('GET');
function GET($request) {
return $this->respondWith('Items.*');
}
}
<Code removed for being too long and boring>
var Memo = Backbone.Model.extend({
idAttribute: 'ID',
urlRoot: 'rest/Memo',
defaults: {'$type': 'Memo'}
});
var Memos = Backbone.Collection.extend({
model: Memo,
url: 'rest/Memo'
});
var converter = new Showdown.converter();
var TextMemo = Memo.extend({
defaults: {'$type': 'TextMemo'},
getNoteHtml: function(){
return converter.makeHtml(this.get('Note'));
}
});
<div id="scroll">
<ul id="memos"></ul>
</div>
$('#memos').entwine({
onadd: function(){
this.setMemos(new Memos());
},
Memos: null,
setMemos: function(memos){
this._super(memos);
memos.on('reset', function(){ this.render(); }, this);
memos.fetch();
}
render: function(){
/* Create <li class="memo"> elements, one per memo */
}
});
$('.memo').entwine({
Memo: null,
Tmplt: '<h1 data-attr="Title"><%= get("Title") %></h1>',
render: function(){
this.html(_.template(this.getTmplt(), this.getMemo()));
}
});
$('.memo.textmemo').entwine({
getTmplt: function() {
return this._super() +
'<div data-attr="Note"><%= getNoteHtml() %></div>';
}
});
$('.memo *').entwine({
getMemo: function() {
return this.parents('.memo').getMemo();
}
});
$('.memo > *').entwine({
onclick: function(){
var input = this.getInput();
if (input) input.insertAfter(this);
}
});
$('.memo > [data-attr]').entwine({
getInput: function(){
return $('<input type="text" />');
}
});
$('.memo > [data-attr=Note]').entwine({
getInput: function(){
return $('<textarea></textarea>');
}
});
$('.memo input, .memo textarea').entwine({
inpVal: function(v) { return this.val(v); },
onadd: function() {
this.inpVal(this.getMemo().get(this.getProperty()));
},
onfocusout: function(){
this.getMemo().set(this.getProperty(), this.inpVal());
this.getMemo().save();
this.remove();
}
});
$('#memos .memo textarea').entwine({
inpVal: function(v) { return this.text(v); }
});