partial_form 0.1.0
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/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +154 -0
- data/app/views/layouts/form/_button.html.erb +2 -0
- data/app/views/layouts/form/_check_box.html.erb +4 -0
- data/app/views/layouts/form/_collection_check_boxes.html.erb +5 -0
- data/app/views/layouts/form/_collection_radio_buttons.html.erb +4 -0
- data/app/views/layouts/form/_collection_select.html.erb +4 -0
- data/app/views/layouts/form/_color_field.html.erb +4 -0
- data/app/views/layouts/form/_date_field.html.erb +4 -0
- data/app/views/layouts/form/_datetime_field.html.erb +4 -0
- data/app/views/layouts/form/_datetime_local_field.html.erb +4 -0
- data/app/views/layouts/form/_email_field.html.erb +4 -0
- data/app/views/layouts/form/_file_field.html.erb +4 -0
- data/app/views/layouts/form/_grouped_collection_select.html.erb +4 -0
- data/app/views/layouts/form/_hidden_field.html.erb +4 -0
- data/app/views/layouts/form/_label.html.erb +4 -0
- data/app/views/layouts/form/_month_field.html.erb +4 -0
- data/app/views/layouts/form/_number_field.html.erb +4 -0
- data/app/views/layouts/form/_password_field.html.erb +4 -0
- data/app/views/layouts/form/_phone_field.html.erb +4 -0
- data/app/views/layouts/form/_radio_button.html.erb +4 -0
- data/app/views/layouts/form/_range_field.html.erb +4 -0
- data/app/views/layouts/form/_search_field.html.erb +4 -0
- data/app/views/layouts/form/_select.html.erb +4 -0
- data/app/views/layouts/form/_submit.html.erb +2 -0
- data/app/views/layouts/form/_telephone_field.html.erb +4 -0
- data/app/views/layouts/form/_text_area.html.erb +4 -0
- data/app/views/layouts/form/_text_field.html.erb +4 -0
- data/app/views/layouts/form/_time_field.html.erb +4 -0
- data/app/views/layouts/form/_time_zone_select.html.erb +4 -0
- data/app/views/layouts/form/_url_field.html.erb +4 -0
- data/app/views/layouts/form/_week_field.html.erb +4 -0
- data/app/views/layouts/form/_weekday_select.html.erb +4 -0
- data/app/views/layouts/form/_wrapper.html.erb +15 -0
- data/lib/generators/partial_form/partials_generator.rb +42 -0
- data/lib/partial_form/builder.rb +309 -0
- data/lib/partial_form/engine.rb +5 -0
- data/lib/partial_form/version.rb +3 -0
- data/lib/partial_form.rb +6 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 35c22d1a3abf0d4b2827af73c6a28a1128d5a3ea37719aadfe6b033966bd3f90
|
4
|
+
data.tar.gz: 3f63f0465f0d6547ae2740e312cc6f814644acd59c91923ef02166e21bf8b8ca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5b225a18088404fb2746c000c262780207b97d2db81992cb83a95e9591cc186e9ae63dd7dc276057413fc9e7b8ac0157d79ec729f6a0abd61854b0f26e6f7e1b
|
7
|
+
data.tar.gz: 77b4cf2729f0e77a2656203c5e630957931562adb04327a9d488bac9a24977f904a7a6d0664f22288f10206f05bb0b2ecd294f08198c2d37a14415d2f8e48963
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Tom Rothe
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# PartialForm
|
2
|
+
|
3
|
+
Customizable forms for Rails using partials!
|
4
|
+
|
5
|
+
The PartialForm gem simplifies the rendering of form fields by providing a `FormBuilder` that leverages partials. This approach streamlines the management and maintenance of the field helper markup.
|
6
|
+
|
7
|
+
Potential uses are:
|
8
|
+
|
9
|
+
- Show error messages right next to the input field
|
10
|
+
- Render labels along with the inputs
|
11
|
+
- Indicate if a field is required or optional
|
12
|
+
- Keep the field markup & CSS classes consistent throughout the app
|
13
|
+
- Add more complex input fields (such as a barcode input or a custom date range picker)
|
14
|
+
|
15
|
+
## Installation & Usage
|
16
|
+
|
17
|
+
You can install the gem using `bundler add partial_form`.
|
18
|
+
|
19
|
+
The gem provides a form builder named `PartialForm::Builder`, here an example:
|
20
|
+
|
21
|
+
```erb
|
22
|
+
<%# app/views/article/_form.html.erb %>
|
23
|
+
<%= form_with model: @article, builder: PartialForm::Builder do |f| %>
|
24
|
+
<%= f._text_field :title # mind the prefix, renders app/views/form/_text_field.html.erb %>
|
25
|
+
<%= f._date_field :published_on, hint: "The release date" # pass arbitrary options to the partial %>
|
26
|
+
<%= f.text_field :slug # the default form helper is available without prefix %>
|
27
|
+
<% end %>
|
28
|
+
```
|
29
|
+
|
30
|
+
The `PartialForm::Builder` mimics the API of the [default FormBuilder](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html) but adds a `_` prefix.
|
31
|
+
The partial builder comes with default templates for each helper. These render something like this (for an invalid field):
|
32
|
+
|
33
|
+
```html
|
34
|
+
<!-- example for the rendered output of an included template -->
|
35
|
+
<div class="form-group">
|
36
|
+
<label for="article_title">Published On</label>
|
37
|
+
<input type="date" name="article[published_on]" id="article_published_on" class="invalid">
|
38
|
+
<p class="form-errors">can't be blank</p>
|
39
|
+
<p class="form-hint">The release date</p>
|
40
|
+
</div>
|
41
|
+
```
|
42
|
+
|
43
|
+
If you want to set the builder as default builder for all your forms, you can:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
class ApplicationController < ActionController::Base
|
47
|
+
default_form_builder PartialForm::Builder
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
## Documentation
|
52
|
+
|
53
|
+
Find the [latest documentation](https://motine.github.io/partial_form/).
|
54
|
+
|
55
|
+
Here an extensive list of all helpers: `_label`, `_text_field`, `_color_field`, `_date_field`, `_datetime_field`, `_datetime_local_field`, `_email_field`, `_file_field`, `_hidden_field`, `_month_field`, `_number_field`, `_password_field`, `_phone_field`, `_range_field`, `_search_field`, `_telephone_field`, `_text_area`, `_time_field`, `_url_field`, `_week_field`, `_check_box`, `_radio_button`, `_select`, `_collection_select`, `_grouped_collection_select`, `_time_zone_select`, `_weekday_select`, `_collection_check_boxes`, `_collection_radio_buttons`, `_button`, `_submit`
|
56
|
+
|
57
|
+
## Customize the builder
|
58
|
+
|
59
|
+
You can copy the standard partials to your application using:
|
60
|
+
|
61
|
+
```bash
|
62
|
+
rails g partial_form:partials
|
63
|
+
# Which partials do you want to copy? [default, all] default
|
64
|
+
# create app/views/layouts/form/_wrapper.html.erb
|
65
|
+
# create app/views/layouts/form/_text_field.html.erb
|
66
|
+
# create app/views/layouts/form/_label.html.erb
|
67
|
+
# create app/views/layouts/form/_submit.html.erb
|
68
|
+
```
|
69
|
+
|
70
|
+
Here an example how to **customize an existing helper** (`_text_field`) partial:
|
71
|
+
|
72
|
+
```erb
|
73
|
+
<%# available locals: f, method, options, errors; all keyword arguments passed to the `_text_field` are accessible via `options` %>
|
74
|
+
<%= f.label method, class: "mb-3" # call the default form builder helper %>
|
75
|
+
<%= f.text_field method, options.merge!(class: class_names(options[:class], "mb-3 border", invalid: errors.any?)) # make sure to retain passed `class` %>
|
76
|
+
<% if errors.any? -%>
|
77
|
+
<p class="mt-4 text-red-200"><%= errors.to_sentence %></p>
|
78
|
+
<% end %>
|
79
|
+
```
|
80
|
+
|
81
|
+
Please mind that some helpers use `options` and others `html_options` and check the [documentation](https://motine.github.io/partial_form/).
|
82
|
+
|
83
|
+
To **add a new helper method**, you can derive from the `PartialForm::Builder` and a new method as well as a partial:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
class MyBuilder < PartialForm::Builder
|
87
|
+
def _fancy_field(method, options = {})
|
88
|
+
render_simple_field(:_fancy_field, method, options) # renders the partial `views/layouts/form/_fancy_field` and passes the default arguments such as `f`, `method`, `errors`, etc.
|
89
|
+
end
|
90
|
+
|
91
|
+
def _super_fancy_field(bells)
|
92
|
+
whistles = Whistle.all
|
93
|
+
render_partial("super", {f: self, bells:, whistles:}) # renders `views/layouts/form/_super` and passes `f`, `bells`, `whistles`
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
## Develop & Contribute
|
99
|
+
|
100
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/motine/partial_form).
|
101
|
+
|
102
|
+
The easiest way to get a development environment is to build and use a Docker image:
|
103
|
+
|
104
|
+
```bash
|
105
|
+
# build and enter the dev container
|
106
|
+
docker build -t partial_form .
|
107
|
+
docker run -it --rm -v $(pwd):/app -p 3000:3000 partial_form
|
108
|
+
|
109
|
+
# use the demo app for testing
|
110
|
+
_demo_app/bin/rails s -b 0.0.0.0 # visit http://localhost:3000 (the gem is reloaded in a very sloppy manner)
|
111
|
+
|
112
|
+
# useful commands
|
113
|
+
rake test
|
114
|
+
rake standard:fix
|
115
|
+
rake # run both
|
116
|
+
rake rdoc
|
117
|
+
```
|
118
|
+
|
119
|
+
## Release
|
120
|
+
|
121
|
+
This section is intended for the maintainer.
|
122
|
+
|
123
|
+
```shell
|
124
|
+
# make changes
|
125
|
+
rake # preflight
|
126
|
+
# review and edit CHANGELOG.md
|
127
|
+
# edit lib/partial_form/version.rb
|
128
|
+
export VERSION=0.1.0
|
129
|
+
git commit -am "version bump"
|
130
|
+
git tag $VERSION
|
131
|
+
gem build partial_form.gemspec
|
132
|
+
gem push partial_form-$VERSION.gem
|
133
|
+
git push && git push --tags
|
134
|
+
```
|
135
|
+
|
136
|
+
# Alternatives
|
137
|
+
|
138
|
+
Currently, there are multiple ways to solve the problem of adapting the markup for form fields. There is a [dedicated section](https://guides.rubyonrails.org/form_helpers.html#customizing-form-builders) in the [Action View Form Helpers Guide](https://guides.rubyonrails.org/form_helpers.html) on how to customize form elements. Some cases can even be solved with dedicated configuration options such as [field_error_proc](https://guides.rubyonrails.org/configuring.html#config-action-view-field-error-proc).
|
139
|
+
|
140
|
+
In my opinion, these approaches are either verbose or too limited to solve the use cases above.
|
141
|
+
|
142
|
+
- **Copy the required logic & markup into templates** Repeating the markup in some views may keep the cross-dependencies low. However, copying the same (faulty) markup/logic to all forms, decreases maintainability.
|
143
|
+
- **Introduce helper methods** Helpers are a very convenient way to refactor repeating code. However, specifying markup in helpers can easily become unreadable if the logic becomes more involved. Also, helpers do not have access to the form object unless passed explicitly.
|
144
|
+
- **Add a form builder** Form builders are made for adapting and extending form field rendering. They are a great tool. However, similar to introducing helper methods, specifying the markup can become cumbersome ([example gist](https://gist.github.com/motine/dc47f6ceeaaea96e855a2dd7f4ef83ae)) and hard to read.
|
145
|
+
- **Refactor to partials** Partials are geared towards defining markup structures. They keep code readable even if logic becomes more complicated. However, partials do not have access to the form object per se. Also, using the `render` syntax does not communicate the type of input as well as a form builder method (`render "forms/text_field", method: :title, builder: f` vs. `f.text_field :title`).
|
146
|
+
- **Pull in a form builder gem** There are [many gems](https://awesome-ruby.com/#-form-builder), that allow customizing form rendering. Each of them, has its own way to adapt the behavior. This requires the developer to learn these ([sometimes complicated](https://github.com/heartcombo/simple_form?tab=readme-ov-file#the-wrappers-api)) concepts. Also, some gems provide additional functionality which may not be needed (e.g. automatic collection population).
|
147
|
+
|
148
|
+
If you are interested in more details, please check the discussion on [discuss.rubyonrails.org](https://discuss.rubyonrails.org/t/introduce-a-standard-formbuilder-that-leverages-partials/86790).
|
149
|
+
|
150
|
+
The [view_partial_form_builder gem](https://github.com/seanpdoyle/view_partial_form_builder) is similar to this gem, however there are subtle differences.
|
151
|
+
|
152
|
+
## License
|
153
|
+
|
154
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<%# available locals: f, method, collection, value_method, text_method, options, html_options, block, errors %>
|
2
|
+
<%= render("layouts/form/wrapper", **local_assigns) do -%>
|
3
|
+
<%= f.collection_check_boxes method, collection, value_method, text_method, options, html_options, &block %>
|
4
|
+
<% end %>
|
5
|
+
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%# available locals: f, method, collection, value_method, text_method, options, html_options, block, errors %>
|
2
|
+
<%= render("layouts/form/wrapper", **local_assigns) do -%>
|
3
|
+
<%= f.collection_radio_buttons method, collection, value_method, text_method, options, html_options, &block %>
|
4
|
+
<% end %>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%# available locals: f, method, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options, errors %>
|
2
|
+
<%= render("layouts/form/wrapper", **local_assigns) do -%>
|
3
|
+
<%= f.grouped_collection_select method, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options %>
|
4
|
+
<% end %>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%# available locals: f, method, options, block, errors and text (can be `nil` to infer via I18n or `false` to skip this label) %>
|
2
|
+
<% unless text == false # we always render the label unless the `false` is given -%>
|
3
|
+
<%= f.label method, text, options, &block %>
|
4
|
+
<% end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%# please see _text_field partial for available locals %>
|
2
|
+
<%
|
3
|
+
options_target = defined?(html_options) ? html_options : options # in some helper methods the class must be added to `options`, in others to `html_options`
|
4
|
+
options_target.merge!(class: class_names(options_target[:class], invalid: errors.any?))
|
5
|
+
%>
|
6
|
+
<div class="form-group">
|
7
|
+
<%= f._label method, options.delete(:label) -%>
|
8
|
+
<%= yield -%>
|
9
|
+
<% if errors.any? -%>
|
10
|
+
<p class="form-errors"><%= errors.to_sentence %></p>
|
11
|
+
<% end %>
|
12
|
+
<% if options[:hint].present? %>
|
13
|
+
<p class="form-hint"><%= options[:hint] %></p>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PartialForm
|
2
|
+
module Generators
|
3
|
+
class PartialsGenerator < Rails::Generators::Base
|
4
|
+
SELECTION_GLOBS = {
|
5
|
+
default: "_{wrapper,text_field,label,submit}*.erb",
|
6
|
+
all: "*.erb"
|
7
|
+
}
|
8
|
+
FORM_PARTIALS_PATH = Pathname(__dir__).join("../../../app/views/layouts/form")
|
9
|
+
source_root FORM_PARTIALS_PATH
|
10
|
+
argument :given_selection, type: :string, optional: true, banner: "SELECTION" # optional because we ask for it if the user does not specify it
|
11
|
+
|
12
|
+
def self.banner # :nodoc:
|
13
|
+
<<~BANNER
|
14
|
+
rails g partial_form:partials SELECTION [options]
|
15
|
+
|
16
|
+
Copies partial templates to your application.
|
17
|
+
You can choose if all partials or only a subset is copied.
|
18
|
+
Pick on of: #{SELECTION_GLOBS.keys.join(", ")}
|
19
|
+
BANNER
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_selection
|
23
|
+
@selection = given_selection
|
24
|
+
valid_selections = SELECTION_GLOBS.keys.map(&:to_s)
|
25
|
+
if @selection.blank?
|
26
|
+
@selection = ask("Which partials do you want to copy?", limited_to: valid_selections)
|
27
|
+
end
|
28
|
+
unless valid_selections.include?(@selection)
|
29
|
+
raise Thor::Error, "Please choose a valid selection (first parameter): #{valid_selections.join(", ")}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def copy_partials
|
34
|
+
pattern = SELECTION_GLOBS[@selection.to_sym]
|
35
|
+
filenames = FORM_PARTIALS_PATH.glob(pattern).map { _1.basename }
|
36
|
+
filenames.each do |filename|
|
37
|
+
copy_file filename, "app/views/layouts/form/#{filename}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,309 @@
|
|
1
|
+
require "action_view"
|
2
|
+
|
3
|
+
module PartialForm
|
4
|
+
##
|
5
|
+
# The builder allows the rendering of form fields similar to rails default `FormBuilder`.
|
6
|
+
# This Builder uses partials to manage and maintain the form field markup code.
|
7
|
+
# The Builder mimics the API of the default [Rails FormBuilder](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html) with the prefix `_`.
|
8
|
+
#
|
9
|
+
# The general idea is that each helper renders a dedicated partial and passes the arguments: `f`, `method`, `options`, `errors`.
|
10
|
+
#
|
11
|
+
# Please see README.md for more details.
|
12
|
+
class Builder < ActionView::Helpers::FormBuilder
|
13
|
+
def initialize(*) # :nodoc:
|
14
|
+
super
|
15
|
+
# CAUTION
|
16
|
+
# we want to make sure that fields are not wrapped by a "field_with_errors" proc
|
17
|
+
# this change affects all builders working on the current template
|
18
|
+
@template.field_error_proc = proc { |html_tag, instance| html_tag }
|
19
|
+
end
|
20
|
+
|
21
|
+
SIMPLE_FIELD_HELPER = [ # :nodoc:
|
22
|
+
:color_field, :date_field, :datetime_field, :datetime_local_field, :email_field, :file_field,
|
23
|
+
:hidden_field, :month_field, :number_field, :password_field, :phone_field, :range_field,
|
24
|
+
:search_field, :telephone_field, :text_field, :text_area, :time_field, :url_field, :week_field
|
25
|
+
]
|
26
|
+
|
27
|
+
##
|
28
|
+
# :method: _text_field
|
29
|
+
# :call-seq: _text_field(method, options = {})
|
30
|
+
#
|
31
|
+
# Renders the partial `views/layouts/form/_text_field`.
|
32
|
+
# All options are forwarded to the partial. Typically, options such as `label` and `hint` are taken into account with the template.
|
33
|
+
# Please checkout the examples in the README.md
|
34
|
+
#
|
35
|
+
# The partial template usually wraps the original field helper which can be found here: [ActionView::Helpers::FormBuilder#text_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-text_field).
|
36
|
+
|
37
|
+
##
|
38
|
+
# :method: _color_field
|
39
|
+
# :call-seq: _color_field(method, options = {})
|
40
|
+
#
|
41
|
+
# Renders the partial `views/layouts/form/_color_field`.
|
42
|
+
#
|
43
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#color_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-color_field).
|
44
|
+
|
45
|
+
##
|
46
|
+
# :method: _date_field
|
47
|
+
# :call-seq: _date_field(method, options = {})
|
48
|
+
#
|
49
|
+
# Renders the partial `views/layouts/form/_date_field`.
|
50
|
+
#
|
51
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#date_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-date_field).
|
52
|
+
|
53
|
+
##
|
54
|
+
# :method: _datetime_field
|
55
|
+
# :call-seq: _datetime_field(method, options = {})
|
56
|
+
#
|
57
|
+
# Renders the partial `views/layouts/form/_datetime_field`.
|
58
|
+
#
|
59
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#datetime_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-datetime_field).
|
60
|
+
|
61
|
+
##
|
62
|
+
# :method: _datetime_local_field
|
63
|
+
# :call-seq: _datetime_local_field(method, options = {})
|
64
|
+
#
|
65
|
+
# Renders the partial `views/layouts/form/_datetime_local_field`.
|
66
|
+
#
|
67
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#text_fielddatetime_local_fieldhttps://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-datetime_local_field).
|
68
|
+
|
69
|
+
##
|
70
|
+
# :method: _email_field
|
71
|
+
# :call-seq: _email_field(method, options = {})
|
72
|
+
#
|
73
|
+
# Renders the partial `views/layouts/form/_email_field`.
|
74
|
+
#
|
75
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#email_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-email_field).
|
76
|
+
|
77
|
+
##
|
78
|
+
# :method: _file_field
|
79
|
+
# :call-seq: _file_field(method, options = {})
|
80
|
+
#
|
81
|
+
# Renders the partial `views/layouts/form/_file_field`.
|
82
|
+
#
|
83
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#file_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-file_field).
|
84
|
+
|
85
|
+
##
|
86
|
+
# :method: _hidden_field
|
87
|
+
# :call-seq: _hidden_field(method, options = {})
|
88
|
+
#
|
89
|
+
# Renders the partial `views/layouts/form/_hidden_field`.
|
90
|
+
#
|
91
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#hidden_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-hidden_field).
|
92
|
+
|
93
|
+
##
|
94
|
+
# :method: _month_field
|
95
|
+
# :call-seq: _month_field(method, options = {})
|
96
|
+
#
|
97
|
+
# Renders the partial `views/layouts/form/_month_field`.
|
98
|
+
#
|
99
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#month_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-month_field).
|
100
|
+
|
101
|
+
##
|
102
|
+
# :method: _number_field
|
103
|
+
# :call-seq: _number_field(method, options = {})
|
104
|
+
#
|
105
|
+
# Renders the partial `views/layouts/form/_number_field`.
|
106
|
+
#
|
107
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#number_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-number_field).
|
108
|
+
|
109
|
+
##
|
110
|
+
# :method: _password_field
|
111
|
+
# :call-seq: _password_field(method, options = {})
|
112
|
+
#
|
113
|
+
# Renders the partial `views/layouts/form/_password_field`.
|
114
|
+
#
|
115
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#password_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-password_field).
|
116
|
+
|
117
|
+
##
|
118
|
+
# :method: _phone_field
|
119
|
+
# :call-seq: _phone_field(method, options = {})
|
120
|
+
#
|
121
|
+
# Renders the partial `views/layouts/form/_phone_field`.
|
122
|
+
#
|
123
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#phone_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-phone_field).
|
124
|
+
|
125
|
+
##
|
126
|
+
# :method: _range_field
|
127
|
+
# :call-seq: _range_field(method, options = {})
|
128
|
+
#
|
129
|
+
# Renders the partial `views/layouts/form/_range_field`.
|
130
|
+
#
|
131
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#range_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-range_field).
|
132
|
+
|
133
|
+
##
|
134
|
+
# :method: _search_field
|
135
|
+
# :call-seq: _search_field(method, options = {})
|
136
|
+
#
|
137
|
+
# Renders the partial `views/layouts/form/_search_field`.
|
138
|
+
#
|
139
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#search_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-search_field).
|
140
|
+
|
141
|
+
##
|
142
|
+
# :method: _telephone_field
|
143
|
+
# :call-seq: _telephone_field(method, options = {})
|
144
|
+
#
|
145
|
+
# Renders the partial `views/layouts/form/_telephone_field`.
|
146
|
+
#
|
147
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#telephone_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-telephone_field).
|
148
|
+
|
149
|
+
##
|
150
|
+
# :method: _text_area
|
151
|
+
# :call-seq: _text_area(method, options = {})
|
152
|
+
#
|
153
|
+
# Renders the partial `views/layouts/form/_text_area`.
|
154
|
+
#
|
155
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#text_area](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-text_area).
|
156
|
+
|
157
|
+
##
|
158
|
+
# :method: _time_field
|
159
|
+
# :call-seq: _time_field(method, options = {})
|
160
|
+
#
|
161
|
+
# Renders the partial `views/layouts/form/_time_field`.
|
162
|
+
#
|
163
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#time_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-time_field).
|
164
|
+
|
165
|
+
##
|
166
|
+
# :method: _url_field
|
167
|
+
# :call-seq: _url_field(method, options = {})
|
168
|
+
#
|
169
|
+
# Renders the partial `views/layouts/form/_url_field`.
|
170
|
+
#
|
171
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#url_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-url_field).
|
172
|
+
|
173
|
+
##
|
174
|
+
# :method: _week_field
|
175
|
+
# :call-seq: _week_field(method, options = {})
|
176
|
+
#
|
177
|
+
# Renders the partial `views/layouts/form/_week_field`.
|
178
|
+
#
|
179
|
+
# Please see #_text_field for more details. The partial template usually wraps [ActionView::Helpers::FormBuilder#week_field](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-week_field).
|
180
|
+
|
181
|
+
SIMPLE_FIELD_HELPER.each do |method_name|
|
182
|
+
define_method :"_#{method_name}" do |method, options = {}|
|
183
|
+
render_simple_field(__method__, method, options)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# Renders the partial `views/layouts/form/_label`.
|
189
|
+
#
|
190
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#label](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label).
|
191
|
+
def _label(method, text = nil, options = {}, &block)
|
192
|
+
errors = object.errors.messages_for(method)
|
193
|
+
render_partial("label", {f: self, method:, text:, errors:, options:, block:})
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# Renders the partial `views/layouts/form/_button`.
|
198
|
+
#
|
199
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#button](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-button).
|
200
|
+
def _button(value = nil, options = {}, &block)
|
201
|
+
render_partial("button", {f: self, value:, options:, block:})
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Renders the partial `views/layouts/form/_submit`.
|
206
|
+
#
|
207
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#submit](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-submit).
|
208
|
+
def _submit(value = nil, options = {})
|
209
|
+
render_partial("submit", {f: self, value:, options:})
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Renders the partial `views/layouts/form/_check_box`.
|
214
|
+
#
|
215
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#check_box](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-check_box).
|
216
|
+
def _check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
|
217
|
+
errors = object.errors.messages_for(method)
|
218
|
+
render_partial("check_box", {f: self, method:, options:, checked_value:, unchecked_value:, errors:})
|
219
|
+
end
|
220
|
+
|
221
|
+
##
|
222
|
+
# Renders the partial `views/layouts/form/_radio_button`.
|
223
|
+
#
|
224
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#radio_button](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-radio_button).
|
225
|
+
def _radio_button(method, tag_value, options = {})
|
226
|
+
errors = object.errors.messages_for(method)
|
227
|
+
render_partial("radio_button", {f: self, method:, tag_value:, options:, errors:})
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# Renders the partial `views/layouts/form/_select`.
|
232
|
+
#
|
233
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-select).
|
234
|
+
def _select(method, choices = nil, options = {}, html_options = {}, &block)
|
235
|
+
errors = object.errors.messages_for(method)
|
236
|
+
render_partial("select", {f: self, method:, choices:, options:, html_options:, block:, errors:})
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# Renders the partial `views/layouts/form/_collection_select`.
|
241
|
+
#
|
242
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#collection_select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select).
|
243
|
+
def _collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
|
244
|
+
errors = object.errors.messages_for(method)
|
245
|
+
render_partial("collection_select", {f: self, method:, collection:, value_method:, text_method:, options:, html_options:, errors:})
|
246
|
+
end
|
247
|
+
|
248
|
+
##
|
249
|
+
# Renders the partial `views/layouts/form/_grouped_collection_select`.
|
250
|
+
#
|
251
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#grouped_collection_select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-grouped_collection_select).
|
252
|
+
def _grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
|
253
|
+
errors = object.errors.messages_for(method)
|
254
|
+
render_partial("grouped_collection_select", {f: self, method:, collection:, group_method:, group_label_method:, option_key_method:, option_value_method:, options:, html_options:, errors:})
|
255
|
+
end
|
256
|
+
|
257
|
+
##
|
258
|
+
# Renders the partial `views/layouts/form/_time_zone_select`.
|
259
|
+
#
|
260
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#time_zone_select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-time_zone_select).
|
261
|
+
def _time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
|
262
|
+
errors = object.errors.messages_for(method)
|
263
|
+
render_partial("time_zone_select", {f: self, method:, priority_zones:, options:, html_options:, errors:})
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# Renders the partial `views/layouts/form/_weekday_select`.
|
268
|
+
#
|
269
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#weekday_select](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-weekday_select).
|
270
|
+
def _weekday_select(method, options = {}, html_options = {})
|
271
|
+
errors = object.errors.messages_for(method)
|
272
|
+
render_partial("weekday_select", {f: self, method:, options:, html_options:, errors:})
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# Renders the partial `views/layouts/form/_collection_check_boxes`.
|
277
|
+
#
|
278
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#collection_check_boxes](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_check_boxes).
|
279
|
+
def _collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
280
|
+
errors = object.errors.messages_for(method)
|
281
|
+
render_partial("collection_check_boxes", {f: self, method:, collection:, value_method:, text_method:, options:, html_options:, block:, errors:})
|
282
|
+
end
|
283
|
+
|
284
|
+
##
|
285
|
+
# Renders the partial `views/layouts/form/_collection_radio_buttons`.
|
286
|
+
#
|
287
|
+
# The partial template usually wraps [ActionView::Helpers::FormBuilder#collection_radio_buttons](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_radio_buttons).
|
288
|
+
def _collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
289
|
+
errors = object.errors.messages_for(method)
|
290
|
+
render_partial("collection_radio_buttons", {f: self, method:, collection:, value_method:, text_method:, options:, html_options:, block:, errors:})
|
291
|
+
end
|
292
|
+
|
293
|
+
protected
|
294
|
+
|
295
|
+
def render_simple_field(type_with_prefix, method, options) # :nodoc:
|
296
|
+
type = type_with_prefix.to_s.delete_prefix("_")
|
297
|
+
errors = object.errors.messages_for(method)
|
298
|
+
render_partial(type, {f: self, method:, errors:, options:})
|
299
|
+
end
|
300
|
+
|
301
|
+
# Renders the partial with the given name, forwarding the locals to it.
|
302
|
+
def render_partial(partial_name, locals = {})
|
303
|
+
# layout name: controller.send :_layout, self.lookup_context, []
|
304
|
+
partial_path = "layouts/form/#{partial_name}"
|
305
|
+
raise "Please provide #{partial_path} partial" unless @template.lookup_context.exists?(partial_path, [], true) # true stands for partial
|
306
|
+
@template.render(partial: partial_path, locals:)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
data/lib/partial_form.rb
ADDED
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: partial_form
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Rothe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionview
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '7.1'
|
27
|
+
description: The gem simplifies the rendering of form fields by providing a `FormBuilder`
|
28
|
+
that leverages partials. This approach streamlines the management and maintenance
|
29
|
+
of the field helper markup.
|
30
|
+
email:
|
31
|
+
- info@tomrothe.de
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- CHANGELOG.md
|
37
|
+
- LICENSE.txt
|
38
|
+
- README.md
|
39
|
+
- app/views/layouts/form/_button.html.erb
|
40
|
+
- app/views/layouts/form/_check_box.html.erb
|
41
|
+
- app/views/layouts/form/_collection_check_boxes.html.erb
|
42
|
+
- app/views/layouts/form/_collection_radio_buttons.html.erb
|
43
|
+
- app/views/layouts/form/_collection_select.html.erb
|
44
|
+
- app/views/layouts/form/_color_field.html.erb
|
45
|
+
- app/views/layouts/form/_date_field.html.erb
|
46
|
+
- app/views/layouts/form/_datetime_field.html.erb
|
47
|
+
- app/views/layouts/form/_datetime_local_field.html.erb
|
48
|
+
- app/views/layouts/form/_email_field.html.erb
|
49
|
+
- app/views/layouts/form/_file_field.html.erb
|
50
|
+
- app/views/layouts/form/_grouped_collection_select.html.erb
|
51
|
+
- app/views/layouts/form/_hidden_field.html.erb
|
52
|
+
- app/views/layouts/form/_label.html.erb
|
53
|
+
- app/views/layouts/form/_month_field.html.erb
|
54
|
+
- app/views/layouts/form/_number_field.html.erb
|
55
|
+
- app/views/layouts/form/_password_field.html.erb
|
56
|
+
- app/views/layouts/form/_phone_field.html.erb
|
57
|
+
- app/views/layouts/form/_radio_button.html.erb
|
58
|
+
- app/views/layouts/form/_range_field.html.erb
|
59
|
+
- app/views/layouts/form/_search_field.html.erb
|
60
|
+
- app/views/layouts/form/_select.html.erb
|
61
|
+
- app/views/layouts/form/_submit.html.erb
|
62
|
+
- app/views/layouts/form/_telephone_field.html.erb
|
63
|
+
- app/views/layouts/form/_text_area.html.erb
|
64
|
+
- app/views/layouts/form/_text_field.html.erb
|
65
|
+
- app/views/layouts/form/_time_field.html.erb
|
66
|
+
- app/views/layouts/form/_time_zone_select.html.erb
|
67
|
+
- app/views/layouts/form/_url_field.html.erb
|
68
|
+
- app/views/layouts/form/_week_field.html.erb
|
69
|
+
- app/views/layouts/form/_weekday_select.html.erb
|
70
|
+
- app/views/layouts/form/_wrapper.html.erb
|
71
|
+
- lib/generators/partial_form/partials_generator.rb
|
72
|
+
- lib/partial_form.rb
|
73
|
+
- lib/partial_form/builder.rb
|
74
|
+
- lib/partial_form/engine.rb
|
75
|
+
- lib/partial_form/version.rb
|
76
|
+
homepage: https://github.com/motine/partial_form
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata:
|
80
|
+
homepage_uri: https://github.com/motine/partial_form
|
81
|
+
source_code_uri: https://github.com/motine/partial_form/
|
82
|
+
changelog_uri: https://github.com/motine/partial_form/blob/master/CHANGELOG.md
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 3.2.0
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubygems_version: 3.5.16
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Customizable forms for Rails using partials!
|
102
|
+
test_files: []
|