optimism 0.3.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4243758152d4a7299eecfe0104b01187a272be5f1da3873b618441b532289f01
4
- data.tar.gz: fcdf8b15dacfa3e211e0f3ffd2bba7ba0dd9f095a93152315795bba37430e896
3
+ metadata.gz: 9519a511dec44dd176cdd2f1f13ba50b31846cc9f9247088b821d3117728c052
4
+ data.tar.gz: 26acc98ea3fbd2fafec358ecd007b7258518b2cc75e4c387b16e7106771a2e91
5
5
  SHA512:
6
- metadata.gz: 0ae487f731194a11c364aea1fc5baefbdef1496dc536c5d3723be3d304d73a4fab36d6179ff2b86ddc5949a39129fe1a1edb284742ae88d7f68c7b99f78f1398
7
- data.tar.gz: ae7cb3a35fcbe92e3a03ce5698c7dc0e8029b2bbd80ec038762066295803f64692196a04505b5ce5851ed012734e48f56b5685ed79dc537fa535423213a40733
6
+ metadata.gz: 7294ff7de16b9119b348af7db1e29747747cc968546ea5610e2463cbe8f72804412a36b3f73a4eafc4c49d72f38d59b4765e0c0e824867f786e7886884615728
7
+ data.tar.gz: ac8eef02349c7cea595bfa4235609ebe4e33ff6e0fcc28599a887667cc9daee584a76ef38b02e59eac16caab629ffe1f2474945252af6f3679d723076835369d
data/Gemfile.lock CHANGED
@@ -1,97 +1,103 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- optimism (0.3.1)
5
- cable_ready (>= 4)
4
+ optimism (0.3.5)
5
+ cable_ready (>= 4.4.6)
6
6
  rack (~> 2.0)
7
7
  rails (>= 6, >= 5.2)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actioncable (6.0.3.2)
13
- actionpack (= 6.0.3.2)
12
+ actioncable (6.1.4.1)
13
+ actionpack (= 6.1.4.1)
14
+ activesupport (= 6.1.4.1)
14
15
  nio4r (~> 2.0)
15
16
  websocket-driver (>= 0.6.1)
16
- actionmailbox (6.0.3.2)
17
- actionpack (= 6.0.3.2)
18
- activejob (= 6.0.3.2)
19
- activerecord (= 6.0.3.2)
20
- activestorage (= 6.0.3.2)
21
- activesupport (= 6.0.3.2)
17
+ actionmailbox (6.1.4.1)
18
+ actionpack (= 6.1.4.1)
19
+ activejob (= 6.1.4.1)
20
+ activerecord (= 6.1.4.1)
21
+ activestorage (= 6.1.4.1)
22
+ activesupport (= 6.1.4.1)
22
23
  mail (>= 2.7.1)
23
- actionmailer (6.0.3.2)
24
- actionpack (= 6.0.3.2)
25
- actionview (= 6.0.3.2)
26
- activejob (= 6.0.3.2)
24
+ actionmailer (6.1.4.1)
25
+ actionpack (= 6.1.4.1)
26
+ actionview (= 6.1.4.1)
27
+ activejob (= 6.1.4.1)
28
+ activesupport (= 6.1.4.1)
27
29
  mail (~> 2.5, >= 2.5.4)
28
30
  rails-dom-testing (~> 2.0)
29
- actionpack (6.0.3.2)
30
- actionview (= 6.0.3.2)
31
- activesupport (= 6.0.3.2)
32
- rack (~> 2.0, >= 2.0.8)
31
+ actionpack (6.1.4.1)
32
+ actionview (= 6.1.4.1)
33
+ activesupport (= 6.1.4.1)
34
+ rack (~> 2.0, >= 2.0.9)
33
35
  rack-test (>= 0.6.3)
34
36
  rails-dom-testing (~> 2.0)
35
37
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
36
- actiontext (6.0.3.2)
37
- actionpack (= 6.0.3.2)
38
- activerecord (= 6.0.3.2)
39
- activestorage (= 6.0.3.2)
40
- activesupport (= 6.0.3.2)
38
+ actiontext (6.1.4.1)
39
+ actionpack (= 6.1.4.1)
40
+ activerecord (= 6.1.4.1)
41
+ activestorage (= 6.1.4.1)
42
+ activesupport (= 6.1.4.1)
41
43
  nokogiri (>= 1.8.5)
42
- actionview (6.0.3.2)
43
- activesupport (= 6.0.3.2)
44
+ actionview (6.1.4.1)
45
+ activesupport (= 6.1.4.1)
44
46
  builder (~> 3.1)
45
47
  erubi (~> 1.4)
46
48
  rails-dom-testing (~> 2.0)
47
49
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
48
- activejob (6.0.3.2)
49
- activesupport (= 6.0.3.2)
50
+ activejob (6.1.4.1)
51
+ activesupport (= 6.1.4.1)
50
52
  globalid (>= 0.3.6)
51
- activemodel (6.0.3.2)
52
- activesupport (= 6.0.3.2)
53
- activerecord (6.0.3.2)
54
- activemodel (= 6.0.3.2)
55
- activesupport (= 6.0.3.2)
56
- activestorage (6.0.3.2)
57
- actionpack (= 6.0.3.2)
58
- activejob (= 6.0.3.2)
59
- activerecord (= 6.0.3.2)
60
- marcel (~> 0.3.1)
61
- activesupport (6.0.3.2)
53
+ activemodel (6.1.4.1)
54
+ activesupport (= 6.1.4.1)
55
+ activerecord (6.1.4.1)
56
+ activemodel (= 6.1.4.1)
57
+ activesupport (= 6.1.4.1)
58
+ activestorage (6.1.4.1)
59
+ actionpack (= 6.1.4.1)
60
+ activejob (= 6.1.4.1)
61
+ activerecord (= 6.1.4.1)
62
+ activesupport (= 6.1.4.1)
63
+ marcel (~> 1.0.0)
64
+ mini_mime (>= 1.1.0)
65
+ activesupport (6.1.4.1)
62
66
  concurrent-ruby (~> 1.0, >= 1.0.2)
63
- i18n (>= 0.7, < 2)
64
- minitest (~> 5.1)
65
- tzinfo (~> 1.1)
66
- zeitwerk (~> 2.2, >= 2.2.2)
67
+ i18n (>= 1.6, < 2)
68
+ minitest (>= 5.1)
69
+ tzinfo (~> 2.0)
70
+ zeitwerk (~> 2.3)
67
71
  ast (2.4.0)
68
72
  builder (3.2.4)
69
- cable_ready (4.1.2)
73
+ cable_ready (4.5.0)
70
74
  rails (>= 5.2)
75
+ thread-local (>= 1.1.0)
71
76
  coderay (1.1.2)
72
- concurrent-ruby (1.1.6)
77
+ concurrent-ruby (1.1.9)
73
78
  crass (1.0.6)
74
- erubi (1.9.0)
75
- globalid (0.4.2)
76
- activesupport (>= 4.2.0)
77
- i18n (1.8.3)
79
+ erubi (1.10.0)
80
+ globalid (0.5.2)
81
+ activesupport (>= 5.0)
82
+ i18n (1.8.10)
78
83
  concurrent-ruby (~> 1.0)
79
84
  jaro_winkler (1.5.4)
80
- loofah (2.6.0)
85
+ loofah (2.12.0)
81
86
  crass (~> 1.0.2)
82
87
  nokogiri (>= 1.5.9)
83
88
  mail (2.7.1)
84
89
  mini_mime (>= 0.1.1)
85
- marcel (0.3.3)
86
- mimemagic (~> 0.3.2)
90
+ marcel (1.0.1)
87
91
  method_source (0.9.2)
88
- mimemagic (0.3.5)
89
- mini_mime (1.0.2)
90
- mini_portile2 (2.4.0)
91
- minitest (5.14.1)
92
- nio4r (2.5.2)
93
- nokogiri (1.10.9)
94
- mini_portile2 (~> 2.4.0)
92
+ mini_mime (1.1.1)
93
+ mini_portile2 (2.6.1)
94
+ minitest (5.14.4)
95
+ nio4r (2.5.8)
96
+ nokogiri (1.12.3)
97
+ mini_portile2 (~> 2.6.1)
98
+ racc (~> 1.4)
99
+ nokogiri (1.12.3-x64-mingw32)
100
+ racc (~> 1.4)
95
101
  parallel (1.19.1)
96
102
  parser (2.7.0.2)
97
103
  ast (~> 2.4.0)
@@ -100,35 +106,36 @@ GEM
100
106
  method_source (~> 0.9.0)
101
107
  pry-nav (0.3.0)
102
108
  pry (>= 0.9.10, < 0.13.0)
109
+ racc (1.5.2)
103
110
  rack (2.2.3)
104
111
  rack-test (1.1.0)
105
112
  rack (>= 1.0, < 3)
106
- rails (6.0.3.2)
107
- actioncable (= 6.0.3.2)
108
- actionmailbox (= 6.0.3.2)
109
- actionmailer (= 6.0.3.2)
110
- actionpack (= 6.0.3.2)
111
- actiontext (= 6.0.3.2)
112
- actionview (= 6.0.3.2)
113
- activejob (= 6.0.3.2)
114
- activemodel (= 6.0.3.2)
115
- activerecord (= 6.0.3.2)
116
- activestorage (= 6.0.3.2)
117
- activesupport (= 6.0.3.2)
118
- bundler (>= 1.3.0)
119
- railties (= 6.0.3.2)
113
+ rails (6.1.4.1)
114
+ actioncable (= 6.1.4.1)
115
+ actionmailbox (= 6.1.4.1)
116
+ actionmailer (= 6.1.4.1)
117
+ actionpack (= 6.1.4.1)
118
+ actiontext (= 6.1.4.1)
119
+ actionview (= 6.1.4.1)
120
+ activejob (= 6.1.4.1)
121
+ activemodel (= 6.1.4.1)
122
+ activerecord (= 6.1.4.1)
123
+ activestorage (= 6.1.4.1)
124
+ activesupport (= 6.1.4.1)
125
+ bundler (>= 1.15.0)
126
+ railties (= 6.1.4.1)
120
127
  sprockets-rails (>= 2.0.0)
121
128
  rails-dom-testing (2.0.3)
122
129
  activesupport (>= 4.2.0)
123
130
  nokogiri (>= 1.6)
124
- rails-html-sanitizer (1.3.0)
131
+ rails-html-sanitizer (1.4.2)
125
132
  loofah (~> 2.3)
126
- railties (6.0.3.2)
127
- actionpack (= 6.0.3.2)
128
- activesupport (= 6.0.3.2)
133
+ railties (6.1.4.1)
134
+ actionpack (= 6.1.4.1)
135
+ activesupport (= 6.1.4.1)
129
136
  method_source
130
- rake (>= 0.8.7)
131
- thor (>= 0.20.3, < 2.0)
137
+ rake (>= 0.13)
138
+ thor (~> 1.0)
132
139
  rainbow (3.0.0)
133
140
  rake (13.0.1)
134
141
  rubocop (0.79.0)
@@ -144,7 +151,7 @@ GEM
144
151
  sprockets (4.0.2)
145
152
  concurrent-ruby (~> 1.0)
146
153
  rack (> 1, < 3)
147
- sprockets-rails (3.2.1)
154
+ sprockets-rails (3.2.2)
148
155
  actionpack (>= 4.0)
149
156
  activesupport (>= 4.0)
150
157
  sprockets (>= 3.0.0)
@@ -153,18 +160,19 @@ GEM
153
160
  rubocop-performance (~> 1.5.1)
154
161
  standardrb (1.0.0)
155
162
  standard
156
- thor (1.0.1)
157
- thread_safe (0.3.6)
158
- tzinfo (1.2.7)
159
- thread_safe (~> 0.1)
163
+ thor (1.1.0)
164
+ thread-local (1.1.0)
165
+ tzinfo (2.0.4)
166
+ concurrent-ruby (~> 1.0)
160
167
  unicode-display_width (1.6.1)
161
- websocket-driver (0.7.2)
168
+ websocket-driver (0.7.5)
162
169
  websocket-extensions (>= 0.1.0)
163
170
  websocket-extensions (0.1.5)
164
- zeitwerk (2.3.0)
171
+ zeitwerk (2.4.2)
165
172
 
166
173
  PLATFORMS
167
174
  ruby
175
+ x64-mingw32
168
176
 
169
177
  DEPENDENCIES
170
178
  bundler (~> 2.0)
data/README.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  The missing drop-in solution for realtime remote form validation in Rails.
6
6
 
7
+ {% hint style="success" %}
8
+ Optimism v0.4.1 now supports Ruby 3.0.0, thanks to [Julian Rubisch](https://twitter.com/julian_rubisch) and Rails 6.1, thanks to [Josh LeBlanc](https://github.com/joshleblanc). 🎉
9
+ {% endhint %}
10
+
7
11
  ## Why have optimism?
8
12
 
9
13
  [Optimism](https://github.com/leastbad/optimism) is an MIT-licensed [Ruby on Rails](https://rubyonrails.org/) gem that makes it easy to give your users instant constructive feedback if they enter invalid data into your application. Instead of dumping a list of errors at the top of your interface, Optimism provides specific instructions directly beside or below individual input elements.
data/lib/optimism/rake.rb CHANGED
@@ -16,7 +16,7 @@ task :"optimism:install" do
16
16
  $stderr.puts "=> [ skipping ] #{channel[:app_path]} already exists"
17
17
  else
18
18
  FileUtils.cp(File.expand_path(channel[:template_path], __dir__), "./#{channel[:app_path]}")
19
- $stderr.puts "=> #{channel[:app_path]} created"
19
+ $stdout.puts "=> #{channel[:app_path]} created"
20
20
  end
21
21
  end
22
22
  end
@@ -1,3 +1,3 @@
1
1
  module Optimism
2
- VERSION = "0.3.5"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/optimism.rb CHANGED
@@ -3,28 +3,25 @@ require "optimism/version"
3
3
  require "optimism/railtie" if defined?(Rails)
4
4
 
5
5
  module Optimism
6
- include CableReady::Broadcaster
7
- class << self
8
- mattr_accessor :channel, :form_class, :error_class, :disable_submit, :suffix, :emit_events, :add_css, :inject_inline, :container_selector, :error_selector, :form_selector, :submit_selector
9
- self.channel = ->(context) { "OptimismChannel" }
10
- self.form_class = "invalid"
11
- self.error_class = "error"
12
- self.disable_submit = false
13
- self.suffix = ""
14
- self.emit_events = false
15
- self.add_css = true
16
- self.inject_inline = true
17
- self.container_selector = "#RESOURCE_ATTRIBUTE_container"
18
- self.error_selector = "#RESOURCE_ATTRIBUTE_error"
19
- self.form_selector = "#RESOURCE_form"
20
- self.submit_selector = "#RESOURCE_submit"
21
- end
6
+ mattr_accessor :channel_proc, :form_class, :error_class, :disable_submit, :suffix, :emit_events, :add_css, :inject_inline, :container_selector, :error_selector, :form_selector, :submit_selector
7
+ self.channel_proc = ->(context) { "OptimismChannel" }
8
+ self.form_class = "invalid"
9
+ self.error_class = "error"
10
+ self.disable_submit = false
11
+ self.suffix = ""
12
+ self.emit_events = false
13
+ self.add_css = true
14
+ self.inject_inline = true
15
+ self.container_selector = "#RESOURCE_ATTRIBUTE_container"
16
+ self.error_selector = "#RESOURCE_ATTRIBUTE_error"
17
+ self.form_selector = "#RESOURCE_form"
18
+ self.submit_selector = "#RESOURCE_submit"
22
19
 
23
20
  def self.configure(&block)
24
21
  yield self
25
22
  end
26
23
 
27
- def broadcast_errors(model, attributes)
24
+ def broadcast_errors(model, attributes, reverse_attributes_for: [])
28
25
  return unless model&.errors&.messages
29
26
  resource = ActiveModel::Naming.param_key(model)
30
27
  form_selector, submit_selector = Optimism.form_selector.sub("RESOURCE", resource), Optimism.submit_selector.sub("RESOURCE", resource)
@@ -39,25 +36,26 @@ module Optimism
39
36
  raise Exception.new "attributes must be a Hash (Parameters, Indifferent or standard), Array, Symbol or String"
40
37
  end
41
38
  model.valid? if model.errors.empty?
42
- process_resource(model, attributes, [resource])
39
+ process_resource(model, attributes, [resource], reverse_attributes_for: reverse_attributes_for)
43
40
  if model.errors.any?
44
- cable_ready[Optimism.channel[self]].dispatch_event(name: "optimism:form:invalid", detail: {resource: resource}) if Optimism.emit_events
45
- cable_ready[Optimism.channel[self]].add_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
46
- cable_ready[Optimism.channel[self]].set_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
41
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:form:invalid", detail: {resource: resource}) if Optimism.emit_events
42
+ CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
43
+ CableReady::Channels.instance[Optimism.channel_proc[self]].set_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
47
44
  else
48
- cable_ready[Optimism.channel[self]].dispatch_event(name: "optimism:form:valid", detail: {resource: resource}) if Optimism.emit_events
49
- cable_ready[Optimism.channel[self]].remove_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
50
- cable_ready[Optimism.channel[self]].remove_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
45
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:form:valid", detail: {resource: resource}) if Optimism.emit_events
46
+ CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: form_selector, name: Optimism.form_class) if Optimism.form_class.present?
47
+ CableReady::Channels.instance[Optimism.channel_proc[self]].remove_attribute(selector: submit_selector, name: "disabled") if Optimism.disable_submit
51
48
  end
52
- cable_ready.broadcast
49
+ CableReady::Channels.instance.broadcast
53
50
  head :ok if defined?(head)
54
51
  end
55
52
 
56
- def process_resource(model, attributes, ancestry)
53
+ def process_resource(model, attributes, ancestry, reverse_attributes_for: [])
57
54
  attributes.keys.each do |attribute|
58
55
  if attribute.ends_with?("_attributes")
59
56
  resource = attribute[0..-12]
60
57
  association = model.send(resource.to_sym)
58
+ association = association.reverse if reverse_attributes_for.include?(resource.to_sym)
61
59
  if association.respond_to? :each_with_index
62
60
  association.each_with_index do |nested, index|
63
61
  process_resource(nested, attributes[attribute][index.to_s], ancestry + [resource, index]) if attributes[attribute].key?(index.to_s)
@@ -79,23 +77,40 @@ module Optimism
79
77
  resource += "_#{ancestry.shift}_attributes_#{ancestry.shift}" until ancestry.empty?
80
78
  end
81
79
  container_selector, error_selector = Optimism.container_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute), Optimism.error_selector.sub("RESOURCE", resource).sub("ATTRIBUTE", attribute)
82
- if model.errors.any? && model.errors.messages.map(&:first).include?(attribute.to_sym)
83
- message = "#{model.errors.full_message(attribute.to_sym, model.errors.messages[attribute.to_sym].first)}#{Optimism.suffix}"
84
- cable_ready[Optimism.channel[self]].dispatch_event(name: "optimism:attribute:invalid", detail: {resource: resource, attribute: attribute, text: message}) if Optimism.emit_events
85
- cable_ready[Optimism.channel[self]].add_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
86
- cable_ready[Optimism.channel[self]].text_content(selector: error_selector, text: message) if Optimism.inject_inline
87
- else
88
- cable_ready[Optimism.channel[self]].dispatch_event(name: "optimism:attribute:valid", detail: {resource: resource, attribute: attribute}) if Optimism.emit_events
89
- cable_ready[Optimism.channel[self]].remove_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
90
- cable_ready[Optimism.channel[self]].text_content(selector: error_selector, text: "") if Optimism.inject_inline
80
+ if model.errors.any?
81
+ if attribute.ends_with?("_id") && model.errors.messages.include?(attribute.delete_suffix("_id").to_sym)
82
+ model.errors.messages[attribute.delete_suffix("_id").to_sym].each do |msg|
83
+ model.errors.add(attribute.to_sym, msg)
84
+ end
85
+ end
86
+ if model.errors.messages.map(&:first).include?(attribute.to_sym)
87
+ message = "#{model.errors.full_message(attribute.to_sym, model.errors.messages[attribute.to_sym].first)}#{Optimism.suffix}"
88
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:invalid", detail: {resource: resource, attribute: attribute, text: message}) if Optimism.emit_events
89
+ CableReady::Channels.instance[Optimism.channel_proc[self]].add_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
90
+ CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: message) if Optimism.inject_inline
91
+ else
92
+ CableReady::Channels.instance[Optimism.channel_proc[self]].dispatch_event(name: "optimism:attribute:valid", detail: {resource: resource, attribute: attribute}) if Optimism.emit_events
93
+ CableReady::Channels.instance[Optimism.channel_proc[self]].remove_css_class(selector: container_selector, name: Optimism.error_class) if Optimism.add_css
94
+ CableReady::Channels.instance[Optimism.channel_proc[self]].text_content(selector: error_selector, text: "") if Optimism.inject_inline
95
+ end
91
96
  end
92
97
  end
93
98
  end
94
99
 
95
100
  module ActionView::Helpers
101
+ module FormHelper
102
+ def error_for(object_name, attribute, **options)
103
+ tag.span **options.merge(id: error_id_for(object_name, attribute))
104
+ end
105
+
106
+ def error_id_for(object_name, attribute)
107
+ Optimism.error_selector.sub("RESOURCE", object_name.to_s.delete("]").tr("[", "_")).sub("ATTRIBUTE", attribute.to_s)[1..-1]
108
+ end
109
+ end
110
+
96
111
  class FormBuilder
97
112
  def container_for(attribute, **options, &block)
98
- @template.tag.div @template.capture(&block), options.merge!(id: container_id_for(attribute)) if block_given?
113
+ @template.tag.div @template.capture(&block), **options.merge(id: container_id_for(attribute)) if block_given?
99
114
  end
100
115
 
101
116
  def container_id_for(attribute)
@@ -103,11 +118,7 @@ module ActionView::Helpers
103
118
  end
104
119
 
105
120
  def error_for(attribute, **options)
106
- @template.tag.span options.merge! id: error_id_for(attribute)
107
- end
108
-
109
- def error_id_for(attribute)
110
- Optimism.error_selector.sub("RESOURCE", object_name.to_s.delete("]").tr("[", "_")).sub("ATTRIBUTE", attribute.to_s)[1..-1]
121
+ @template.error_for(object_name, attribute, **options)
111
122
  end
112
123
  end
113
124
  end
data/optimism.gemspec CHANGED
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "pry-nav", "~> 0.3.0"
27
27
  spec.add_development_dependency "standardrb", "~> 1.0.0"
28
28
  spec.add_dependency "rack", "~> 2.0"
29
- spec.add_dependency "rails", [">= 5.2", ">= 6"]
30
- spec.add_dependency "cable_ready", ">= 4"
29
+ spec.add_dependency "rails", [">= 5.2"]
30
+ spec.add_dependency "cable_ready", ">= 4.4.6"
31
31
  end
data/reference.md CHANGED
@@ -93,7 +93,7 @@ Optimism is configurable via an optional initializer file. As with all initializ
93
93
  {% code title="config/initializers/optimism.rb" %}
94
94
  ```ruby
95
95
  Optimism.configure do |config|
96
- config.channel = ->(context) { "OptimismChannel" }
96
+ config.channel_proc = ->(context) { "OptimismChannel" }
97
97
  config.form_class = "invalid"
98
98
  config.error_class = "error"
99
99
  config.disable_submit = false
data/typical-usage.md CHANGED
@@ -27,17 +27,17 @@ Now that you have seen what Optimism can do, let's flex our muscles a bit and se
27
27
  {% endcode %}
28
28
  {% endtab %}
29
29
 
30
- {% tab title="Bootstrap 4" %}
30
+ {% tab title="Bootstrap" %}
31
31
  {% code title="app/views/posts/\_form.html.erb" %}
32
32
  ```rust
33
33
  <%= form_with(model: post, id: "posts_form") do |form| %>
34
- <%= form.container_for :name, class: "form-group" do %>
34
+ <%= form.container_for :name, class: "input-group" do %>
35
35
  <%= form.label :name %>
36
36
  <%= form.text_field :name, class: "form-control" %>
37
37
  <%= form.error_for :name, class: "small align-bottom text-danger d-none" %>
38
38
  <% end %>
39
39
 
40
- <%= form.container_for :body, class: "form-group" do %>
40
+ <%= form.container_for :body, class: "input-group" do %>
41
41
  <%= form.label :body %>
42
42
  <%= form.text_area :body, class: "form-control" %>
43
43
  <%= form.error_for :body, class: "small align-bottom text-danger d-none" %>
@@ -76,14 +76,14 @@ Here we introduce the `container_for` helper, which wraps a form element in a `d
76
76
  ```
77
77
  {% endtab %}
78
78
 
79
- {% tab title="Bootstrap 4" %}
79
+ {% tab title="Bootstrap" %}
80
80
  ```css
81
- .form-group.error > .d-none {
81
+ .input-group.error > .d-none {
82
82
  display: inline !important;
83
83
  }
84
84
 
85
- .form-group.error > input,
86
- .form-group.error > textarea {
85
+ .input-group.error > input,
86
+ .input-group.error > textarea {
87
87
  background-color: rgba(255, 239, 213, 0.7);
88
88
  }
89
89
  ```
@@ -98,5 +98,15 @@ If you assign an id to the form itself that matches the expected format - in thi
98
98
  Unfortunately, we can't automatically generate the id for the form during its own declaration. Luckily, the format is pretty easy: **resources\_form**.
99
99
  {% endhint %}
100
100
 
101
+ ## Gotchas
102
+
103
+ Optimism is a fundamentally simple library, which means that inevitably, there's going to be scenarios that require some extra consideration.
104
+
105
+ #### Radio buttons and checkboxes
106
+
107
+ Thanks to a quirk of the way certain OG form input elements work, it's possible for an unchecked element to not be included in a form's parameters. For example, if you have a set of radio buttons with no default selection, your `params` hash will not include data for it.
108
+
109
+ Make sure to use the `checkbox` helpers that Rails provides, which implement a clever hack to make sure that unchecked checkboxes produce a `false` value in your `params`.
110
+
101
111
  ![](.gitbook/assets/web_developer.svg)
102
112
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optimism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - leastbad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-22 00:00:00.000000000 Z
11
+ date: 2021-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,9 +101,6 @@ dependencies:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '5.2'
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- version: '6'
107
104
  type: :runtime
108
105
  prerelease: false
109
106
  version_requirements: !ruby/object:Gem::Requirement
@@ -111,23 +108,20 @@ dependencies:
111
108
  - - ">="
112
109
  - !ruby/object:Gem::Version
113
110
  version: '5.2'
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '6'
117
111
  - !ruby/object:Gem::Dependency
118
112
  name: cable_ready
119
113
  requirement: !ruby/object:Gem::Requirement
120
114
  requirements:
121
115
  - - ">="
122
116
  - !ruby/object:Gem::Version
123
- version: '4'
117
+ version: 4.4.6
124
118
  type: :runtime
125
119
  prerelease: false
126
120
  version_requirements: !ruby/object:Gem::Requirement
127
121
  requirements:
128
122
  - - ">="
129
123
  - !ruby/object:Gem::Version
130
- version: '4'
124
+ version: 4.4.6
131
125
  description: Realtime remote form input validations delivered via websockets
132
126
  email:
133
127
  - hello@leastbad.com
@@ -189,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
183
  - !ruby/object:Gem::Version
190
184
  version: '0'
191
185
  requirements: []
192
- rubygems_version: 3.0.6
186
+ rubygems_version: 3.1.6
193
187
  signing_key:
194
188
  specification_version: 4
195
189
  summary: Drop-in Rails form validations