formal 0.0.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +12 -48
- data/Rakefile +3 -5
- data/formal.gemspec +2 -1
- data/lib/formal.rb +2 -39
- data/lib/formal/form_builder.rb +42 -0
- data/lib/formal/version.rb +1 -1
- data/lib/rails/generators/formal/install/install_generator.rb +15 -0
- data/lib/rails/generators/formal/install/templates/initializer.rb +1 -0
- data/spec/fixtures/locales/en.yml +7 -0
- data/spec/formal_spec.rb +93 -33
- data/spec/spec_helper.rb +12 -12
- metadata +28 -14
- data/.rspec +0 -1
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d21e6d5dc193f7af782330e988253ee219c397a2
|
4
|
+
data.tar.gz: 88b86cdb027538447a1f5de3a9d5e6904dc833f3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 28b44ea81f3b987682da5b265d7a09577d0c7bb0a270b1f799761672e01400047d2391fe6eef4affd7b1b461edce48c3ee400012e807052b5f57c6628efff993
|
7
|
+
data.tar.gz: ebd8ca726289c489b8f2581e8ec3e8f82061fd41a544dc001fd3b71f56d2b01a32741bdff2b3197cd263b23f76ceba948e92953f0835ad151d03be3f44560dc8
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Formal
|
2
2
|
|
3
|
+
[](http://badge.fury.im/rb/formal)
|
4
|
+
[](https://travis-ci.org/mrmicahcooper/formal)
|
5
|
+
[](https://codeclimate.com/github/mrmicahcooper/formal)
|
6
|
+
|
3
7
|
Formal is simply a form builder that provides the markup we typically use
|
4
8
|
around form fields on Hashrocket projects.
|
5
9
|
|
@@ -19,68 +23,28 @@ Or install it yourself as:
|
|
19
23
|
|
20
24
|
## Usage
|
21
25
|
|
22
|
-
Specify the builder option in your form_for parameters
|
26
|
+
Specify the builder option in your `form_for` parameters
|
23
27
|
|
24
28
|
```ruby
|
25
|
-
|
29
|
+
form_for(obj, builder: Formal::FormBuilder)
|
26
30
|
```
|
27
31
|
|
32
|
+
### Label
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
The following get wrapped in a ```<dd>``` or a ```<dd class="error">```:
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
f.text_field
|
36
|
-
f.password_field
|
37
|
-
f.text_area
|
38
|
-
f.select
|
39
|
-
f.email_field
|
40
|
-
f.search_field
|
41
|
-
f.telephone_field
|
42
|
-
f.number_field
|
43
|
-
f.file_field
|
44
|
-
f.range_field
|
45
|
-
```
|
34
|
+
Label is created with error messaging within `label` element
|
46
35
|
|
47
|
-
|
36
|
+
Example:
|
48
37
|
|
49
38
|
```ruby
|
50
|
-
f.
|
51
|
-
```
|
52
|
-
|
53
|
-
returns
|
54
|
-
|
55
|
-
```HTML
|
56
|
-
<dd>
|
57
|
-
<input type="text" id="post_body" name="post[body]" />
|
58
|
-
</dd>
|
59
|
-
```
|
60
|
-
|
61
|
-
Also provided is a helper for a label with a checkbox __inside__ it (which is
|
62
|
-
also wrapped in a ```<dt>```). Use:
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
f.check_box_with_label :published
|
39
|
+
= f.label attribute
|
66
40
|
```
|
67
41
|
|
68
|
-
|
42
|
+
When `obj.attribute` is in an invalid state the markup returned will be like:
|
69
43
|
|
70
44
|
```html
|
71
|
-
<
|
72
|
-
<label for="post_published">
|
73
|
-
<input name="post[published]" type="hidden" value="0" />
|
74
|
-
<input id="post_published" name="post[published]" type="checkbox" value="1" />
|
75
|
-
published
|
76
|
-
</label>
|
77
|
-
</dt>
|
45
|
+
<label for='obj_attribute'>Attribute <span class='error'>Error message</span></label>
|
78
46
|
```
|
79
47
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
48
|
## Contributing
|
85
49
|
|
86
50
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -2,10 +2,8 @@
|
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
require 'rspec/core/rake_task'
|
4
4
|
|
5
|
+
desc 'Run formal tests.'
|
6
|
+
RSpec::Core::RakeTask.new('spec')
|
7
|
+
|
5
8
|
desc 'Default: run tests.'
|
6
9
|
task :default => :spec
|
7
|
-
|
8
|
-
desc 'Run formal tests.'
|
9
|
-
RSpec::Core::RakeTask.new('spec') do |t|
|
10
|
-
t.pattern = FileList['spec/**/*_spec.rb']
|
11
|
-
end
|
data/formal.gemspec
CHANGED
data/lib/formal.rb
CHANGED
@@ -1,42 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require 'formal/version'
|
2
|
+
require 'formal/form_builder'
|
2
3
|
|
3
4
|
module Formal
|
4
|
-
class Builder < ActionView::Helpers::FormBuilder
|
5
|
-
|
6
|
-
ActionView::Base.field_error_proc = proc { |input, instance| input }
|
7
|
-
|
8
|
-
@@field_helper_methods = %w(label_tag text_field password_field text_area select email_field search_field telephone_field number_field file_field range_field)
|
9
|
-
|
10
|
-
def label(method, text = nil, options = {}, &block)
|
11
|
-
text = text || method.to_s.humanize
|
12
|
-
|
13
|
-
if object.errors.any?
|
14
|
-
error_message = object.errors[method]
|
15
|
-
errors = error_message.is_a?(Array) ? error_message.first : error_message
|
16
|
-
error_span = @template.content_tag(:span, errors, class: 'error')
|
17
|
-
text << " #{error_span}"
|
18
|
-
@template.content_tag(:dt, super(method, text.html_safe, options, &block), class: 'error')
|
19
|
-
else
|
20
|
-
@template.content_tag(:dt, super(method, text.html_safe, options, &block))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
@@field_helper_methods.each do |method_name|
|
25
|
-
define_method method_name do |*args|
|
26
|
-
method_name = args.first
|
27
|
-
if object.errors[method_name].present?
|
28
|
-
@template.content_tag(:dd, super(*args), class: 'error')
|
29
|
-
else
|
30
|
-
@template.content_tag(:dd, super(*args))
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def check_box_with_label(method, text = nil, *args)
|
36
|
-
text = text || method.to_s
|
37
|
-
box = [check_box(method, *args).html_safe, text].join(" ")
|
38
|
-
label(method, box, *args)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
5
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Formal
|
2
|
+
|
3
|
+
# Public: Adds functionality to rails form builder
|
4
|
+
#
|
5
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
6
|
+
|
7
|
+
# Public: renders html label element
|
8
|
+
#
|
9
|
+
# method - String or Symbol object attribute
|
10
|
+
# text - String text to be rendered inside of `label` markup
|
11
|
+
# (optional, default: nil)
|
12
|
+
# options - Hash of options
|
13
|
+
# :error_element - String or Symbol representing html element the
|
14
|
+
# error markup will be rendered in.
|
15
|
+
# (optional, default: :span)
|
16
|
+
# :hide_errors - Boolean to hide error markup if it is to be
|
17
|
+
# rendered. (optional)
|
18
|
+
def label(method, text = nil, options = {}, &block)
|
19
|
+
error_element = options.delete(:error_element) || :span
|
20
|
+
hide_errors = options.delete(:hide_errors)
|
21
|
+
i18n_text = I18n.t("#{object_name}.#{method}", default: '', scope: "helpers.label").presence
|
22
|
+
text = i18n_text || text || method.to_s.humanize
|
23
|
+
|
24
|
+
unless object.nil? || hide_errors
|
25
|
+
errors = object.errors[method.to_sym]
|
26
|
+
if errors.present?
|
27
|
+
error_message = errors.is_a?(Array) ? errors.first : errors
|
28
|
+
error_markup = @template.content_tag(error_element, error_message, class: 'error')
|
29
|
+
text << " #{error_markup}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
super(method, text.html_safe, options, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_box_with_label(method, text = nil, *args)
|
37
|
+
text = text || method.to_s
|
38
|
+
box = [check_box(method, *args).html_safe, text].join(" ")
|
39
|
+
label(method, box, *args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/formal/version.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Formal
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Creates the Formal initializer at config/initializers/formal.rb"
|
5
|
+
|
6
|
+
def self.source_root
|
7
|
+
@source_root ||= File.expand_path("../templates", __FILE__)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_initializer_file
|
11
|
+
template "initializer.rb", "config/initializers/formal.rb"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
ActionView::Base.default_form_builder = Formal::FormBuilder
|
data/spec/formal_spec.rb
CHANGED
@@ -1,50 +1,110 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'formal'
|
2
3
|
|
3
|
-
describe Formal do
|
4
|
+
describe Formal::FormBuilder do
|
4
5
|
include FormalSpecHelper
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
describe "#label" do
|
8
|
+
describe 'when in a valid state' do
|
9
|
+
context 'and text is provided' do
|
10
|
+
it 'returns element with provided text' do
|
11
|
+
form_for(TestValid.new, builder: described_class) do |f|
|
12
|
+
label = f.label(:body, "PROVIDED TEXT")
|
13
|
+
expected_result = "<label for=\"test_valid_body\">PROVIDED TEXT</label>"
|
14
|
+
expect(label).to eq(expected_result)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
19
|
+
context 'and local is unavailable' do
|
20
|
+
it 'returns a properly populated label element' do
|
21
|
+
form_for(TestValid.new, builder: described_class) do |f|
|
22
|
+
label = f.label(:body)
|
23
|
+
expected_result = "<label for=\"test_valid_body\">Body</label>"
|
24
|
+
expect(label).to eq(expected_result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
16
28
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
29
|
+
context 'and locale is available' do
|
30
|
+
before do
|
31
|
+
I18n.config.backend.load_translations(fixture_locale(:en))
|
32
|
+
end
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
|
34
|
+
after do
|
35
|
+
I18n.config.backend.reload!
|
36
|
+
end
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
|
38
|
+
it 'returns a properly populated label element' do
|
39
|
+
form_for(TestValid.new, builder: described_class) do |f|
|
40
|
+
label = f.label(:body)
|
41
|
+
expected_result = "<label for=\"test_valid_body\">VALID</label>"
|
42
|
+
expect(label).to eq(expected_result)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
29
46
|
end
|
30
|
-
expected = %q{<dt><label for="post_published"><input name="post[published]" type="hidden" value="0" /><input id="post_published" name="post[published]" type="checkbox" value="1" /> published</label></dt>}
|
31
|
-
output.should include(expected)
|
32
|
-
end
|
33
47
|
|
34
|
-
|
35
|
-
|
48
|
+
describe "when in an invalid state" do
|
49
|
+
context "and locale is unavailable" do
|
50
|
+
it 'returns a label with nested error element' do
|
51
|
+
form_for(TestInvalid.new, builder: described_class) do |f|
|
52
|
+
label = f.label(:body)
|
53
|
+
expected_result = "<label for=\"test_invalid_body\">Body <span class=\"error\">ERROR</span></label>"
|
54
|
+
expect(label).to eq(expected_result)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'and locale is available' do
|
60
|
+
before do
|
61
|
+
I18n.config.backend.load_translations(fixture_locale(:en))
|
62
|
+
end
|
63
|
+
|
64
|
+
after do
|
65
|
+
I18n.config.backend.reload!
|
66
|
+
end
|
36
67
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
68
|
+
it 'returns a label with nested error element' do
|
69
|
+
form_for(TestInvalid.new, builder: described_class) do |f|
|
70
|
+
label = f.label(:body)
|
71
|
+
expected_result = "<label for=\"test_invalid_body\">INVALID <span class=\"error\">ERROR</span></label>"
|
72
|
+
expect(label).to eq(expected_result)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
41
76
|
end
|
42
77
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
78
|
+
describe 'error element' do
|
79
|
+
context 'when default' do
|
80
|
+
it 'returns span markup' do
|
81
|
+
form_for(TestInvalid.new, builder: described_class) do |f|
|
82
|
+
label = f.label(:body)
|
83
|
+
expected_result = "<label for=\"test_invalid_body\">Body <span class=\"error\">ERROR</span></label>"
|
84
|
+
expect(label).to eq(expected_result)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when passed in' do
|
90
|
+
it 'returns passed in markup' do
|
91
|
+
form_for(TestInvalid.new, builder: described_class) do |f|
|
92
|
+
label = f.label(:body, nil, error_element: :small)
|
93
|
+
expected_result = "<label for=\"test_invalid_body\">Body <small class=\"error\">ERROR</small></label>"
|
94
|
+
expect(label).to eq(expected_result)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
47
98
|
end
|
48
99
|
|
100
|
+
describe 'hide errors' do
|
101
|
+
it 'removes error markup' do
|
102
|
+
form_for(TestInvalid.new, builder: described_class) do |f|
|
103
|
+
label = f.label(:body, nil, hide_errors: true)
|
104
|
+
expected_result = "<label for=\"test_invalid_body\">Body</label>"
|
105
|
+
expect(label).to eq(expected_result)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
49
109
|
end
|
50
110
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,9 +2,8 @@ require 'action_view'
|
|
2
2
|
require 'active_model'
|
3
3
|
|
4
4
|
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formal'))
|
5
|
-
require 'formal'
|
6
5
|
|
7
|
-
class
|
6
|
+
class TestValid < Struct.new(:body)
|
8
7
|
extend ActiveModel::Naming
|
9
8
|
include ActiveModel::Conversion
|
10
9
|
|
@@ -17,7 +16,7 @@ class Post < Struct.new(:body, :published)
|
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
|
-
class
|
19
|
+
class TestInvalid < Struct.new(:body)
|
21
20
|
extend ActiveModel::Naming
|
22
21
|
include ActiveModel::Conversion
|
23
22
|
|
@@ -26,31 +25,32 @@ class InvalidPost < Struct.new(:body, :title)
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def errors
|
29
|
-
{ :body => ["
|
28
|
+
{ :body => ["ERROR"] }
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
32
|
+
def fixture_locale(local_name)
|
33
|
+
File.expand_path("../fixtures/locales/#{local_name}.yml", __FILE__)
|
34
|
+
end
|
35
|
+
|
33
36
|
module FormalSpecHelper
|
34
37
|
include ActionView::Context if defined?(ActionView::Context)
|
35
38
|
include ActionController::RecordIdentifier
|
36
39
|
include ActionView::Helpers::FormHelper
|
37
40
|
|
38
|
-
def
|
39
|
-
"/
|
41
|
+
def path(*args)
|
42
|
+
"/test_path"
|
40
43
|
end
|
41
|
-
alias :
|
44
|
+
alias :test_invalids_path :path
|
45
|
+
alias :test_valids_path :path
|
42
46
|
|
43
47
|
def protect_against_forgery?
|
44
48
|
false
|
45
49
|
end
|
46
50
|
|
47
51
|
def with_builder(model = Post.new)
|
48
|
-
@output = form_for(model, builder: Formal::
|
52
|
+
@output = form_for(model, builder: Formal::FormBuilder) do |f|
|
49
53
|
yield f
|
50
54
|
end
|
51
55
|
end
|
52
|
-
|
53
|
-
def output
|
54
|
-
@output
|
55
|
-
end
|
56
56
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- mrmicahcooper
|
@@ -10,22 +9,34 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2013-06-20 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rspec-rails
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - '='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.14.0.rc1
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.14.0.rc1
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: pry
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
21
33
|
- !ruby/object:Gem::Version
|
22
34
|
version: '0'
|
23
35
|
type: :development
|
24
36
|
prerelease: false
|
25
37
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
38
|
requirements:
|
28
|
-
- -
|
39
|
+
- - '>='
|
29
40
|
- !ruby/object:Gem::Version
|
30
41
|
version: '0'
|
31
42
|
description: Helpful form builder used by Rocketeers
|
@@ -36,40 +47,43 @@ extensions: []
|
|
36
47
|
extra_rdoc_files: []
|
37
48
|
files:
|
38
49
|
- .gitignore
|
39
|
-
- .rspec
|
40
50
|
- Gemfile
|
41
51
|
- LICENSE
|
42
52
|
- README.md
|
43
53
|
- Rakefile
|
44
54
|
- formal.gemspec
|
45
55
|
- lib/formal.rb
|
56
|
+
- lib/formal/form_builder.rb
|
46
57
|
- lib/formal/version.rb
|
58
|
+
- lib/rails/generators/formal/install/install_generator.rb
|
59
|
+
- lib/rails/generators/formal/install/templates/initializer.rb
|
60
|
+
- spec/fixtures/locales/en.yml
|
47
61
|
- spec/formal_spec.rb
|
48
62
|
- spec/spec_helper.rb
|
49
63
|
homepage: http://github.com/mrmicahcooper/formal
|
50
64
|
licenses: []
|
65
|
+
metadata: {}
|
51
66
|
post_install_message:
|
52
67
|
rdoc_options: []
|
53
68
|
require_paths:
|
54
69
|
- lib
|
55
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
-
none: false
|
57
71
|
requirements:
|
58
|
-
- -
|
72
|
+
- - '>='
|
59
73
|
- !ruby/object:Gem::Version
|
60
74
|
version: '0'
|
61
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
63
76
|
requirements:
|
64
|
-
- -
|
77
|
+
- - '>='
|
65
78
|
- !ruby/object:Gem::Version
|
66
79
|
version: '0'
|
67
80
|
requirements: []
|
68
81
|
rubyforge_project:
|
69
|
-
rubygems_version:
|
82
|
+
rubygems_version: 2.0.3
|
70
83
|
signing_key:
|
71
|
-
specification_version:
|
84
|
+
specification_version: 4
|
72
85
|
summary: A form builder that wraps form fields the way we like it at Hashrocket
|
73
86
|
test_files:
|
87
|
+
- spec/fixtures/locales/en.yml
|
74
88
|
- spec/formal_spec.rb
|
75
89
|
- spec/spec_helper.rb
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|