Created
September 24, 2010 19:05
-
-
Save tj/595859 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
:model | |
form(user) | |
p | |
field(name) | |
p | |
field(email) | |
p | |
field(summary, as: 'textarea') | |
buttons |
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
form(method="post", id="user-model-form") | |
p | |
input(type="text", name="user[name]", value=user.name) | |
- if (user.errors.name) | |
p.error= user.errors.name | |
p | |
input(type="text", name="user[email]", value=user.email) | |
- if (user.errors.email) | |
p.error= user.errors.email | |
p.buttons | |
- if (user.isNew) | |
input(type="submit", value="Save") | |
- else | |
input(type="submit", value="Update") |
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
<form id="user-model-form" method="post"> | |
<p> | |
<label for="user[name]">Name:</label> | |
<input type="text" value="Tobi" name="user[name]"/></p> | |
<p> | |
<label for="user[email]">Email:</label> | |
<input type="text" value="vision-media.ca" name="user[email]"/> | |
<p class="error">Invalid email</p></p> | |
<p> | |
<label for="user[summary]">Summary:</label> | |
<textarea name="user[summary]">Tobi is a ferret, he is supes cool.</textarea></p> | |
<p class="buttons"> | |
<input type="submit" value="Update"/></p> | |
<input type="hidden" name="_method" value="put"/></form> |
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
<% form_for(@user) do |f| %> | |
<p> | |
<%= f.label :name %> | |
<%= f.text_field :name %> | |
</p> | |
<p> | |
<%= f.label :name %> | |
<%= f.text_field :email %> | |
</p> | |
<p> | |
<%= f.label :summary %> | |
<%= f.text_area :summary %> | |
</p> | |
<p class="buttons"> | |
<%= f.submit %> | |
</p> | |
<% end %> |
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
// First define a filter named "model", | |
// which accepts a node (a Block node), | |
// and the parent Compiler | |
jade.filters.model = function(block, compiler){ | |
// pass the block / previous options to our new Visitor | |
return new Visitor(block, compiler.options).compile(); | |
}; | |
function Visitor(node, options) { | |
// "super" to the Compiler() constructor | |
Compiler.call(this, node, options); | |
} | |
// Inherit from Compiler | |
Visitor.prototype.__proto__ = Compiler.prototype; | |
// Overwrite visitTag method | |
Visitor.prototype.visitTag = function(node){ | |
var parent = Compiler.prototype.visitTag; | |
switch (node.name) { | |
case 'form': | |
// Store the record variable name, | |
// in our case "user" is our first | |
// anonymous attribute | |
this.record = node.attrs[0].name; | |
// remove the record name attribute | |
node.removeAttribute(this.record); | |
node.setAttribute('id', '"' + this.record + '-model-form"'); | |
node.setAttribute('method', '"post"'); | |
// when the record is not new, we probably want a _method hidden | |
// field to tell our server to use PUT with frameworks like Express | |
var code = new nodes.Code('if (!' + this.record + '.new)'); | |
var put = new nodes.Tag('input'); | |
put.setAttribute('type', '"hidden"'); | |
put.setAttribute('name', '"_method"'); | |
put.setAttribute('value', '"put"'); | |
code.block = new nodes.Block(put); | |
node.block.push(code); | |
parent.call(this, node); | |
break; | |
case 'field': | |
// Grab "as" attribute, defaulting it to "text" | |
// perform some surgery on it since it IS literal JavaScript | |
var name = node.attrs[0].name, | |
as = (node.getAttribute('as') || 'text').trim().replace(/'/g, ''), | |
capitalized = name.charAt(0).toUpperCase() + name.slice(1); | |
// Field label | |
var label = new nodes.Tag('label'); | |
label.setAttribute('for', '"' + this.record + '[' + name + ']"'); | |
label.block.push(new nodes.Text(capitalized + ':')); | |
parent.call(this, label); | |
// Field input | |
switch (as) { | |
case 'textarea': | |
var code = new nodes.Code(this.record + '.' + name, true, true); | |
node = new nodes.Tag('textarea'); | |
node.block.push(code); | |
break; | |
case 'text': | |
node = new nodes.Tag('input'); | |
node.setAttribute('type', '"text"'); | |
node.setAttribute('value', this.record + '.' + name); | |
} | |
node.setAttribute('name', '"' + this.record + '[' + name + ']"'); | |
parent.call(this, node); | |
// Potential error tag | |
var err = this.record + '.errors.' + name; | |
node = new nodes.Code('if (' + err + ')'); | |
node.block = new nodes.Block; | |
var p = new nodes.Tag('p', new nodes.Block(new nodes.Code(err, true, true))); | |
node.block.push(p); | |
Visitor.prototype.visitCode.call(this, node); | |
break; | |
case 'buttons': | |
// Generate context sensative buttons which | |
// check the record's state. | |
node = new nodes.Tag('input'); | |
node.setAttribute('type', '"submit"'); | |
node.setAttribute('value', this.record + '.new ? "Save" : "Update"'); | |
var p = new nodes.Tag('p', new nodes.Block(node)); | |
p.setAttribute('class', '"buttons"'); | |
parent.call(this, p); | |
break; | |
default: | |
parent.call(this, node); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment