cookbook 0.1.5 → 0.1.6

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: 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