diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5b63966..401ce06 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -38,9 +38,9 @@ _Tell us what happens instead_ - [ ] I confirm that my browser's development console output does not contain errors ### Additional JavaScript Libraries* -_If your issue depends on other JavaScript libraries, please list them here. E.g: *Bootstrap Modal v3.3.7, jQuery UI Datepicker 1.12.4*._ +_If your issue depends on other JavaScript libraries, please list them here. E.g. Bootstrap Modal v3.3.7, flatpickr 4.6.13._ -### Repository demostrating the issue +### Repository demonstrating the issue Debugging CSV issues is a time consuming task. If you want to speed up things, please provide a link to a repository showing the issue. diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 60297bf..5bff5b3 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -16,12 +16,12 @@ jobs: strategy: matrix: ruby-version: ['3.2', '3.3', '3.4', '4.0'] - gemfile: [ csv_23.0 ] + gemfile: [ csv_24.0 ] channel: ['stable'] include: - ruby-version: 'head' - gemfile: csv_23.0 + gemfile: csv_24.0 channel: 'experimental' - ruby-version: '3.2' gemfile: csv_edge diff --git a/.rubocop.yml b/.rubocop.yml index 248033a..4f08b2e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -61,3 +61,7 @@ Style/Documentation: Style/IfUnlessModifier: Enabled: false + +Style/OneClassPerFile: + Exclude: + - 'test/**/*' diff --git a/Appraisals b/Appraisals index aebb5d4..ab2f369 100644 --- a/Appraisals +++ b/Appraisals @@ -1,7 +1,7 @@ # frozen_string_literal: true -appraise 'csv-23.0' do - gem 'client_side_validations', '~> 23.0' +appraise 'csv-24.0' do + gem 'client_side_validations', '~> 24.0' end appraise 'csv-edge' do diff --git a/CHANGELOG.md b/CHANGELOG.md index 91bd369..f83be72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 18.0.0 / 2026-04-19 + +* [FEATURE] Breaking change: Align the Simple Form JavaScript hooks with the DOM-first `ClientSideValidations` runtime +* [ENHANCEMENT] Remove jQuery-specific assumptions from the browser test harness and documentation + ## 17.0.0 / 2026-01-07 * [FEATURE] Drop Internet Explorer and other older browsers support diff --git a/README.md b/README.md index 1181f7b..3fc0def 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,11 @@ required **before** `client_side_validations-simple_form`. Instructions depend on your technology stack. +This package extends the jQuery-free, DOM-first `ClientSideValidations` runtime. + #### When using Webpacker #### -Make sure that you are requiring jQuery and Client Side Validations. +Make sure that you are requiring Client Side Validations before the Simple Form plugin. Add the following package: @@ -58,7 +60,7 @@ require('@client-side-validations/simple-form/dist/simple-form.bootstrap4.esm') #### When using Sprockets #### -Make sure that you are requiring jQuery and Client Side Validations. +Make sure that you are requiring Client Side Validations before the Simple Form plugin. According to the web framework you are using, add **one** of the following lines to your `app/assets/javascripts/application.js`, **after** @@ -80,6 +82,18 @@ rails g client_side_validations:copy_assets Note: If you run `copy_assets`, you will need to run it again each time you update this project. +## Migration Guide ## + +### Removing jQuery Dependency ### + +`client_side_validations-simple_form` now plugs into the DOM-first `ClientSideValidations` runtime and no longer assumes jQuery is present. + +Follow the main `ClientSideValidations` migration guide for the public API changes. In particular, load the current DOM-first `ClientSideValidations` bundle before loading this package, and update any custom code that still expects jQuery-wrapped objects. + +Custom Simple Form builders now receive native DOM elements in their `add` and `remove` hooks, so custom overrides should use DOM APIs such as `.closest()`, `.querySelector()`, and `.classList`. + +If you vendor the compiled assets with `rails g client_side_validations:copy_assets`, run that generator again after upgrading so the copied Simple Form assets stay in sync with the current `ClientSideValidations` bundle. + ## Usage ## The usage is the same as `ClientSideValidations`, just pass `validate: true` to the form builder diff --git a/client_side_validations-simple_form.gemspec b/client_side_validations-simple_form.gemspec index 5ee7ba4..b8971df 100644 --- a/client_side_validations-simple_form.gemspec +++ b/client_side_validations-simple_form.gemspec @@ -27,6 +27,6 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 3.2' - spec.add_dependency 'client_side_validations', '>= 23.0' + spec.add_dependency 'client_side_validations', '>= 24.0' spec.add_dependency 'simple_form', '>= 5.4' end diff --git a/dist/simple-form.bootstrap4.esm.js b/dist/simple-form.bootstrap4.esm.js index 51a41d0..e1d6ebd 100644 --- a/dist/simple-form.bootstrap4.esm.js +++ b/dist/simple-form.bootstrap4.esm.js @@ -1,5 +1,5 @@ /*! - * Client Side Validations Simple Form JS (Default) - v17.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) + * Client Side Validations Simple Form JS (Default) - v18.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) * Copyright (c) 2026 Geremia Taglialatela, Brian Cardarella * Licensed under MIT (https://opensource.org/licenses/mit-license.php) */ @@ -18,11 +18,11 @@ const removeClass = (element, customClass) => { }; ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message); + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message); }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings); + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings); }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default; diff --git a/dist/simple-form.bootstrap4.js b/dist/simple-form.bootstrap4.js index 9660d50..4044985 100644 --- a/dist/simple-form.bootstrap4.js +++ b/dist/simple-form.bootstrap4.js @@ -1,5 +1,5 @@ /*! - * Client Side Validations Simple Form JS (Bootstrap 4+) - v17.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) + * Client Side Validations Simple Form JS (Bootstrap 4+) - v18.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) * Copyright (c) 2026 Geremia Taglialatela, Brian Cardarella * Licensed under MIT (https://opensource.org/licenses/mit-license.php) */ @@ -22,11 +22,11 @@ }; ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message); + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message); }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings); + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings); }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default; diff --git a/dist/simple-form.esm.js b/dist/simple-form.esm.js index d8c469d..25ca17e 100644 --- a/dist/simple-form.esm.js +++ b/dist/simple-form.esm.js @@ -1,5 +1,5 @@ /*! - * Client Side Validations Simple Form JS (Default) - v17.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) + * Client Side Validations Simple Form JS (Default) - v18.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) * Copyright (c) 2026 Geremia Taglialatela, Brian Cardarella * Licensed under MIT (https://opensource.org/licenses/mit-license.php) */ @@ -18,11 +18,11 @@ const removeClass = (element, customClass) => { }; ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message); + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message); }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings); + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings); }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default; diff --git a/dist/simple-form.js b/dist/simple-form.js index bdc9814..51e0017 100644 --- a/dist/simple-form.js +++ b/dist/simple-form.js @@ -1,5 +1,5 @@ /*! - * Client Side Validations Simple Form JS (Default) - v17.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) + * Client Side Validations Simple Form JS (Default) - v18.0.0 (https://github.com/DavyJonesLocker/client_side_validations-simple_form) * Copyright (c) 2026 Geremia Taglialatela, Brian Cardarella * Licensed under MIT (https://opensource.org/licenses/mit-license.php) */ @@ -22,11 +22,11 @@ }; ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message); + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message); }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings); + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings); }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default; diff --git a/gemfiles/csv_23.0.gemfile b/gemfiles/csv_24.0.gemfile similarity index 90% rename from gemfiles/csv_23.0.gemfile rename to gemfiles/csv_24.0.gemfile index 384ac3a..fddb0eb 100644 --- a/gemfiles/csv_23.0.gemfile +++ b/gemfiles/csv_24.0.gemfile @@ -19,6 +19,6 @@ gem "simplecov" gem "simplecov-lcov" gem "sinatra" gem "webrick" -gem "client_side_validations", "~> 23.0" +gem "client_side_validations", "~> 24.0" gemspec path: "../" diff --git a/lib/client_side_validations/simple_form/version.rb b/lib/client_side_validations/simple_form/version.rb index dd3a8c9..e469b80 100644 --- a/lib/client_side_validations/simple_form/version.rb +++ b/lib/client_side_validations/simple_form/version.rb @@ -2,6 +2,6 @@ module ClientSideValidations module SimpleForm - VERSION = '17.0.0' + VERSION = '18.0.0' end end diff --git a/package.json b/package.json index 3a7b6ba..804726a 100644 --- a/package.json +++ b/package.json @@ -23,20 +23,20 @@ "test": "test/javascript/run-qunit.mjs" }, "devDependencies": { - "@babel/core": "^7.28.5", - "@babel/preset-env": "^7.28.5", + "@babel/core": "^7.29.0", + "@babel/preset-env": "^7.29.2", "@rollup/plugin-babel": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "chrome-launcher": "^1.2.1", "eslint": "^9.39.2", "eslint-plugin-compat": "^6.0.2", - "neostandard": "^0.12.2", - "puppeteer-core": "^24.34.0", - "rollup": "^4.55.1", + "neostandard": "^0.13.0", + "puppeteer-core": "^24.41.0", + "rollup": "^4.60.2", "rollup-plugin-copy": "^3.5.0" }, "peerDependencies": { - "@client-side-validations/client-side-validations": ">=23.0.0" + "@client-side-validations/client-side-validations": ">=24.0.0" }, "main": "dist/simple-form.js", "module": "dist/simple-form.esm.js", @@ -66,7 +66,7 @@ "/vendor/" ] }, - "version": "17.0.0", + "version": "18.0.0", "directories": { "lib": "lib", "test": "test" diff --git a/src/index.bootstrap4.js b/src/index.bootstrap4.js index 2b747ae..e8b7cb3 100644 --- a/src/index.bootstrap4.js +++ b/src/index.bootstrap4.js @@ -2,11 +2,11 @@ import ClientSideValidations from '@client-side-validations/client-side-validati import { addClass, removeClass } from './utils' ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message) + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message) }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings) + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings) }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default diff --git a/src/index.js b/src/index.js index eac92fa..3df2711 100644 --- a/src/index.js +++ b/src/index.js @@ -2,11 +2,11 @@ import ClientSideValidations from '@client-side-validations/client-side-validati import { addClass, removeClass } from './utils' ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = { - add: function ($element, settings, message) { - this.wrapper(settings.wrapper).add.call(this, $element[0], settings, message) + add: function (element, settings, message) { + this.wrapper(settings.wrapper).add.call(this, element, settings, message) }, - remove: function ($element, settings) { - this.wrapper(settings.wrapper).remove.call(this, $element[0], settings) + remove: function (element, settings) { + this.wrapper(settings.wrapper).remove.call(this, element, settings) }, wrapper: function (name) { return this.wrappers[name] || this.wrappers.default diff --git a/test/javascript/public/test/form_builders/validateSimpleForm.js b/test/javascript/public/test/form_builders/validateSimpleForm.js index a322e42..c03b093 100644 --- a/test/javascript/public/test/form_builders/validateSimpleForm.js +++ b/test/javascript/public/test/form_builders/validateSimpleForm.js @@ -1,3 +1,5 @@ +var currentFormBuilder + QUnit.module('Validate SimpleForm', { before: function () { currentFormBuilder = window.ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] @@ -9,6 +11,12 @@ QUnit.module('Validate SimpleForm', { }, beforeEach: function () { + var fixture = document.getElementById('qunit-fixture') + var form = document.createElement('form') + var wrapper = document.createElement('div') + var input = document.createElement('input') + var label = document.createElement('label') + dataCsv = { html_settings: { type: 'SimpleForm::FormBuilder', @@ -20,70 +28,92 @@ QUnit.module('Validate SimpleForm', { wrapper: 'default' }, validators: { - 'user[name]': { presence: [{ message: 'must be present' }], format: [{ message: 'is invalid', 'with': { options: 'g', source: '\\d+' } }] } + 'user[name]': { presence: [{ message: 'must be present' }], format: [{ message: 'is invalid', with: { options: 'g', source: '\\d+' } }] } } } - $('#qunit-fixture') - .append($('