Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working form_tags #10

Merged
merged 12 commits into from Aug 15, 2017
19 changes: 9 additions & 10 deletions spec/jasper/helpers/forms_spec.cr
Expand Up @@ -35,7 +35,7 @@ describe Jasper::Helpers::Forms do
text_field(:name)
end

result.should eq("<form id=\"myForm\"><input type=\"text\" name=\"name\" id=\"name\"/></form>")
result.should eq("<form id=\"myForm\" method=\"post\"><input type=\"text\" name=\"name\" id=\"name\"/></form>")
end
end

Expand All @@ -47,19 +47,19 @@ describe Jasper::Helpers::Forms do

describe "#select_field" do
it "creates a select_field with two dimension arrays" do
select_field(:age, [[1, "A"],[2, "B"]]).should eq("<select name=\"age\" id=\"age\"><option value=\"1\">A</option><option value=\"2\">B</option></select>")
select_field(:age, [[1, "A"], [2, "B"]]).should eq("<select class=\"age\" id=\"age\" name=\"age\"><option value=\"1\">A</option><option value=\"2\">B</option></select>")
end

it "creates a select_field with array of hashes" do
select_field(:age, [ {:"1" => "A"}, {:"2" => "B"}] ).should eq("<select name=\"age\" id=\"age\"><option value=\"1\">A</option><option value=\"2\">B</option></select>")
select_field(:age, [{:"1" => "A"}, {:"2" => "B"}]).should eq("<select class=\"age\" id=\"age\" name=\"age\"><option value=\"1\">A</option><option value=\"2\">B</option></select>")
end

it "creates a select_field with single dimension array" do
select_field(:age, ["A", "B"]).should eq("<select name=\"age\" id=\"age\"><option>A</option><option>B</option></select>")
select_field(:age, ["A", "B"]).should eq("<select class=\"age\" id=\"age\" name=\"age\"><option value=\"A\">A</option><option value=\"B\">B</option></select>")
end

it "creates a select_field with range" do
select_field(:age, range: 1..5).should eq("<select name=\"age\" id=\"age\"><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option></select>")
select_field(:age, collection: 1..5).should eq("<select class=\"age\" id=\"age\" name=\"age\"><option value=\"1\">1</option><option value=\"2\">2</option><option value=\"3\">3</option><option value=\"4\">4</option><option value=\"5\">5</option></select>")
end
end

Expand All @@ -69,11 +69,11 @@ describe Jasper::Helpers::Forms do
end

it "allows for rows and cols to be specified" do
text_area(:description, "My Great Textarea", cols: 5, rows: 10).should eq("<textarea cols=\"5\" rows=\"10\" name=\"description\" id=\"description\">My Great Textarea</textarea>")
text_area(:description, "My Great Textarea", cols: 5, rows: 10).should eq("<textarea name=\"description\" id=\"description\" cols=\"5\" rows=\"10\">My Great Textarea</textarea>")
end

it "allows for size to be specified" do
text_area(:description, "My Great Textarea", size: "5x10").should eq("<textarea cols=\"5\" rows=\"10\" name=\"description\" id=\"description\">My Great Textarea</textarea>")
text_area(:description, "My Great Textarea", size: "5x10").should eq("<textarea name=\"description\" id=\"description\" cols=\"5\" rows=\"10\">My Great Textarea</textarea>")
end
end

Expand All @@ -87,14 +87,13 @@ describe Jasper::Helpers::Forms do
end

it "creates a submit with value and id parameters" do
submit(:create, id: "my-submit-tag").should eq("<input type=\"submit\" id=\"my-submit-tag\" value=\"Create\"/>")
submit(:create, id: "my-submit-tag").should eq("<input type=\"submit\" value=\"Create\" id=\"my-submit-tag\"/>")
end
end

describe "#check_box" do
it "creates a check_box with only value" do
check_box(:allowed, value: "yes").should eq( "<input type=\"checkbox\" name=\"allowed\" id=\"allowed\" value=\"yes\" checked=\"false\"/>")
check_box(:allowed, checked_value: "yes", unchecked_value: "no").should eq("<input type=\"hidden\" name=\"allowed\" id=\"allowed\" value=\"no\"/><input type=\"checkbox\" name=\"allowed\" id=\"allowed\" value=\"yes\"/>")
end
end

end
31 changes: 31 additions & 0 deletions spec/jasper/helpers/links_spec.cr
@@ -0,0 +1,31 @@
require "../../spec_helper"

describe Jasper::Helpers::Links do
describe "#link_to" do
it "works with body and url provided" do
link_to("Save", "/save").should eq("<a href=\"/save\">Save</a>")
end

it "works with a block" do
result = link_to("/save") do
"<span class=\"label\">Badge</span>"
end

result.should eq("<a href=\"/save\"><span class=\"label\">Badge</span></a>")
end

it "works with a class" do
link_to("Save", "/save", class: "my-link").should eq("<a href=\"/save\" class=\"my-link\">Save</a>")
end
end

describe "#button_to" do
it "works with body and url provided" do
button_to("Save", "/save").should eq("<form action=\"/save\" class=\"button\" method=\"post\"><button type=\"submit\">Save</button></form>")
end

it "changes the method when provided" do
button_to("Save", "/save", :put).should eq("<form action=\"/save\" class=\"button\" method=\"post\"><input type=\"hidden\" name=\"_method\" id=\"_method\" value=\"put\"/><button type=\"submit\">Save</button></form>")
end
end
end
6 changes: 3 additions & 3 deletions spec/jasper/helpers/tags_spec.cr
Expand Up @@ -21,12 +21,12 @@ describe Jasper::Helpers::Tags do

describe "#content" do
it "accepts a content string" do
content(name: :span, options: { :id => "bar" }, content: "Hello").should eq("<span id=\"bar\">Hello</span>")
content(element_name: :span, options: { :id => "bar" }, content: "Hello").should eq("<span id=\"bar\">Hello</span>")
end

it "accepts a block as input" do
result = content(name: :div, options: { :id => "foo" }) do
content(name: :span, options: { :id => "bar" }, content: "Hello")
result = content(element_name: :div, options: { :id => "foo" }) do
content(element_name: :span, options: { :id => "bar" }, content: "Hello")
end

result.should eq("<div id=\"foo\"><span id=\"bar\">Hello</span></div>")
Expand Down
3 changes: 2 additions & 1 deletion spec/spec_helper.cr
Expand Up @@ -2,4 +2,5 @@ require "spec"
require "../src/jasper/helpers/**"

include Jasper::Helpers::Tags
include Jasper::Helpers::Forms
include Jasper::Helpers::Forms
include Jasper::Helpers::Links
157 changes: 47 additions & 110 deletions src/jasper/helpers/forms.cr
@@ -1,181 +1,118 @@
module Jasper::Helpers::Forms

# text_field
def text_field(**options : Object)
options = options.to_h
input_field(type: :text, options: options)
end

def text_field(name : String | Symbol, **options : Object)
options = options.to_h

input_field(type: :text, options: {:name => name, :id => name}.merge(options))
end

def text_field(name : String | Symbol)
input_field(type: :text, options: {:name => name, :id => name})
end

# label
def label(**options : Object)
options = options.to_h

name = options[:name]
content = options[:content]

content(name: :label, content: content, options: {:for => name, :id => "#{name}_label"}.merge(options))
def label(name : String | Symbol, content : String? = nil, **options : Object)
content(element_name: :label, content: (content ? content : name.to_s.capitalize), options: {:for => name, :id => "#{name}_label"}.merge(options.to_h))
end

def label(name : String | Symbol, content : String, **options : Object)
options = options.to_h

content(name: :label, content: content, options: {:for => name, :id => "#{name}_label"}.merge(options))
def label(name : String | Symbol, content : String? = nil)
label(name, content: (content ? content : name.to_s.capitalize), for: name, id: "#{name}_label")
end

def label(name : String | Symbol, content : String)
content(name: :label, content: content, options: {:for => name, :id => "#{name}_label"})
end
# def csrf_field
# hidden_field(name: "authenticity_token", value: "")
# end

# form
def form(**options, &block)
content(name: :form, options: options.to_h) do
yield
def form(method = :post, **options : Object, &block)
options_hash = options.to_h.merge({:method => (method == :get ? :get : :post)})
content(element_name: :form, options: options_hash) do
String.build do |str|
str << hidden_field(name: "_method", value: method) if method != :post
# str << csrf_field
str << yield
end
end
end

# hidden_field
def hidden_field(**options : Object)
options = options.to_h

input_field(type: :hidden, options: options)

def form(method = :post, &block)
form(:post, class: "amber_form", &block)
end

# hidden_field
def hidden_field(name : String | Symbol, **options : Object)
options = options.to_h

input_field(type: :text, options: {:name => name, :id => name}.merge(options))
input_field(type: :hidden, options: {:name => name, :id => name}.merge(options.to_h))
end

def hidden_field(name : String | Symbol)
input_field(type: :hidden, options: {:name => name, :id => name})
hidden_field(name: name, id: name)
end

# select_field
# with collection Array(Array)
def select_field(name : String | Symbol, collection : Array(Array), **options : Object)
content(name: :select, options: options.to_h) do
collection.map{ |item| "<option value=\"#{item[0]}\">#{item[1]}</option>"}.join("")
content(element_name: :select, options: options.to_h.merge({:name => name})) do
collection.map { |item| "<option value=\"#{item[0]}\">#{item[1]}</option>" }.join("")
end
end

# Utilizes method above for when options are not defined and sets class and id.
def select_field(name : String | Symbol, collection : Array(Array))
content(name: :select, options: {:name => name, :id => name}) do
collection.map{ |item| "<option value=\"#{item[0]}\">#{item[1]}</option>"}.join("")
end
select_field(name, collection, class: name, id: name)
end

# with collection Array(Hash)
def select_field(name : String | Symbol, collection : Array(Hash), **options : Object)
content(name: :select, options: options.to_h) do
collection.map{ |hash| "<option value=\"#{hash.first[0]}\">#{hash.first[1]}</option>"}.join("")
end
select_field(name, collection.map(&.first.to_a), **options)
end

def select_field(name : String | Symbol, collection : Array(Hash))
content(name: :select, options: {:name => name, :id => name}) do
collection.map{ |hash| "<option value=\"#{hash.first[0]}\">#{hash.first[1]}</option>"}.join("")
end
select_field(name, collection.map(&.first.to_a), class: name, id: name)
end

# with collection Array
def select_field(name : String | Symbol, collection : Array, **options : Object)
content(name: :select, options: options.to_h) do
collection.map{ |item| "<option>#{item}</option>"}.join("")
end
def select_field(name : String | Symbol, collection : Array | Range, **options : Object)
select_field(name, collection.map { |i| [i.to_s, i.to_s.capitalize] }, **options)
end

def select_field(name : String | Symbol, collection : Array)
content(name: :select, options: {:name => name, :id => name}) do
collection.map{ |item| "<option>#{item}</option>"}.join("")
end
end

# with range Range
def select_field(name : String | Symbol, range : Range, **options : Object)
collection = range.to_a

content(name: :select, options: options.to_h) do
collection.map{ |item| "<option>#{item}</option>"}.join("")
end
end

def select_field(name : String | Symbol, range : Range)
collection = range.to_a

content(name: :select, options: {:name => name, :id => name}) do
collection.map{ |item| "<option>#{item}</option>"}.join("")
end
def select_field(name : String | Symbol, collection : Array | Range)
select_field(name, collection.map { |i| [i.to_s, i.to_s.capitalize] }, class: name, id: name)
end

# text_area
def text_area(name : String | Symbol, content : String, **options : Object)
options_hash = {} of Symbol => String | Symbol | Int32

options_hash.merge!(options.to_h)

if options_hash.has_key?(:size) # cols by rows
options_hash[:cols], options_hash[:rows] = options_hash[:size].to_s.split("x")
options_hash.reject!(:size)
end

options_hash.merge!({:name => name, :id => name})

content(name: :textarea, options: options_hash) do
options_hash = Hash(Symbol, String | Symbol).new.merge(options.to_h)
options_hash[:cols], options_hash[:rows] = options_hash.delete(:size).to_s.split("x") if options.has_key?(:size)
content(element_name: :textarea, options: {:name => name, :id => name}.merge(options_hash)) do
content
end
end

def text_area(name : String | Symbol, content : String)
content(name: :textarea, options: {:name => name, :id => name}) do
content
end
text_area(name, content, id: name)
end

# submit
def submit(**options : Object)
options = options.to_h

input_field(type: :submit, options: options)
input_field(type: :submit, options: options.to_h)
end

def submit(value : String | Symbol, **options : Object)
options = options.to_h

options[:value] = value.to_s.capitalize

input_field(type: :submit, options: options)
input_field(type: :submit, options: {:value => value.to_s.capitalize}.merge(options.to_h))
end

def submit(value = "Save changes")
options = { :value => value.to_s.capitalize }

input_field(type: :submit, options: options)
def submit(value : String | Symbol = "Save changes")
submit(value: value.to_s.capitalize)
end

# check_box
def check_box(name : String | Symbol, value = "1", checked = false, **options : Object)
options = options.to_h

options[:value] = value
options[:checked] = checked

input_field(type: :checkbox, options: options.merge(name: name))
def check_box(name : String | Symbol, checked_value = "1", unchecked_value = "0", **options : Object)
options_hash = Hash(Symbol, String | Symbol).new.merge({:name => name, :id => name, :value => checked_value})
String.build do |str|
str << hidden_field(name, value: unchecked_value)
str << input_field(type: :checkbox, options: options_hash.merge(options.to_h))
end
end

def check_box(name : String | Symbol, value = "1", checked = false)
options = {:name => name, :id => name, :value => value, :checked => checked}

input_field(type: :checkbox, options: options)
def check_box(name : String | Symbol, checked_value = "1", unchecked_value = "0")
check_box(name, checked_value: checked_value, unchecked_value: unchecked_value, id: name)
end

end
37 changes: 37 additions & 0 deletions src/jasper/helpers/links.cr
@@ -0,0 +1,37 @@
module Jasper::Helpers::Links
def link_to(body : String, url : String)
link_html_string(type: :a, body: body, options: {:href => url})
end

def link_to(body : String, url : String, **options : Object)
link_html_string(type: :a, body: body, options: {:href => url}.merge(options.to_h))
end

def link_to(url : String, &block)
link_html_string(type: :a, body: yield, options: {:href => url})
end

def link_to(url : String, **options : Object, &block)
link_html_string(type: :a, body: yield, options: {:href => url}.merge(options.to_h))
end

#TODO: Should just use content.
def link_html_string(type : Symbol, body : String, options : Hash(Symbol, String | Bool | Symbol | Int32))
options = options.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")
options = " #{options}" if !options.blank?

"<#{type}#{options}>#{body}</#{type}>"
end

def button_to(body : String, url : String, method = :post, **options : Object)
form(action: url, class: "button", method: method) do
link_html_string(:button, body, options)
end
end

def button_to(body : String, url : String, method = :post)
form(action: url, class: "button", method: method) do
link_html_string(:button, body, {:type => "submit"})
end
end
end