-
-
Save pootsbook/cb02dce23509ec4044e43095fb5f6806 to your computer and use it in GitHub Desktop.
Form Representation as Data 3 (select and options)
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
require "scrivener" | |
require "hypertext" | |
require "hypertext/dsl" | |
class RegistrationForm < Scrivener | |
attr_accessor :name | |
attr_accessor :email | |
attr_accessor :message | |
attr_accessor :enquiry | |
def validate | |
assert_present :name | |
assert_present :email | |
assert_present :message | |
assert_email :email | |
end | |
def form | |
{ | |
action: "/contact", | |
method: "post", | |
errors: errors, | |
fields: attributes.keys.map do |attr| | |
{ | |
"label" => { | |
for: "#{attr}_field", | |
text: attr.capitalize.to_s | |
}, | |
tag_mapping[attr] => { | |
type: type_mapping[attr], | |
name: attr, | |
id: "#{attr}_field", | |
value: send(attr), | |
attribute: attr | |
}.tap do |f| | |
f[:text] = send(attr) if tag_mapping[attr] == "textarea" | |
f[:options] = send("#{attr}_options") if tag_mapping[attr] == "select" | |
end | |
} | |
end.push({ | |
"input" => { | |
type: :submit, | |
value: "send" | |
} | |
}) | |
} | |
end | |
def enquiry_options | |
[ | |
{ | |
"option" => { | |
value: "uninterested", | |
text: "I’m just having a look around." | |
} | |
}, | |
{ | |
"option" => { | |
value: "interested", | |
text: "I’d really like to buy something" | |
} | |
} | |
] | |
end | |
def tag_mapping | |
{ | |
name: "input", | |
email: "input", | |
message: "textarea", | |
enquiry: "select" | |
} | |
end | |
def type_mapping | |
{ | |
name: :text, | |
email: :email, | |
} | |
end | |
end | |
class Template < Hypertext::DSL | |
ATTRS = { | |
"input" => %i(type name id value), | |
"label" => %i(for), | |
"textarea" => %i(id name rows cols), | |
"select" => %i(id name), | |
"option" => %i(value) | |
} | |
def initialize(site) | |
site.each_pair do |key, val| | |
instance_variable_set(sprintf("@%s", key), val) | |
end | |
@ht = Hypertext.new | |
render_form @form | |
end | |
def render(string) | |
instance_eval string | |
end | |
def render_form(f) | |
form f.slice(:action, :method) do | |
f[:fields].each do |ff| | |
render_field(ff) | |
end | |
end | |
end | |
def render_field(f) | |
f.each do |tag, att| | |
if att[:text] | |
public_send tag, att.slice(*ATTRS.fetch(tag)) do | |
text att[:text] | |
end | |
elsif att.has_key? :options | |
public_send tag, att.slice(*ATTRS.fetch(tag)) do | |
att[:options].each do |option| | |
render_field(option) | |
end | |
end | |
else | |
public_send tag, att.slice(*ATTRS.fetch(tag)) | |
end | |
end | |
end | |
end | |
validator = RegistrationForm.new(message: "Hello, World!") | |
template = Template.new(form: validator.form) | |
puts template.to_s | |
+ <form action="/contact" method="post"> | |
+ <label for="email_field"> | |
+ </label> | |
+ <input type="email" name="email" id="email_field" value="" /> | |
+ <label for="name_field"> | |
+ Name | |
+ </label> | |
+ <input type="text" name="name" id="name_field" value="" /> | |
+ <label for="message_field"> | |
+ Message | |
+ </label> | |
+ <textarea id="message_field" name="message"> | |
+ Hello, World! | |
+ </textarea> | |
+ <label for="enquiry_field"> | |
+ Enquiry | |
+ </label> | |
+ <select id="enquiry_field" name="enquiry"> | |
+ <option value="uninterested"> | |
+ I’m just having a look around. | |
+ </option> | |
+ <option value="interested"> | |
+ I’d really like to buy something | |
+ </option> | |
+ </select> | |
+ <input type="submit" value="send" /> | |
+ </form> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment