fi_form 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []