13 | <% end %>
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = "1.0"
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in the app/assets
11 | # folder are already added.
12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
13 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads Spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require 'rubygems'
8 | require 'bundler'
9 |
10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
11 | spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
12 | if spring
13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
14 | gem 'spring', spring.version
15 | require 'spring/binstub'
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/vanilla_nested.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'vanilla_nested/view_helpers'
4 |
5 | module VanillaNested
6 | class Engine < ::Rails::Engine
7 | initializer 'vanilla_nested.initialize' do |_app|
8 | ActiveSupport.on_load :action_view do
9 | ActionView::Base.send :include, VanillaNested::ViewHelpers
10 | end
11 | end
12 |
13 | initializer "vanilla_nested.assets" do
14 | if Rails.application.config.respond_to?(:assets)
15 | Rails.application.config.assets.precompile += %w( vanilla_nested.js )
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/app/javascript/controllers/index.js:
--------------------------------------------------------------------------------
1 | // Import and register all your controllers from the importmap under controllers/*
2 |
3 | import { application } from "controllers/application"
4 |
5 | // Eager load all controllers defined in the import map under controllers/**/*_controller
6 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
7 | eagerLoadControllersFrom("controllers", application)
8 |
9 | // Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
10 | // import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
11 | // lazyLoadControllersFrom("controllers", application)
12 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 | # Add Yarn node_modules folder to the asset load path.
9 | Rails.application.config.assets.paths << Rails.root.join('node_modules')
10 |
11 | # Precompile additional assets.
12 | # application.js, application.css, and all non-JS/CSS in the app/assets
13 | # folder are already added.
14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
15 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, "\\1en"
8 | # inflect.singular /^(ox)en/i, "\\1"
9 | # inflect.irregular "person", "people"
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym "RESTful"
16 | # end
17 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem "sqlite3"
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative 'boot'
2 |
3 | require 'rails/all'
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(*Rails.groups)
8 |
9 | module VanillaNestedTests
10 | class Application < Rails::Application
11 | # Initialize configuration defaults for originally generated Rails version.
12 | config.load_defaults 6.0
13 |
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration can go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded after loading
17 | # the framework and any gems in your application.
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
6 | * vendor/assets/stylesheets directory can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10 | * files in this directory. Styles in this file should be added after the last require_* statement.
11 | * It is generally better to create a new file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
6 | * vendor/assets/stylesheets directory can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS
10 | * files in this directory. Styles in this file should be added after the last require_* statement.
11 | * It is generally better to create a new file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative "boot"
2 |
3 | require "rails/all"
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(*Rails.groups)
8 |
9 | module VanillaNestedTestRails7
10 | class Application < Rails::Application
11 | # Initialize configuration defaults for originally generated Rails version.
12 | config.load_defaults 7.0
13 |
14 | # Configuration for the application, engines, and railties goes here.
15 | #
16 | # These settings can be overridden in specific environments using the files
17 | # in config/environments, which are processed later.
18 | #
19 | # config.time_zone = "Central Time (US & Canada)"
20 | # config.eager_load_paths << Rails.root.join("extras")
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore the default SQLite database.
11 | /db/*.sqlite3
12 | /db/*.sqlite3-journal
13 | /db/*.sqlite3-*
14 |
15 | # Ignore all logfiles and tempfiles.
16 | /log/*
17 | /tmp/*
18 |
19 | # Ignore uploaded files in development.
20 | /storage/*
21 |
22 | /public/assets
23 | .byebug_history
24 |
25 | # Ignore master key for decrypting credentials and more.
26 | /config/master.key
27 |
28 | /public/packs
29 | /public/packs-test
30 | /node_modules
31 | /yarn-error.log
32 | yarn-debug.log*
33 | .yarn-integrity
34 |
--------------------------------------------------------------------------------
/.github/workflows/test-rails7.yml:
--------------------------------------------------------------------------------
1 | name: Tests Rails 7
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | branches:
8 | - main
9 |
10 | defaults:
11 | run:
12 | working-directory: ./test/VanillaNestedTestRails7
13 |
14 | jobs:
15 | test:
16 | runs-on: ubuntu-latest
17 |
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | ruby:
22 | - 2.7
23 | - "3.0"
24 | - 3.1
25 | - 3.2
26 |
27 | steps:
28 | - uses: actions/checkout@v3
29 | - name: Setup Ruby
30 | uses: ruby/setup-ruby@v1
31 | with:
32 | ruby-version: ${{ matrix.ruby }}
33 | working-directory: test/VanillaNestedTestRails7
34 | bundler-cache: true
35 | - name: Unit tests
36 | run: bundle exec rails test
37 | - name: System tests
38 | run: bundle exec rails test:system
39 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore the default SQLite database.
11 | /db/*.sqlite3
12 | /db/*.sqlite3-*
13 |
14 | # Ignore all logfiles and tempfiles.
15 | /log/*
16 | /tmp/*
17 | !/log/.keep
18 | !/tmp/.keep
19 |
20 | # Ignore pidfiles, but keep the directory.
21 | /tmp/pids/*
22 | !/tmp/pids/
23 | !/tmp/pids/.keep
24 |
25 | # Ignore uploaded files in development.
26 | /storage/*
27 | !/storage/.keep
28 | /tmp/storage/*
29 | !/tmp/storage/
30 | !/tmp/storage/.keep
31 |
32 | /public/assets
33 |
34 | # Ignore master key for decrypting credentials and more.
35 | /config/master.key
36 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # The following keys must be escaped otherwise they will not be retrieved by
20 | # the default I18n backend:
21 | #
22 | # true, false, on, off, yes, no
23 | #
24 | # Instead, surround them with single quotes.
25 | #
26 | # en:
27 | # 'true': 'foo'
28 | #
29 | # To learn more, please read the Rails Internationalization guide
30 | # available at https://guides.rubyonrails.org/i18n.html.
31 |
32 | en:
33 | hello: "Hello world"
34 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t "hello"
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t("hello") %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # The following keys must be escaped otherwise they will not be retrieved by
20 | # the default I18n backend:
21 | #
22 | # true, false, on, off, yes, no
23 | #
24 | # Instead, surround them with single quotes.
25 | #
26 | # en:
27 | # "true": "foo"
28 | #
29 | # To learn more, please read the Rails Internationalization guide
30 | # available at https://guides.rubyonrails.org/i18n.html.
31 |
32 | en:
33 | hello: "Hello world"
34 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/app/javascript/packs/application.js:
--------------------------------------------------------------------------------
1 | // This file is automatically compiled by Webpack, along with any other files
2 | // present in this directory. You're encouraged to place your actual application logic in
3 | // a relevant structure within app/javascript and only use these pack files to reference
4 | // that code so it'll be compiled.
5 |
6 | require("@rails/ujs").start()
7 | require("turbolinks").start()
8 | require("@rails/activestorage").start()
9 | require("channels")
10 |
11 |
12 | // Uncomment to copy all static images under ../images to the output folder and reference
13 | // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
14 | // or the `imagePath` JavaScript helper below.
15 | //
16 | // const images = require.context('../images', true)
17 | // const imagePath = (name) => images(name, true)
18 |
19 | import 'vanilla-nested'
20 |
21 | document.addEventListener('vanilla-nested:fields-limit-reached', () => {
22 | document.getElementById('pets').insertAdjacentHTML('afterbegin', 'Limit reached')
23 | })
24 |
--------------------------------------------------------------------------------
/.github/workflows/test-rails6.yml:
--------------------------------------------------------------------------------
1 | name: Tests Rails 6
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | branches:
8 | - main
9 |
10 | defaults:
11 | run:
12 | working-directory: ./test/VanillaNestedTests
13 |
14 | jobs:
15 | test:
16 | runs-on: ubuntu-latest
17 |
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | ruby:
22 | - 2.6
23 | - 2.7
24 |
25 | steps:
26 | - uses: actions/checkout@v3
27 | - name: Setup Ruby
28 | uses: ruby/setup-ruby@v1
29 | with:
30 | ruby-version: ${{ matrix.ruby }}
31 | working-directory: test/VanillaNestedTests
32 | bundler-cache: true
33 | - uses: actions/setup-node@v2
34 | with:
35 | node-version: "14"
36 | - name: YARN
37 | uses: bahmutov/npm-install@v1
38 | with:
39 | working-directory: test/VanillaNestedTests
40 | - name: Unit tests
41 | run: bundle exec rails test
42 | - name: System tests
43 | run: bundle exec rails test:system
44 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/app/javascript/packs/application_turbo.js:
--------------------------------------------------------------------------------
1 | // This file is automatically compiled by Webpack, along with any other files
2 | // present in this directory. You're encouraged to place your actual application logic in
3 | // a relevant structure within app/javascript and only use these pack files to reference
4 | // that code so it'll be compiled.
5 |
6 | require("@rails/ujs").start();
7 | require("@rails/activestorage").start();
8 | require("channels");
9 | import "@hotwired/turbo-rails";
10 | import "../controllers";
11 |
12 | // Uncomment to copy all static images under ../images to the output folder and reference
13 | // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
14 | // or the `imagePath` JavaScript helper below.
15 | //
16 | // const images = require.context('../images', true)
17 | // const imagePath = (name) => images(name, true)
18 |
19 | import "vanilla-nested";
20 |
21 | document.addEventListener("vanilla-nested:fields-limit-reached", () => {
22 | document
23 | .getElementById("pets")
24 | .insertAdjacentHTML("afterbegin", "Limit reached");
25 | });
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Ariel Juodziukynas
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # This file is the source Rails uses to define your schema when running `bin/rails
6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 | # be faster and is potentially less error prone than running all of your
8 | # migrations from scratch. Old migrations may fail to apply correctly if those
9 | # migrations use external dependencies or application code.
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema.define(version: 2021_02_20_015510) do
14 |
15 | create_table "pets", force: :cascade do |t|
16 | t.bigint "user_id"
17 | t.string "name"
18 | t.string "color"
19 | t.index ["user_id"], name: "index_pets_on_user_id"
20 | end
21 |
22 | create_table "users", force: :cascade do |t|
23 | t.string "name"
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # This file is the source Rails uses to define your schema when running `bin/rails
6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 | # be faster and is potentially less error prone than running all of your
8 | # migrations from scratch. Old migrations may fail to apply correctly if those
9 | # migrations use external dependencies or application code.
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema[7.0].define(version: 2021_02_20_015510) do
14 | create_table "pets", force: :cascade do |t|
15 | t.integer "user_id"
16 | t.string "name"
17 | t.string "color"
18 | t.index ["user_id"], name: "index_pets_on_user_id"
19 | end
20 |
21 | create_table "users", force: :cascade do |t|
22 | t.string "name"
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "fileutils"
3 |
4 | # path to your application root.
5 | APP_ROOT = File.expand_path("..", __dir__)
6 |
7 | def system!(*args)
8 | system(*args) || abort("\n== Command #{args} failed ==")
9 | end
10 |
11 | FileUtils.chdir APP_ROOT do
12 | # This script is a way to set up or update your development environment automatically.
13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome.
14 | # Add necessary setup steps to this file.
15 |
16 | puts "== Installing dependencies =="
17 | system! "gem install bundler --conservative"
18 | system("bundle check") || system!("bundle install")
19 |
20 | # puts "\n== Copying sample files =="
21 | # unless File.exist?("config/database.yml")
22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml"
23 | # end
24 |
25 | puts "\n== Preparing database =="
26 | system! "bin/rails db:prepare"
27 |
28 | puts "\n== Removing old logs and tempfiles =="
29 | system! "bin/rails log:clear tmp:clear"
30 |
31 | puts "\n== Restarting application server =="
32 | system! "bin/rails restart"
33 | end
34 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'fileutils'
3 |
4 | # path to your application root.
5 | APP_ROOT = File.expand_path('..', __dir__)
6 |
7 | def system!(*args)
8 | system(*args) || abort("\n== Command #{args} failed ==")
9 | end
10 |
11 | FileUtils.chdir APP_ROOT do
12 | # This script is a way to setup or update your development environment automatically.
13 | # This script is idempotent, so that you can run it at anytime and get an expectable outcome.
14 | # Add necessary setup steps to this file.
15 |
16 | puts '== Installing dependencies =='
17 | system! 'gem install bundler --conservative'
18 | system('bundle check') || system!('bundle install')
19 |
20 | # Install JavaScript dependencies
21 | system('bin/yarn')
22 |
23 | # puts "\n== Copying sample files =="
24 | # unless File.exist?('config/database.yml')
25 | # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
26 | # end
27 |
28 | puts "\n== Preparing database =="
29 | system! 'bin/rails db:prepare'
30 |
31 | puts "\n== Removing old logs and tempfiles =="
32 | system! 'bin/rails log:clear tmp:clear'
33 |
34 | puts "\n== Restarting application server =="
35 | system! 'bin/rails restart'
36 | end
37 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/storage.yml:
--------------------------------------------------------------------------------
1 | test:
2 | service: Disk
3 | root: <%= Rails.root.join("tmp/storage") %>
4 |
5 | local:
6 | service: Disk
7 | root: <%= Rails.root.join("storage") %>
8 |
9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10 | # amazon:
11 | # service: S3
12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14 | # region: us-east-1
15 | # bucket: your_own_bucket
16 |
17 | # Remember not to checkin your GCS keyfile to a repository
18 | # google:
19 | # service: GCS
20 | # project: your_project
21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22 | # bucket: your_own_bucket
23 |
24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25 | # microsoft:
26 | # service: AzureStorage
27 | # storage_account_name: your_account_name
28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29 | # container: your_container_name
30 |
31 | # mirror:
32 | # service: Mirror
33 | # primary: local
34 | # mirrors: [ amazon, google, microsoft ]
35 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide content security policy
4 | # For further information see the following documentation
5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
6 |
7 | # Rails.application.configure do
8 | # config.content_security_policy do |policy|
9 | # policy.default_src :self, :https
10 | # policy.font_src :self, :https, :data
11 | # policy.img_src :self, :https, :data
12 | # policy.object_src :none
13 | # policy.script_src :self, :https
14 | # policy.style_src :self, :https
15 | # # Specify URI for violation reports
16 | # # policy.report_uri "/csp-violation-report-endpoint"
17 | # end
18 | #
19 | # # Generate session nonces for permitted importmap and inline scripts
20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
21 | # config.content_security_policy_nonce_directives = %w(script-src)
22 | #
23 | # # Report CSP violations to a specified URI. See:
24 | # # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
25 | # # config.content_security_policy_report_only = true
26 | # end
27 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/storage.yml:
--------------------------------------------------------------------------------
1 | test:
2 | service: Disk
3 | root: <%= Rails.root.join("tmp/storage") %>
4 |
5 | local:
6 | service: Disk
7 | root: <%= Rails.root.join("storage") %>
8 |
9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10 | # amazon:
11 | # service: S3
12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14 | # region: us-east-1
15 | # bucket: your_own_bucket-<%= Rails.env %>
16 |
17 | # Remember not to checkin your GCS keyfile to a repository
18 | # google:
19 | # service: GCS
20 | # project: your_project
21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22 | # bucket: your_own_bucket-<%= Rails.env %>
23 |
24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25 | # microsoft:
26 | # service: AzureStorage
27 | # storage_account_name: your_account_name
28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29 | # container: your_container_name-<%= Rails.env %>
30 |
31 | # mirror:
32 | # service: Mirror
33 | # primary: local
34 | # mirrors: [ amazon, google, microsoft ]
35 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/test/system/html_tag_test.rb:
--------------------------------------------------------------------------------
1 | require "application_system_test_case"
2 |
3 | class HtmlTagTest < ApplicationSystemTestCase
4 | test "accepts custom tags for link_to_add/remove_nested" do
5 | visit new_with_custom_link_tag_users_path
6 |
7 | assert_selector '#new_user'
8 |
9 | assert_selector '.pet-fields', count: 1
10 |
11 | within '.pet-fields:nth-of-type(1)' do
12 | fill_in 'Name', with: 'Spike'
13 | end
14 |
15 | # wrapper is a SPAN tag
16 | find('span.vanilla-nested-add', text: 'Add Pet').click
17 |
18 | assert_selector '.pet-fields', count: 2
19 |
20 | within '.pet-fields:nth-of-type(2)' do
21 | fill_in 'Name', with: 'Marnie'
22 | end
23 |
24 | # wrapper is a DIV tag
25 | within '.pet-fields:nth-of-type(1)' do
26 | find('div.vanilla-nested-remove', text: 'X').click
27 | end
28 | end
29 |
30 | test "accepts attributes for the custom tags for link_to_add/remove_nested" do
31 | visit new_with_attributes_on_link_tag_users_path
32 |
33 | # 'add' wrapper has a title attribute
34 | # it also preserves data and classes attributes
35 | # tag_attributes: {title: "Add Pet", data: {some_data: 'is preserved'}
36 | find('.vanilla-nested-add[title="Add Pet"][data-some-data="is preserved"]', text: '+').click
37 |
38 | # wrapper has a tabindex
39 | # tag: 'button', tag_attributes: {tabindex: "10"}
40 | within '.pet-fields:nth-of-type(1)' do
41 | find('button.vanilla-nested-remove[tabindex="10"]', text: 'X').click
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/test/system/html_tag_test.rb:
--------------------------------------------------------------------------------
1 | require "application_system_test_case"
2 |
3 | class HtmlTagTest < ApplicationSystemTestCase
4 | test "accepts custom tags for link_to_add/remove_nested" do
5 | visit new_with_custom_link_tag_users_path
6 |
7 | assert_selector '#new_user'
8 |
9 | assert_selector '.pet-fields', count: 1
10 |
11 | within '.pet-fields:nth-of-type(1)' do
12 | fill_in 'Name', with: 'Spike'
13 | end
14 |
15 | # wrapper is a SPAN tag
16 | find('span.vanilla-nested-add', text: 'Add Pet').click
17 |
18 | assert_selector '.pet-fields', count: 2
19 |
20 | within '.pet-fields:nth-of-type(2)' do
21 | fill_in 'Name', with: 'Marnie'
22 | end
23 |
24 | # wrapper is a DIV tag
25 | within '.pet-fields:nth-of-type(1)' do
26 | find('div.vanilla-nested-remove', text: 'X').click
27 | end
28 | end
29 |
30 | test "accepts attributes for the custom tags for link_to_add/remove_nested" do
31 | visit new_with_attributes_on_link_tag_users_path
32 |
33 | # 'add' wrapper has a title attribute
34 | # it also preserves data and classes attributes
35 | # tag_attributes: {title: "Add Pet", data: {some_data: 'is preserved'}
36 | find('.vanilla-nested-add[title="Add Pet"][data-some-data="is preserved"]', text: '+').click
37 |
38 | # wrapper has a tabindex
39 | # tag: 'button', tag_attributes: {tabindex: "10"}
40 | within '.pet-fields:nth-of-type(1)' do
41 | find('button.vanilla-nested-remove[tabindex="10"]', text: 'X').click
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide content security policy
4 | # For further information see the following documentation
5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
6 |
7 | # Rails.application.config.content_security_policy do |policy|
8 | # policy.default_src :self, :https
9 | # policy.font_src :self, :https, :data
10 | # policy.img_src :self, :https, :data
11 | # policy.object_src :none
12 | # policy.script_src :self, :https
13 | # policy.style_src :self, :https
14 | # # If you are using webpack-dev-server then specify webpack-dev-server host
15 | # policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
16 |
17 | # # Specify URI for violation reports
18 | # # policy.report_uri "/csp-violation-report-endpoint"
19 | # end
20 |
21 | # If you are using UJS then enable automatic nonce generation
22 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
23 |
24 | # Set the nonce only to specific directives
25 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
26 |
27 | # Report CSP violations to a specified URI
28 | # For further information see the following documentation:
29 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
30 | # Rails.application.config.content_security_policy_report_only = true
31 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/config/puma.rb:
--------------------------------------------------------------------------------
1 | # Puma can serve each request in a thread from an internal thread pool.
2 | # The `threads` method setting takes two numbers: a minimum and maximum.
3 | # Any libraries that use thread pools should be configured to match
4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
5 | # and maximum; this matches the default thread size of Active Record.
6 | #
7 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9 | threads min_threads_count, max_threads_count
10 |
11 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
12 | #
13 | port ENV.fetch("PORT") { 3000 }
14 |
15 | # Specifies the `environment` that Puma will run in.
16 | #
17 | environment ENV.fetch("RAILS_ENV") { "development" }
18 |
19 | # Specifies the `pidfile` that Puma will use.
20 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
21 |
22 | # Specifies the number of `workers` to boot in clustered mode.
23 | # Workers are forked web server processes. If using threads and workers together
24 | # the concurrency of the application would be max `threads` * `workers`.
25 | # Workers do not work on JRuby or Windows (both of which do not support
26 | # processes).
27 | #
28 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
29 |
30 | # Use the `preload_app!` method when specifying a `workers` number.
31 | # This directive tells Puma to first boot the application and load code
32 | # before forking the application. This takes advantage of Copy On Write
33 | # process behavior so workers use less memory.
34 | #
35 | # preload_app!
36 |
37 | # Allow puma to be restarted by `rails restart` command.
38 | plugin :tmp_restart
39 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
We're sorry, but something went wrong.
62 |
63 |
If you are the application owner check the logs for more information.
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/test/VanillaNestedTestRails7/config/puma.rb:
--------------------------------------------------------------------------------
1 | # Puma can serve each request in a thread from an internal thread pool.
2 | # The `threads` method setting takes two numbers: a minimum and maximum.
3 | # Any libraries that use thread pools should be configured to match
4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
5 | # and maximum; this matches the default thread size of Active Record.
6 | #
7 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9 | threads min_threads_count, max_threads_count
10 |
11 | # Specifies the `worker_timeout` threshold that Puma will use to wait before
12 | # terminating a worker in development environments.
13 | #
14 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
15 |
16 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
17 | #
18 | port ENV.fetch("PORT") { 3000 }
19 |
20 | # Specifies the `environment` that Puma will run in.
21 | #
22 | environment ENV.fetch("RAILS_ENV") { "development" }
23 |
24 | # Specifies the `pidfile` that Puma will use.
25 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
26 |
27 | # Specifies the number of `workers` to boot in clustered mode.
28 | # Workers are forked web server processes. If using threads and workers together
29 | # the concurrency of the application would be max `threads` * `workers`.
30 | # Workers do not work on JRuby or Windows (both of which do not support
31 | # processes).
32 | #
33 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
34 |
35 | # Use the `preload_app!` method when specifying a `workers` number.
36 | # This directive tells Puma to first boot the application and load code
37 | # before forking the application. This takes advantage of Copy On Write
38 | # process behavior so workers use less memory.
39 | #
40 | # preload_app!
41 |
42 | # Allow puma to be restarted by `bin/rails restart` command.
43 | plugin :tmp_restart
44 |
--------------------------------------------------------------------------------
/test/VanillaNestedTests/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
130 | <% end %>
131 | ```
132 |
133 | Note that:
134 |
135 | - `link_to_remove_nested` receives the nested form as a parameter, it adds a hidden `[_destroy]` field
136 | - `link_to_add_nested` expects the form builder, the name of the association and the selector of the container where the gem will insert the new fields
137 |
138 | # Customizing link_to_add_nested
139 |
140 | #### Link text
141 |
142 | The default value is `Add `, but it can be changed using the parameter `link_text`:
143 |
144 | ```Ruby
145 | link_to_add_nested(form, :order_items, '#order-items', link_text: I18n.t(:some_key))
146 | ```
147 |
148 | This way you can, for example, internationalize the text.
149 |
150 | #### Link classes
151 |
152 | By default, the link to add new fields has the class `vanilla-nested-add` which is required, but you can add more classes passing a string:
153 |
154 | ```Ruby
155 | link_to_add_nested(form, :order_items, '#order-items', link_classes: 'btn btn-primary')
156 | ```
157 |
158 | This way you can style the link with no need of targeting the specific vanilla nested class.
159 |
160 | #### Insert position
161 |
162 | By default, new fields are appended to the container, you can change that with the `insert_method` option. For now, only `:append` and `:prepend` are supported:
163 |
164 | ```Ruby
165 | link_to_add_nested(form, :order_items, '#order-items', insert_method: :prepend)
166 | ```
167 |
168 | #### Partial name
169 |
170 | The default partial's name is inferred using the association's class name. If your Order has_many :order_items and the class of those items is OrderItem, then the inferred name is `order_item_fields`. You can use any partial name you like, though:
171 |
172 | ```Ruby
173 | link_to_add_nested(form, :order_items, '#order-items', partial: 'my_partial')
174 | ```
175 |
176 | #### Form variable used in the partial
177 |
178 | `link_to_add_nested` needs to render an empty template in order to later append/prepend it. To do that, it passes the form as a local variable. If your partial uses `form`, you don't have to do anything, but if you using another variable name, just customize it here.
179 |
180 | ```HTML+ERB
181 | # orders/_order_item_fields.html.erb
182 |
183 | <%= ff.text_field :attr1 %>
184 | <%= ff.select :attr2 ..... %>
185 | <%= link_to_remove_nested(ff) # adds a link to remove the element %>
186 |
187 | ```
188 |
189 | ```Ruby
190 | link_to_add_nested(form, :order_items, '#order-items', partial_form_variable: :ff)
191 | ```
192 |
193 | You can also pass more local variables to the partial by setting the partial_locals value.
194 |
195 | ```Ruby
196 | link_to_add_nested(form, :order_items, '#order-items', partial_locals: { key: 'value' })
197 | ```
198 |
199 | #### Tag
200 |
201 | The HTML tag that will be generated. An `` tag by default.
202 |
203 | ```Ruby
204 | link_to_add_nested(form, :order_items, '#order-items', tag: 'span')
205 | ```
206 |
207 | #### Tag Attributes
208 |
209 | HTML attributes to set for the generated HTML tag. It's a has with key value pairs user for the `content_tag` call, so it support any attribute/value pair supported by [`content_tag`](https://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag)
210 |
211 | ```Ruby
212 | link_to_add_nested(form, :order_items, '#order-items', link_text: '+', tag_attributes: {title: "Add Order"})
213 | # +
214 | ```
215 |
216 | `class` attributes are appended to the `vanilla-nested-add` class and the custom classes specified with the `link_classes` argument.
217 |
218 | ```Ruby
219 | link_to_add_nested(form, :order_items, '#order-items', link_text: '+', tag_attributes: {class: "some-class"}, link_classes: 'another-class')
220 | # +
221 | ```
222 |
223 | #### Link content
224 |
225 | If you need html content, you can use a block:
226 |
227 | ```erb
228 | <%= link_to_add_nested(form, :order_items, '#order-items') do %>
229 |
230 | <% end %>
231 | ```
232 |
233 | # Customizing link_to_remove_nested
234 |
235 | #### Link text
236 |
237 | The default value is `"X"`, but it can be changed using the parameter `link_text`:
238 |
239 | ```Ruby
240 | link_to_remove_nested(form, link_text: "remove")
241 | ```
242 |
243 | #### Link content
244 |
245 | If you need html content, you can use a block:
246 |
247 | ```erb
248 | <%= link_to_remove_nested(form) do %>
249 |
250 | <% end %>
251 | ```
252 |
253 | #### Link classes
254 |
255 | By default, the link to remove fields has the class `vanilla-nested-remove` which is required, but you can add more classes passing a space separated string:
256 |
257 | ```Ruby
258 | link_to_remove_nested(form, link_classes: 'btn btn-primary')
259 | ```
260 |
261 | This way you can style the link with no need of targeting the specific vanilla nested class.
262 |
263 | #### Fields wrapper
264 |
265 | By default, the link to remove the fields assumes it's a direct child of the wrapper of the fields. You can customize this if you can't make it a direct child.
266 |
267 | ```HTML+ERB
268 | # orders/_order_item_fields.html.erb
269 |
270 |
274 | <%= link_to_remove_nested(ff, fields_wrapper_selector: '.wrapper-div') # if we don't set this, it will only hide the span %>
275 |
276 | ```
277 |
278 | Note that:
279 |
280 | - The link MUST be a descendant of the fields wrapper, it may not be a direct child, but the look up of the wrapper uses JavaScript's `closest()` method, so it looks on the ancestors.
281 | - Since this uses JavaScript's `closest()`, there is no IE supported (https://caniuse.com/#search=closest). You may want to add a polyfill or define the method manually if you need to support it.
282 |
283 | #### Tag
284 |
285 | The HTML tag that will be generated. An `` tag by default.
286 |
287 | ```Ruby
288 | link_to_remove_nested(ff, tag: 'p')
289 | ```
290 |
291 | #### Tag Attributes
292 |
293 | HTML attributes to set for the generated HTML tag. It's a has with key value pairs user for the `content_tag` call, so it support any attribute/value pair supported by [`content_tag`](https://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag)
294 |
295 | ```Ruby
296 | link_to_remove_nested(ff, link_text: 'X', tag_attributes: {title: "Delete!"})
297 | # X
298 | ```
299 |
300 | `class` attributes are appended to the `vanilla-nested-remove` class and the custom classes specified with the `link_classes` argument, just like the `link_to_add_nested` helper.
301 |
302 | #### Undoing
303 |
304 | You can tell the plugin to add an "undo" link right after removing the fields (as a direct child of the fields wrapper! this is not customizable!).
305 |
306 | ```Ruby
307 | link_to_remove_nested(ff, undo_link_timeout: 2000, undo_link_text: I18n.t('undo_remove_fields'), undo_link_classes: 'btn btn-secondary')
308 | ```
309 |
310 | Options are:
311 |
312 | - `undo_link_timeout`: milliseconds, greater than 0 to turn the feature on, default: `nil`
313 | - `undo_link_text`: string with the text of the link, great for internationalization, default: `'Undo'`
314 | - `undo_link_classes`: space separated string, default: `''`
315 |
316 | # Events
317 |
318 | There are some events that you can listen to add custom callbacks on different moments. All events bubbles up the dom, so you can listen for them on any ancestor.
319 |
320 | #### 'vanilla-nested:fields-added'
321 |
322 | Triggered right after the fields wrapper was inserted on the container.
323 |
324 | ```Javascript
325 | document.addEventListener('vanilla-nested:fields-added', function(e){
326 | // e.type == 'vanilla-nested:fields-added'
327 | // e.target == container div of the fields
328 | // e.detail.triggeredBy == the "add" link
329 | // e.detail.added == the fields wrapper just inserted
330 | })
331 | ```
332 |
333 | #### 'vanilla-nested:fields-limit-reached'
334 |
335 | Triggered right after the fields wrapper was inserted on the container if the current count is >= limit, where limit is the value configured on the model: `accepts_nested_attributes_for :assoc, limit: 5`. You can listen to this event to disable the "add" link for example, or to show a warning.
336 |
337 | ```Javascript
338 | document.addEventListener('vanilla-nested:fields-limit-reached', function(e){
339 | // e.type == 'vanilla-nested:fields-added'
340 | // e.target == container div of the fields
341 | // e.detail.triggeredBy == the "add" link
342 | })
343 | ```
344 |
345 | #### 'vanilla-nested:fields-removed'
346 |
347 | Triggered when the fields wrapper if fully hidden (aka ""removed""), that is: after clicking the "remove" link with no timeout OR after the timeout finished.
348 |
349 | ```Javascript
350 | document.addEventListener('vanilla-nested:fields-removed', function(e){
351 | // e.type == 'vanilla-nested:fields-removed'
352 | // e.target == fields wrapper ""removed""
353 | // e.detail.triggeredBy == the "remove" link if no undo action, the 'undo' link if it was triggered by the timeout })
354 | ```
355 |
356 | #### 'vanilla-nested:fields-hidden'
357 |
358 | Triggered when the fields wrapper if hidden with an undo option.
359 |
360 | ```Javascript
361 | document.addEventListener('vanilla-nested:fields-hidden', function(e){
362 | // e.type == 'vanilla-nested:fields-hidden'
363 | // e.target == fields wrapper hidden
364 | // e.detail.triggeredBy == the "remove" link
365 | })
366 | ```
367 |
368 | > **Remove vs Hidden**
369 | >
370 | > Behind the scene, the wrapper is never actually removed, because we need to send the `[_destroy]` parameter. But there are 2 different stages when removing it.
371 | >
372 | > - If there's no "undo" action configured, the wrapped is set to `display: none` and considered "removed".
373 | > - If you use the "undo" feature, first the children of the wrapper are hidden (triggering the `hidden` event) and then, after the timeout passes, the wrapper is set to `display: none` (triggering the `removed` event).
374 |
375 | #### 'vanilla-nested:fields-hidden-undo'
376 |
377 | Triggered when the user undo the removal using the "undo" link.
378 |
379 | ```Javascript
380 | document.addEventListener('vanilla-nested:fields-hidden-undo', function(e){
381 | // e.type == 'vanilla-nested:fields-hidden-undo'
382 | // e.target == fields wrapper unhidden
383 | // e.detail.triggeredBy == the "undo" link
384 | })
385 | ```
386 |
387 | ## Testing
388 |
389 | You can run the tests following these commands:
390 |
391 | - cd test/VanillaNestedTests # move to the rails app dir
392 | - bin/setup # install bundler, gems and yarn packages
393 | - rails test # unit tests
394 | - rails test:system # system tests
395 |
396 | > If you make changes in the JS files, you have to tell yarn to refresh the code inside the node_modules folder running `./bin/update-gem` (or `yarn upgrade vanilla-nested` and `rails webpacker:clobber`), and then restart the rails server or re-run the tests.
397 |
398 | # Version 1.1.0 Changes
399 |
400 | #### Change the method to infere the name of the partial
401 |
402 | Before, it used `SomeClass.name.downcase`, this created a problem for classes with more than one word:
403 |
404 | - User => 'user_fields'
405 | - SomeClass => 'someclass_fields'
406 |
407 | Now it uses `SomeClass.name.underscore`:
408 |
409 | - User => 'user_fields'
410 | - SomeClass => 'some_class_fields'
411 |
412 | If you used the old version, you'll need to change the partial name or provide the old name as the `partial:` argument.
413 |
414 | #### Fix some RuboCop style suggestions
415 |
416 | Mostly single/double quotes, spacing, etc.
417 |
418 | #### Added some Solagraph related doc for the view helpers
419 |
420 | Just so Solargraph plugins on editors like VS-Code can give you some documentation.
421 |
422 | #### Added some documentation on the code
423 |
424 | Mostly on the javascript code
425 |
426 | #### Added node module config
427 |
428 | So it can be used as a node module using yarn to integrate it using webpacker.
429 |
430 | # Version 1.2.0 Changes
431 |
432 | #### New event for the "limit" option of `accepts_nested_attributes_for`
433 |
434 | You can listen to the `vanilla-nested:fields-limit-reached` event that will fire when container has more or equals the amount of children than the `limit` option set on the `accepts_nested_attributes_for` configuration.
435 |
436 | # Version 1.2.1 Changes
437 |
438 | #### Removed "onclick" attribute for helpers and add event listeners within js
439 |
440 | If you were using webpacker, remember to replace the vanilla_nested.js file in your app/javascript folder
441 |
442 | # Version 1.2.2 Changes
443 |
444 | #### Added "link_classes" option to "link_to_remove_nested"
445 |
446 | You can set multiple classes for the "X" link
447 |
448 | #### Added a "link_content" block parameter for both link helpers
449 |
450 | You can pass a block to use as the content for the add and remove links
451 |
452 | # Version 1.2.3 Changes
453 |
454 | #### Fix using nested html elements as the content for buttons
455 |
456 | There was an error when using the helpers with things like:
457 |
458 | ```erb
459 | <%= link_to_add_nested(form, :pets, '#pets') do %>
460 | Add Pet
461 | <% end %>
462 | ```
463 |
464 | It would detect the wrong element for the click event, making the JS fail.
465 |
466 | # Version 1.2.4 Changes
467 |
468 | Play nicely with Turbolinks' `turbolinks:load` event.
469 |
470 | # Version 1.2.5 Changes
471 |
472 | License change from GPL to MIT
473 |
474 | # Version 1.3.0 Changes
475 |
476 | #### Custom generated HTML element tag
477 |
478 | The default HTML tag generated by `link_to_add/remove_nested` is an `A` tag, but it can now be customized with the `tag:` keyword argument:
479 |
480 | ```erb
481 | <%= link_to_add_nested(form, :pets, '#pets', tag: 'span') %>
482 | ```
483 |
484 | #### Extra class added to dynamically added fields
485 |
486 | Elements added dynamically now have an extra `added-by-vanilla-nested` class, used internally and helpful for styling.
487 |
488 | #### Removed elements are actually removed from the document
489 |
490 | Before, the elements were just hidden using `display: none` on the wrapper. That lead to issues when the input elements had validations that were triggered by the browser but the elements where not accessible anymore. With this new version, removing a nested set of fields removes all the content.
491 |
492 | #### Correct calculation for the limit-reached event
493 |
494 | If the `accepts_nested_attributes_for` configuration has a limit, this gem was counting the number of children wrong (it was counting removed elements and extra children of the wrapper). This fixes that by only counting the `[_destroy]` hidden fields with value `0`.
495 |
496 | # Version 1.4.0 Changes
497 |
498 | #### Custom HTML attributes for the generated HTML element tag
499 |
500 | Both `link_to_add_nested` and `link_to_remove_nested` now support a `tag_attributes` keyword argument with key value pairs representing attributes and values for the generated HTML tag.
501 |
502 | You can use this to customize the tag as you need:
503 |
504 | - you can add a `title` for your `a` tag to make them more accessible:
505 |
506 | ```Ruby
507 | link_to_remove_nested(ff, link_text: 'X', tag_attributes: {title: "Delete!"})
508 | # X
509 | ```
510 |
511 | - you can set a `type`, `name` and `value` for a `button` tag if you want to have a non-javascript submit action to fallback in case the user has Javascript disabled:
512 |
513 | ```Ruby
514 | link_to_add_nested(form, :order_items, '#order-items', tag: 'button', tag_attributes: {type: 'submit', name: 'commit', value: 'add-nested' })
515 | # now you have a button tag that will submit your form with a `commit` param with `add-nested` as the value to handle a non-javascript fallback to add nested fields an re-render the form!
516 | ```
517 |
518 | - you can set any valid html attribute accepted by [`content_tag`](https://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag)
519 |
520 | # Version 1.5.0 Changes
521 |
522 | #### Added Integration with the `turbo` Gem
523 |
524 | The JavaScript part of the gem now plays nicely with the `turbo` gem by initializing the needed events when the `turbo:load` event is fired.
525 |
526 | # Version 1.5.1 Changes
527 |
528 | #### Yarn/NPM Packages
529 |
530 | Node package can be installed using npm or yarn without using the GitHub repo. This improves the size of the bundle and allows version flags.
531 |
532 | # Version 1.6.0 Changes
533 |
534 | #### Fix undeclared variables
535 |
536 | https://github.com/arielj/vanilla-nested/pull/45 thanks @gmeir.
537 |
538 | #### Added engine config to support importmaps
539 |
540 | You can pin the vanilla-nested module. A Rails 7 sample app is added to the test directory.
541 |
542 | # Version 1.6.1 Changes
543 |
544 | #### Fix elements' style after undo
545 |
546 | When undoing a removal, the gem was setting `display: initial` to all the elements. Now it sets the `display` value it had before hidding the element.
547 |
548 | > Remember to update both gem and package https://github.com/arielj/vanilla-nested#update
549 |
550 | # Version 1.6.2 Changes
551 |
552 | #### Event listeners are now added once to the `document`
553 |
554 | Attach the vanilla-nested event listeners to the document object. This fixes [issues](https://github.com/arielj/vanilla-nested/issues/47) with turbo/hotwire where the listener was not being attached to the new elements added to the DOM. Thanks to @lenilsonjr for testing these changes!
555 |
556 | # Version 1.7.0 Changes
557 |
558 | #### Fix initialization of Vanilla Nested when using importmaps and Safari
559 |
560 | The shim to support importmaps in Safari was not firing the load events as the code was expecting. This patches that by considering if the DOM is already ready when the code loads.
561 |
562 | # Version 1.7.1 Changes
563 |
564 | #### New classes added
565 |
566 | When removing a nested element, a `hidden-by-vanilla-nested` class is added if there's a timeout. The class is removed if the action is undone.
567 |
568 | When removing a nested element, a `removed-by-vanilla-nested` class is added if there's no timeout or after the timeout expires.
569 |
570 | Thanks to @kikyous for the contribution!
571 |
572 | #### Tests in multiple Ruby versions
573 |
574 | Automated tests now run in multiple Ruby versions in CI.
575 |
576 | This change has no impact in the use of the gem, but I wanted to thank @petergoldstein for their contribution!
577 |
578 | #### New `partial_locals` option for `link_to_add_nested`
579 |
580 | Now you can pass a new option with `locals` for the fields wrapper partial. Check https://github.com/arielj/vanilla-nested/pull/64 for an example. Thanks to @gregogalante for the contribution!
581 |
--------------------------------------------------------------------------------