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 +4 -4
- data/VERSION +1 -1
- data/app/assets/javascript/cookbook/addFields.js +41 -0
- data/app/assets/javascript/cookbook/application.js +2 -0
- data/app/assets/javascript/cookbook/removeFields.js +36 -0
- data/app/helpers/cookbook/application_helper.rb +39 -0
- data/app/views/cookbook/_fields.html.haml +3 -3
- data/app/views/cookbook/_use_fields.html.haml +22 -0
- data/cookbook.gemspec +6 -3
- data/lib/cookbook.rb +0 -1
- data/spec/dummy/app/javascript/packs/application.js +1 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +1788 -0
- data/spec/dummy/log/test.log +2447 -0
- data/spec/requests/how_tos_spec.rb +3 -3
- data/spec/requests/recipes_spec.rb +3 -3
- metadata +5 -2
- data/app/views/cookbook/uses/_fields.html.haml +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2959709e5e50fec64984caac992b47de183442c12ce5388b37d476434e1155dc
|
4
|
+
data.tar.gz: 0b8861cf190ec4da06ac43dc6dee23ccc360c2251a427e4a7fcfc9369b32283f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc961bc7d3a9396de7265eeb271b17ff4c500b6c4c40f5187bfa721702017c7fdf0c70ca453951d792cf5fbf1ea1ada3753548bfedce74e517331be5cb8d13be
|
7
|
+
data.tar.gz: 41ceed87fb03aa183e10f4e1ddab2e2de7e147343d7af48a0dc225dcfd38878aca4ecc727e223986ed6aa146a8469c799f61745c2d938c9c1c9c7099bba64a62
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
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,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 '
|
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/
|
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
|
+
# 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.
|
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
Binary file
|
data/spec/dummy/db/test.sqlite3
CHANGED
Binary file
|