cookbook 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed17e18fbc21b1e5cd13d56061cbfb70cfa37390463f3b066c00216d990f791d
4
- data.tar.gz: 6f027dbee389ea0ed9b33ded8a68aeaa9a941a1ee74b7ccb23600e555105ee5e
3
+ metadata.gz: 2959709e5e50fec64984caac992b47de183442c12ce5388b37d476434e1155dc
4
+ data.tar.gz: 0b8861cf190ec4da06ac43dc6dee23ccc360c2251a427e4a7fcfc9369b32283f
5
5
  SHA512:
6
- metadata.gz: 4944c3707a8612da91fee783427a50500de9bc3a03f3ae13395f29fb2124175222fb2f22f0f0de28df92bdf15444ed02e359e91c5f5d26ef2a5371c93d36b60a
7
- data.tar.gz: ed9430324055b96146b3480f570403e42117e77d5a7594805e01f1391076d5e3739e163f0d0a6868f50d7a7bc5546c09ca905df5b4b744fe9470d10bff7e7fce
6
+ metadata.gz: dc961bc7d3a9396de7265eeb271b17ff4c500b6c4c40f5187bfa721702017c7fdf0c70ca453951d792cf5fbf1ea1ada3753548bfedce74e517331be5cb8d13be
7
+ data.tar.gz: 41ceed87fb03aa183e10f4e1ddab2e2de7e147343d7af48a0dc225dcfd38878aca4ecc727e223986ed6aa146a8469c799f61745c2d938c9c1c9c7099bba64a62
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -0,0 +1,41 @@
1
+ class addFields {
2
+ // This executes when the function is instantiated.
3
+ constructor() {
4
+ this.links = document.querySelectorAll('.add_fields')
5
+ this.iterateLinks()
6
+ }
7
+
8
+ iterateLinks() {
9
+ // If there are no links on the page, stop the function from executing.
10
+ if (this.links.length === 0) return
11
+ // Loop over each link on the page. A page could have multiple nested forms.
12
+ this.links.forEach(link => {
13
+ link.addEventListener('click', e => {
14
+ this.handleClick(link, e)
15
+ })
16
+ })
17
+ }
18
+
19
+ handleClick(link, e) {
20
+ // Stop the function from executing if a link or event were not passed into the function.
21
+ if (!link || !e) return
22
+ // Prevent the browser from following the URL.
23
+ e.preventDefault()
24
+ // Save a unique timestamp to ensure the key of the associated array is unique.
25
+ let time = new Date().getTime()
26
+ // Save the data id attribute into a variable. This corresponds to `new_object.object_id`.
27
+ let linkId = link.dataset.id
28
+ // Create a new regular expression needed to find any instance of the `new_object.object_id` used in the fields data attribute if there's a value in `linkId`.
29
+ let regexp = linkId ? new RegExp(linkId, 'g') : null
30
+ // Replace all instances of the `new_object.object_id` with `time`, and save markup into a variable if there's a value in `regexp`.
31
+ let newFields = regexp ? link.dataset.fields.replace(regexp, time) : null
32
+ // Add the new markup to the form if there are fields to add.
33
+ newFields ? link.insertAdjacentHTML('beforebegin', newFields) : null
34
+ // Tell it new fields are there
35
+ const event = new Event('cookbook:add_fields')
36
+ window.dispatchEvent(event);
37
+ }
38
+ }
39
+
40
+ // Wait for turbolinks to load, otherwise `document.querySelectorAll()` won't work
41
+ window.addEventListener('load', () => new addFields())
@@ -0,0 +1,2 @@
1
+ //= require cookbook/addFields
2
+ //= require cookbook/removeFields
@@ -0,0 +1,36 @@
1
+ class removeFields {
2
+ // This executes when the function is instantiated.
3
+ constructor() {
4
+ this.iterateLinks()
5
+ }
6
+
7
+ iterateLinks() {
8
+ document.querySelectorAll('.remove_fields').forEach(link => {
9
+ link.addEventListener('click', e => {
10
+ this.handleClick(link, e)
11
+ })
12
+ })
13
+ }
14
+
15
+ handleClick(link, e) {
16
+ // Stop the function from executing if a link or event were not passed into the function.
17
+ if (!link || !e) return
18
+ // Prevent the browser from following the URL.
19
+ e.preventDefault()
20
+ // Find the parent wrapper for the set of nested fields.
21
+ let fieldParent = link.closest('.nested-fields')
22
+ // If there is a parent wrapper, find the hidden delete field.
23
+ let deleteField = fieldParent
24
+ ? fieldParent.querySelector('input[type="hidden"]')
25
+ : null
26
+ // If there is a delete field, update the value to `1` and hide the corresponding nested fields.
27
+ if (deleteField) {
28
+ deleteField.value = 1
29
+ fieldParent.style.display = 'none'
30
+ }
31
+ }
32
+ }
33
+
34
+ // Wait for turbolinks to load, otherwise `document.querySelectorAll()` won't work
35
+ window.addEventListener('load', () => new removeFields())
36
+ window.addEventListener('cookbook:add_fields', () => new removeFields())
@@ -15,6 +15,45 @@ module Cookbook
15
15
  render 'cookbook/fields', form: form, usables: build_usables(form.object)
16
16
  end
17
17
 
18
+ # This method creates a link with `data-id` `data-fields` attributes. These attributes are used to create new instances of the nested fields through Javascript.
19
+ def cookbook_link_to_add_fields(name, f, association, partial = nil)
20
+
21
+ # Takes an object (@person) and creates a new instance of its associated model (:addresses)
22
+ # To better understand, run the following in your terminal:
23
+ # rails c --sandbox
24
+ # @person = Person.new
25
+ # new_object = @person.send(:addresses).klass.new
26
+ new_object = f.object.send(association).klass.new
27
+
28
+ # Saves the unique ID of the object into a variable.
29
+ # This is needed to ensure the key of the associated array is unique. This is makes parsing the content in the `data-fields` attribute easier through Javascript.
30
+ # We could use another method to achive this.
31
+ id = new_object.object_id
32
+
33
+ # https://api.rubyonrails.org/ fields_for(record_name, record_object = nil, fields_options = {}, &block)
34
+ # record_name = :addresses
35
+ # record_object = new_object
36
+ # fields_options = { child_index: id }
37
+ # child_index` is used to ensure the key of the associated array is unique, and that it matched the value in the `data-id` attribute.
38
+ # `person[addresses_attributes][child_index_value][_destroy]`
39
+ fields = f.fields_for(association, new_object, child_index: id) do |builder|
40
+
41
+ # `association.to_s.singularize + "_fields"` ends up evaluating to `address_fields`
42
+ # The render function will then look for `views/people/_address_fields.html.erb`
43
+ # The render function also needs to be passed the value of 'builder', because `views/people/_address_fields.html.erb` needs this to render the form tags.
44
+ partial.nil? ? render(association.to_s.singularize + "_fields", f: builder) : render(partial, f: builder)
45
+ end
46
+
47
+ # This renders a simple link, but passes information into `data` attributes.
48
+ # This info can be named anything we want, but in this case we chose `data-id:` and `data-fields:`.
49
+ # The `id:` is from `new_object.object_id`.
50
+ # The `fields:` are rendered from the `fields` blocks.
51
+ # We use `gsub("\n", "")` to remove anywhite space from the rendered partial.
52
+ # The `id:` value needs to match the value used in `child_index: id`.
53
+ link_to(name, '#', class: "add_fields button button-action", data: {id: id, fields: fields.gsub("\n", "")})
54
+
55
+ end
56
+
18
57
  private
19
58
 
20
59
  def build_usables(object)
@@ -1,11 +1,11 @@
1
- = javascript_include_tag 'vanilla_nested'
1
+ = javascript_include_tag 'cookbook/application'
2
2
  - if Cookbook.configuration.include_cookbook_css == true
3
3
  = stylesheet_link_tag 'cookbook/application'
4
4
  - usables.each do |usable|
5
5
  %fieldset.used_in{class: usable.plural_class}
6
6
  %legend
7
7
  %h3= usable.title
8
- = link_to_add_nested form, usable.uses_sym, "##{usable.plural_class}", partial: 'cookbook/uses/fields', link_text: "Add #{usable.singular_title}", link_classes: 'button button-action'
9
8
  %div{id: usable.plural_class}
10
9
  = form.fields_for usable.uses_sym do |g|
11
- = render 'cookbook/uses/fields', form: g, usable: usable
10
+ = render 'cookbook/use_fields', f: g, usable: usable
11
+ = cookbook_link_to_add_fields "Add #{usable.singular_title}", form, usable.uses_sym, 'cookbook/use_fields'
@@ -0,0 +1,22 @@
1
+ %fieldset.nested-fields
2
+ :ruby
3
+ table_sym = f.object_name.gsub(/[^\[]+\[([^\]]+)_uses_attributes\].*/, "\\1").pluralize
4
+ model = table_sym.to_s.classify.constantize
5
+ collection = if Cookbook.configuration.authorize_with == :cancancan
6
+ model.accessible_by(current_ability, :select)
7
+ else
8
+ model.all
9
+ end
10
+ %legend
11
+ %h4
12
+ = model.model_name.human
13
+ = f.hidden_field :_destroy
14
+ = f.hidden_field :use_of_type, value: model.model_name.to_s
15
+ = f.input :use_of_id, collection: collection, as: :select, label_method: model.label_method, value_method: :id, selected: f.object.use_of_id, include_blank: "Select #{model.model_name.human}"
16
+ = f.input :quantity_minimum
17
+ = f.input :quantity_maximum
18
+ = f.input :unit
19
+ = f.input :sort
20
+ = f.input :preparation, hint: 'like "crushed" or "greased"'
21
+ = f.input :note, hint: 'like "to taste"'
22
+ = link_to "Remove", '#', class: 'remove_fields button button-danger'
data/cookbook.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: cookbook 0.1.5 ruby lib
5
+ # stub: cookbook 0.1.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cookbook".freeze
9
- s.version = "0.1.5"
9
+ s.version = "0.1.6"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.metadata = { "source_code_uri" => "http://github.com/gemvein/cookbook" } if s.respond_to? :metadata=
@@ -30,14 +30,17 @@ Gem::Specification.new do |s|
30
30
  "README.md",
31
31
  "Rakefile",
32
32
  "VERSION",
33
+ "app/assets/javascript/cookbook/addFields.js",
34
+ "app/assets/javascript/cookbook/application.js",
35
+ "app/assets/javascript/cookbook/removeFields.js",
33
36
  "app/assets/stylesheets/cookbook/application.scss",
34
37
  "app/controllers/concerns/cookbook/params.rb",
35
38
  "app/helpers/cookbook/application_helper.rb",
36
39
  "app/models/cookbook/use.rb",
37
40
  "app/views/cookbook/_fields.html.haml",
41
+ "app/views/cookbook/_use_fields.html.haml",
38
42
  "app/views/cookbook/_used_in.html.haml",
39
43
  "app/views/cookbook/_uses_of.html.haml",
40
- "app/views/cookbook/uses/_fields.html.haml",
41
44
  "bin/rails",
42
45
  "config/initializers/simple_form.rb",
43
46
  "config/locales/simple_form.en.yml",
data/lib/cookbook.rb CHANGED
@@ -19,7 +19,6 @@ module Cookbook
19
19
  require 'haml-rails'
20
20
  require 'sass-rails'
21
21
  require 'simple_form'
22
- require 'vanilla_nested'
23
22
  require 'cancancan' if Cookbook.configuration.authorize_with == :cancancan
24
23
  end
25
24
 
@@ -13,4 +13,5 @@
13
13
  //= require rails-ujs
14
14
  //= require activestorage
15
15
  //= require cookbook
16
+ //= require ../../../../../app/assets/javascripts/cookbook
16
17
  //= require_tree .
Binary file
Binary file