Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Working form_tags (#10)
* added early link_to helpers.

* added early button_to implementation.

* fixed missing new line.

* fixed some formatting.

* WiP on forms.

* cleaned up form, and added a hidden field with the method type when not a POST.

* little bit cleaner.

* added csrf field inside of form. TODO: add in macro for setting the token.

* Fixed the select_field helpers

* cleaning up

* meh
  • Loading branch information
elorest committed Aug 15, 2017
1 parent 22bfa0a commit 01bd659
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 135 deletions.
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

0 comments on commit 01bd659

Please sign in to comment.