Created
January 23, 2009 02:02
-
-
Save smith/50841 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<title>Blog In A Browser</title> | |
<style> | |
body { font-family: Helvetica, Arial, sans-serif; margin: 0em; } | |
h1, h2, h3 { font-weight: normal; padding-left: 1em; } | |
textarea, a { display: block; } | |
#tabs { float: left; width: 100%; list-style: none; border-bottom: 1px solid; clear: both; } | |
#tabs li { float: left; } | |
#tabs li a { display: block; width: 80px; padding: 10px; text-decoration: none; text-align: center; border: 1px solid #000000; color: #ffffff; background-color: #000000; margin-bottom: -2px; } | |
#tabs li a.active { color: #000000; background-color: #ffffff; border 1px solid #ffffff; border-bottom: 2px solid #ffffff; } | |
#view, #manage { padding: 1em; } | |
</style> | |
</head> | |
<body> | |
<h1>Blog In A Browser</h1> | |
<ul id="tabs"> | |
<li><a href="#view">View</a></li> | |
<li><a href="#manage">Manage</a></li> | |
</ul> | |
<div id="view"></div> | |
<div id="manage"> | |
<div id="createPost"> | |
<h2>New Post</h2> | |
<label for="createPostTitle">Title</label> | |
<input id="createPostTitle" /> | |
<textarea id="createPostText" rows="10" cols="24"></textarea> | |
<button disabled id="createPostButton">Create Post</button> | |
</div> | |
<div id="managePostsList"></div> | |
</div> | |
<!-- Templates for content --> | |
<div id="templates" style="display:none;"> | |
<div id="viewTemplate"> | |
<h2>#{title}</h2> | |
<div class="date">#{created}</div> | |
<p>#{text}</p> | |
<div class="comments">#{comments}</div> | |
<h3>Leave A Comment</h3> | |
<div class="commentForm"> | |
<label for="commentEmail_#{id}">Email (we will spam you)</label> | |
<input id="commentEmail_#{id}" /> | |
<textarea id="commentText_#{id}" rows="10" cols="24"></textarea> | |
<button id="commentButton_#{id}">Save Comment</button> | |
</div> | |
</div> | |
<div id="commentTemplate"> | |
<p>Comment from #{email} posted at #{created}</p> | |
<p>#{text}</p> | |
</div> | |
<div id="manageTemplate"> | |
<div class="editPost"> | |
<h2>Post #{id} <small>(#{created})</small></h2> | |
<a id="deletePostLink_#{id}" href="#">Delete</a> | |
<label for="editPostTitle_#{id}">Title</label> | |
<input id="editPostTitle_#{id}" value="#{title}" /> | |
<textarea id="editPostText_#{id}" rows="10" cols="24">#{text}</textarea> | |
<button id="editPostButton_#{id}">Save Post</button> | |
</div> | |
</div> | |
</div> | |
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script> | |
<script src="active_record.js"></script> | |
<script> | |
/* | |
* This is a simple example of ActiveRecord using Prototype.js | |
* | |
* @author Nathan L Smith | |
* @date January 22, 2009 | |
*/ | |
document.observe("dom:loaded", function () { | |
// Set up Active Record models | |
ActiveRecord.connect(); | |
ActiveRecord.logging = true; | |
var Comment = ActiveRecord.define("comments", { | |
email: '', | |
text: '', | |
created : new Date() | |
}); | |
var Post = ActiveRecord.define("posts", { | |
title: '', | |
text: '', | |
created : new Date() | |
}); | |
Post.hasMany("comments"); | |
// Functions for behavior | |
/** Very simple tab implementation */ | |
function tabs() { | |
var tabLinks = $$("#tabs li a"); | |
var linkOne = tabLinks[0]; | |
var linkTwo = tabLinks[1]; | |
var tabOne = $("view"); | |
var tabTwo = $("manage"); | |
// Start on tab 2 | |
tabOne.hide(); | |
linkTwo.addClassName("active"); | |
$("tabs").observe("click", function (evt) { | |
evt.stop(); | |
var a = evt.findElement('a'); | |
if (a && a.innerHTML === "View") { | |
tabOne.show(); | |
tabTwo.hide(); | |
} else { | |
tabTwo.show(); | |
tabOne.hide(); | |
} | |
linkOne.toggleClassName("active"); | |
linkTwo.toggleClassName("active"); | |
}); | |
} | |
/** | |
* When the create post form is submitted, a new post is created and saved. | |
*/ | |
function createPost(evt) { | |
var p = new Post({ | |
title : $("createPostTitle").value, | |
text : $("createPostText").value | |
}); | |
p.save(); | |
// Clear the form | |
$("createPostTitle").clear(); | |
$("createPostText").clear(); | |
} | |
/** | |
* Update the post when it is edited | |
*/ | |
function editPost(evt) { | |
var id = getId(evt); | |
var post = Post.first({ id : id }); | |
post.set('title', $("editPostTitle_" + id).value); | |
post.set('text', $("editPostText_" + id).value); | |
post.save(); | |
} | |
/** | |
* Create both the 'view' and 'manage' lists from the data and templates | |
*/ | |
function getList() { | |
var viewTemplate = $("viewTemplate").innerHTML; | |
var manageTemplate = $("manageTemplate").innerHTML; | |
var viewDiv = $("view"); | |
var manageDiv = $("managePostsList"); | |
var posts = Post.find({ all : true, order : "created DESC" }); | |
// Clear existing content | |
viewDiv.update(""); | |
manageDiv.update(""); | |
posts.each(function (p) { | |
var commentTemplate = $("commentTemplate").innerHTML; | |
var comments = ""; | |
// Add comment list | |
// FIXME: This adds comments to the wrong post. | |
p.getCommentList().each(function (c) { | |
comments += commentTemplate.interpolate(c); | |
}); | |
p.comments = comments; | |
// Insert interpolated templates | |
viewDiv.insert(viewTemplate.interpolate(p)); | |
manageDiv.insert(manageTemplate.interpolate(p)); | |
// Observe events on newly inserted buttons | |
$("editPostButton_" + p.id).observe("click", editPost); | |
$("deletePostLink_" + p.id).observe("click", destroyPost); | |
$("commentButton_" + p.id).observe("click", addComment); | |
}); | |
} | |
/** | |
* Remove a post | |
*/ | |
function destroyPost(evt) { | |
var id = getId(evt); | |
var p = Post.first({ id : id }); | |
p.destroy(); | |
} | |
function addComment(evt) { | |
var id = getId(evt); | |
var post = Post.first({ id : id }); | |
post.createComment({ | |
email : $("commentEmail_" + id).value, | |
text : $("commentText_" + id).value | |
}); | |
post.save(); | |
} | |
/** | |
* When an event passed to this function originiated from an element with | |
* an id, return the number N after the _ in xxxx_N. | |
*/ | |
function getId(evt) { | |
return Number((evt.element().id || "").gsub(/.*_/, "")) || 0; | |
} | |
// Handle events | |
$("createPostButton").observe("click", createPost); | |
Post.observe("afterSave", getList); | |
Post.observe("afterDestroy", getList); | |
// Start up | |
tabs(); | |
$("createPostButton").disabled = false; | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment