Skip to content

Commit

Permalink
Add label/1 (without form)
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Mar 17, 2018
1 parent 7541059 commit e3f14d8
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 35 deletions.
55 changes: 47 additions & 8 deletions lib/phoenix_html/form.ex
Expand Up @@ -367,10 +367,14 @@ defmodule Phoenix.HTML.Form do
"""
@spec input_id(t | atom, field) :: String.t()
def input_id(%{id: nil}, _field), do: nil
def input_id(%{id: id}, field) when is_atom(field) or is_binary(field), do: "#{id}_#{field}"

def input_id(name, field) when (is_atom(name) and is_atom(field)) or is_binary(field),
do: "#{name}_#{field}"
def input_id(%{id: id}, field) when is_atom(field) or is_binary(field) do
"#{id}_#{field}"
end

def input_id(name, field) when (is_atom(name) and is_atom(field)) or is_binary(field) do
"#{name}_#{field}"
end

@doc """
Returns an id of a corresponding form field and value attached to it.
Expand Down Expand Up @@ -1263,7 +1267,7 @@ defmodule Phoenix.HTML.Form do
"""
def date_select(form, field, opts \\ []) do
value = Keyword.get(opts, :value, input_value(form, field) || Keyword.get(opts, :default))
builder = Keyword.get(opts, :builder) || &date_builder(&1, opts)
builder = Keyword.get(opts, :builder) || (&date_builder(&1, opts))
builder.(datetime_builder(form, field, date_value(value), nil, opts))
end

Expand All @@ -1290,7 +1294,7 @@ defmodule Phoenix.HTML.Form do
"""
def time_select(form, field, opts \\ []) do
value = Keyword.get(opts, :value, input_value(form, field) || Keyword.get(opts, :default))
builder = Keyword.get(opts, :builder) || &time_builder(&1, opts)
builder = Keyword.get(opts, :builder) || (&time_builder(&1, opts))
builder.(datetime_builder(form, field, nil, time_value(value), opts))
end

Expand Down Expand Up @@ -1401,6 +1405,34 @@ defmodule Phoenix.HTML.Form do
@doc """
Generates a label tag.
Useful when wrapping another input inside a label.
## Examples
label do
radio_button :user, :choice, "Choice"
end
#=> <label class="control-label">...</label>
label class: "control-label" do
radio_button :user, :choice, "Choice"
end
#=> <label class="control-label">...</label>
"""
def label(do_block)

def label(do: block) do
content_tag(:label, block, [])
end

def label(opts, do: block) when is_list(opts) do
content_tag(:label, block, opts)
end

@doc """
Generates a label tag for the given field.
The form should either be a `Phoenix.HTML.Form` emitted
by `form_for` or an atom.
Expand All @@ -1409,6 +1441,8 @@ defmodule Phoenix.HTML.Form do
be overriden if you pass a value to the `for` option.
Text content would be inferred from `field` if not specified.
To wrap a label around an input, see `label/1`.
## Examples
# Assuming form contains a User schema
Expand All @@ -1433,14 +1467,17 @@ defmodule Phoenix.HTML.Form do
"E-mail Address"
end
#=> <label class="control-label" for="user_email">E-mail Address</label>
"""
def label(form, field) do
def label(form, field) when is_atom(field) or is_binary(field) do
label(form, field, humanize(field), [])
end

@doc """
See `label/2`.
"""
def label(form, field, text_or_do_block_or_attributes)

def label(form, field, text) when is_binary(text) do
label(form, field, text, [])
end
Expand All @@ -1456,14 +1493,16 @@ defmodule Phoenix.HTML.Form do
@doc """
See `label/2`.
"""
def label(form, field, text, do_block_or_attributes)

def label(form, field, text, opts) when is_binary(text) and is_list(opts) do
opts = Keyword.put_new(opts, :for, input_id(form, field))
content_tag(:label, text, opts)
end

def label(form, field, opts, do: block) do
def label(form, field, opts, do: block) when is_list(opts) do
opts = Keyword.put_new(opts, :for, input_id(form, field))
content_tag(:label, opts, do: block)
content_tag(:label, block, opts)
end

# Normalize field name to string version
Expand Down
64 changes: 37 additions & 27 deletions test/phoenix_html/form_test.exs
Expand Up @@ -1138,43 +1138,53 @@ defmodule Phoenix.HTML.FormTest do
assert content =~ ~s(Sec: <select class="sec" id="sec" name="search[datetime][second]">)
end

## label/4
describe "label" do
test "with block" do
assert safe_to_string(
label do
"Block"
end
) == ~s(<label>Block</label>)

assert safe_to_string(
label class: "foo" do
"Block"
end
) == ~s(<label class="foo">Block</label>)
end

test "label/4" do
assert safe_to_string(label(:search, :key, "Search")) ==
~s(<label for="search_key">Search</label>)
test "with field but no content" do
assert safe_to_string(label(:search, :key)) == ~s(<label for="search_key">Key</label>)

assert safe_to_string(label(:search, :key, "Search", for: "test_key")) ==
~s(<label for="test_key">Search</label>)
end
assert safe_to_string(label(:search, :key, for: "test_key")) ==
~s(<label for="test_key">Key</label>)

test "label/4 with form" do
assert safe_form(&label(&1, :key, "Search")) == ~s(<label for="search_key">Search</label>)
assert safe_to_string(label(:search, :key, for: "test_key", class: "foo")) ==
~s(<label class="foo" for="test_key">Key</label>)
end

assert safe_form(&label(&1, :key, "Search", for: "test_key")) ==
~s(<label for="test_key">Search</label>)
end
test "with field and inline content" do
assert safe_to_string(label(:search, :key, "Search")) ==
~s(<label for="search_key">Search</label>)

test "label/4 with default value" do
assert safe_to_string(label(:search, :key)) == ~s(<label for="search_key">Key</label>)
assert safe_to_string(label(:search, :key, "Search", for: "test_key")) ==
~s(<label for="test_key">Search</label>)

assert safe_to_string(label(:search, :key, for: "test_key")) ==
~s(<label for="test_key">Key</label>)
end
assert safe_form(&label(&1, :key, "Search")) == ~s(<label for="search_key">Search</label>)

test "label/4 with form and default value" do
assert safe_form(&label(&1, :key)) == ~s(<label for="search_key">Key</label>)
assert safe_form(&label(&1, :key, "Search", for: "test_key")) ==
~s(<label for="test_key">Search</label>)

assert safe_form(&label(&1, :key, for: "test_key")) == ~s(<label for="test_key">Key</label>)
end
assert safe_form(&label(&1, :key, "Search", for: "test_key", class: "foo")) ==
~s(<label class="foo" for="test_key">Search</label>)
end

test "label/4 with a block" do
assert safe_form(&label(&1, :key, [class: "test-label"], do: "Hello")) ==
~s(<label class="test-label" for="search_key">Hello</label>)
end
test "with field and block content" do
assert safe_form(&label(&1, :key, do: "Hello")) == ~s(<label for="search_key">Hello</label>)

test "label/3 with a block" do
assert safe_form(&label(&1, :key, do: "Hello")) == ~s(<label for="search_key">Hello</label>)
assert safe_form(&label(&1, :key, [class: "test-label"], do: "Hello")) ==
~s(<label class="test-label" for="search_key">Hello</label>)
end
end

## input_value/2
Expand Down

0 comments on commit e3f14d8

Please sign in to comment.