fi_form 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e355461d23423b6c38f917a181c47a296cecf16b33108cb95699c1067c361c9a
4
+ data.tar.gz: abcee254f77abbe066b788ddcdd5cb5c76fe573001b31c155292f17494cbef50
5
+ SHA512:
6
+ metadata.gz: 58a730b2b834ccf624be68cf8c4318e3cbea8056c35a856f9fc4cfd0e76d2a18b44706b15c9cb39349cffc694ad79e2b165d363b904bf1b3f2d2ea5678baf6a3
7
+ data.tar.gz: d55eb3e743efcbec8e73ed433b0a6859ffb9267297b1febef077f733d259c3902ad3670168c235aaaabb317e65ba633f3187d7dd7624cf8ce3069dac5069cec0
@@ -0,0 +1,117 @@
1
+ class FiForm::Builder # PORO \o/
2
+
3
+ attr_reader :resource, :form, :options, :indentation
4
+ attr_accessor :validation_errors
5
+
6
+ def initialize(resource, options={}, template, &block)
7
+ @resource = resource
8
+ @template = template
9
+ @options = options.dup
10
+
11
+ @validation_errors = {}
12
+
13
+ @form = build_form
14
+ @target = @form
15
+ @indentation = options[:indentation] || 0
16
+ @renderer = options.delete(:renderer)
17
+ end
18
+
19
+ alias_method :object, :resource
20
+
21
+ def add(kind, options={})
22
+ @target << build(kind, options)
23
+ self # allow chaining
24
+ end
25
+
26
+ def group(title=nil, &block)
27
+ add(:group, title: title, indentation: indentation).add_children do
28
+ @template.capture(self, &block)
29
+ end
30
+ end
31
+
32
+ def input(field, options={})
33
+ input_options = {
34
+ value: options[:value] || resource_value(field),
35
+ field: field,
36
+ label: options[:label],
37
+ }
38
+
39
+ input_options[:hint] = options[:hint] if options[:hint]
40
+
41
+ html_options = options.except(:as, :label, :hint, :value)
42
+ input_options[:input] = html_options if html_options.any?
43
+
44
+ add(:input, input_options)
45
+ end
46
+
47
+ def render(*args)
48
+ content = @template.capture(self) do
49
+ @template.render *args
50
+ end
51
+ add :raw, content: content
52
+ end
53
+
54
+ def hint(hint, options={})
55
+ add(:hint, options.merge(hint: hint, indentation: indentation))
56
+ end
57
+
58
+ def title(title, options={})
59
+ add(:title, options.merge(title: title, indentation: indentation))
60
+ end
61
+
62
+ def submit(label=nil, options={})
63
+ add(:submit, options.merge(label: label, indentation: indentation))
64
+ end
65
+
66
+ def to_html
67
+ FiForm.configuration.get_renderer(@renderer).new(@template).render(@form)
68
+ end
69
+
70
+ def add_children(indent: true, &block)
71
+ with_target last_item, indent: indent, &block
72
+ end
73
+
74
+ private
75
+ def resource_value(field)
76
+ end
77
+
78
+ def build(kind, options)
79
+ FiForm::Item.build(kind, form: @form, **options)
80
+ end
81
+
82
+ def sub_builder(resource, &block)
83
+ FiForm::Builder.new(resource, @options.merge(indentation: indentation), @template, &block)
84
+ end
85
+
86
+ def last_item
87
+ @target.last_child
88
+ end
89
+
90
+ def with_target(target_list, indent: true, &block)
91
+ previous_target = @target
92
+ @indentation += 1 if indent
93
+ @target = target_list
94
+ yield
95
+ @indentation -= 1 if indent
96
+ @target = previous_target
97
+ end
98
+
99
+ def capture_target(options={}, &block)
100
+ indent = !!options.delete(:indent)
101
+
102
+ target_list = []
103
+ with_target(target_list, indent: indent, &block)
104
+
105
+ single_target = target_list.first
106
+ single_target.options.merge! options
107
+ single_target
108
+ end
109
+
110
+ def build_form
111
+ FiForm::Item.build(:form,
112
+ resource: @resource,
113
+ errors: validation_errors,
114
+ form_options: @options
115
+ )
116
+ end
117
+ end
@@ -0,0 +1,36 @@
1
+ module FiForm::BuilderExtensions
2
+ module ActiveRecord
3
+
4
+ def fields_for(field, options={}, &block)
5
+ indent = options[:indent]
6
+ indent = true if indent.nil?
7
+
8
+ # build a new record for that association without adding it to the internal collection
9
+ blue_print = capture_target(indent: indent) do
10
+ association = @resource.public_send(field)
11
+ record = association.klass.new(association.scope_attributes).tap(&:readonly!)
12
+ builder = sub_builder(record, &block)
13
+ instance_exec(builder, &block)
14
+
15
+ add(:blue_print, items: builder.form.items)
16
+ end
17
+
18
+ add(:fields_for, field: field, blue_print: blue_print).add_children(indent: indent) do
19
+ # capture fields for every existing record
20
+ resource.public_send(field).each do |sub_resource|
21
+ builder = sub_builder(sub_resource, &block)
22
+ instance_exec(builder, &block)
23
+ @target << builder.form
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+ def resource_value(field)
30
+ return unless @resource.respond_to?(field)
31
+ @resource.public_send(field)
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,45 @@
1
+ module FiForm
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ def self.configure
7
+ self.configuration ||= Configuration.new
8
+ yield(configuration)
9
+ end
10
+
11
+ class Configuration
12
+ attr_accessor :renderers, :default
13
+
14
+ def initialize
15
+ @renderers = {}
16
+ end
17
+
18
+ # Register a renderer. The last added renderer will be the default if not specified
19
+ def register(options)
20
+ self.renderers.merge! options
21
+ end
22
+
23
+ # add custom behaviour
24
+ def add_builder_method(name, &block)
25
+ FiForm::Builder.define_method name, &block
26
+ end
27
+
28
+ # fetch a renderer. if none is specified, the default or debug renderer will be returned
29
+ def get_renderer(identifier=nil)
30
+ identifier ||= default_renderer
31
+ self.renderers[identifier] || DebugRenderer
32
+ end
33
+
34
+ # reload renderer classes in development
35
+ def reload!
36
+ self.renderers = self.renderers.map{|k, klass| [k, klass.to_s.constantize] }.to_h
37
+ end
38
+
39
+ protected
40
+ def default_renderer
41
+ @default || self.renderers.keys.last
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,11 @@
1
+ module FiForm
2
+
3
+ class DebugRenderer < Renderer
4
+ def render(form)
5
+ template.content_tag :pre do
6
+ JSON.pretty_generate form.as_json
7
+ end
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,80 @@
1
+ class FiForm::Item < Struct.new(:kind, :options)
2
+
3
+ class Input < FiForm::Item
4
+ def initialize(*args)
5
+ super
6
+ if form.errors.key?(self.field)
7
+ self.options[:errors] = self.form.errors[self.field]
8
+ end
9
+ end
10
+ end
11
+
12
+ class Form < FiForm::Item
13
+ def as_json(*args)
14
+ super(except: :resource)
15
+ end
16
+ end
17
+
18
+ def self.build(kind, options)
19
+ case kind
20
+ when :input
21
+ Input
22
+ when :form
23
+ Form
24
+ else
25
+ self
26
+ end.new(kind, options)
27
+ end
28
+
29
+ attr_reader :resource, :form, :field
30
+ alias_method :object, :resource
31
+ def initialize(*args)
32
+ super
33
+ @form = self.options.delete(:form)
34
+
35
+ @resource = if self.options.key? :resource
36
+ self.options.delete(:resource)
37
+ else
38
+ @form.resource
39
+ end
40
+ end
41
+
42
+ def errors
43
+ self.options.fetch(:errors)
44
+ end
45
+
46
+ def items
47
+ self.options&.dig(:items) || []
48
+ end
49
+ alias_method :children, :items
50
+
51
+ def field
52
+ self.options.fetch(:field)
53
+ end
54
+
55
+ def value
56
+ self.options.fetch(:value)
57
+ end
58
+
59
+ def input
60
+ self.options&.dig(:input)
61
+ end
62
+
63
+ def <<(item)
64
+ self.options[:items] ||= []
65
+ self.options[:items] << item
66
+ end
67
+
68
+ def add_items(items)
69
+ self.options[:items] += items
70
+ end
71
+
72
+ def last_child
73
+ self.options[:items].last
74
+ end
75
+
76
+ def as_json(*args)
77
+ super(except: :resource)
78
+ end
79
+
80
+ end
@@ -0,0 +1,24 @@
1
+ module FiForm
2
+
3
+ module ViewHelper
4
+ def fi_form_for(resource, options={}, &block)
5
+ builder = FiForm::Builder.new(resource, options, self, &block)
6
+ builder.validation_errors = resource&.errors&.details
7
+
8
+ capture(builder, &block)
9
+
10
+ builder.to_html
11
+ end
12
+ end
13
+
14
+ class Railtie < Rails::Railtie
15
+ initializer 'fi_form.helper' do |_app|
16
+ ActionView::Base.send :include, FiForm::ViewHelper
17
+ end
18
+
19
+ config.to_prepare do
20
+ FiForm.configuration.reload!
21
+ end if Rails.env.development?
22
+ end
23
+
24
+ end
@@ -0,0 +1,14 @@
1
+ module FiForm
2
+
3
+ class Renderer
4
+ attr_reader :template
5
+ def initialize(template)
6
+ @template = template
7
+ end
8
+
9
+ def render(*args)
10
+ warn "Please Override render method"
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,5 @@
1
+ FiForm.configure do |config|
2
+ config.register debug: FiForm::DebugRenderer
3
+
4
+ #config.register foundation5: FiForm::Foundation5
5
+ end
@@ -0,0 +1,3 @@
1
+ module FiForm
2
+ VERSION = '0.0.2'
3
+ end
data/lib/fi_form.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'fi_form/version'
2
+ require 'fi_form/configuration'
3
+
4
+ require 'fi_form/renderer'
5
+ require 'fi_form/debug_renderer'
6
+ require 'fi_form/builder'
7
+ require 'fi_form/item'
8
+
9
+ require 'fi_form/setup'
10
+
11
+ module FiForm
12
+ end
13
+
14
+ require 'fi_form/railtie' if defined?(Rails)
15
+
16
+
17
+ # load extensions
18
+ if Gem.loaded_specs['activerecord']
19
+ require 'active_record'
20
+ require 'fi_form/builder_extensions/active_record'
21
+ FiForm::Builder.prepend FiForm::BuilderExtensions::ActiveRecord
22
+ end
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fi_form
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Pauly
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-07-13 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: '5.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 6.1.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 6.1.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: activesupport
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '5.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 6.1.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '5.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 6.1.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: awesome_print
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: byebug
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: wwtd
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: single_cov
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rspec
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: bump
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ description:
152
+ email: alex.pauly+git@posteo.de
153
+ executables: []
154
+ extensions: []
155
+ extra_rdoc_files: []
156
+ files:
157
+ - lib/fi_form.rb
158
+ - lib/fi_form/builder.rb
159
+ - lib/fi_form/builder_extensions/active_record.rb
160
+ - lib/fi_form/configuration.rb
161
+ - lib/fi_form/debug_renderer.rb
162
+ - lib/fi_form/item.rb
163
+ - lib/fi_form/railtie.rb
164
+ - lib/fi_form/renderer.rb
165
+ - lib/fi_form/setup.rb
166
+ - lib/fi_form/version.rb
167
+ homepage: https://github.com/apauly/fi_form
168
+ licenses:
169
+ - MIT
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: 2.4.0
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubygems_version: 3.0.4
187
+ signing_key:
188
+ specification_version: 4
189
+ summary: Frontend Independant Forms.
190
+ test_files: []