activeadmin_dynamic_fields 0.5.0 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '019f2b81ed1552f13f57b73141860957f4869b10de1f018a289aa8724cc23ec1'
4
- data.tar.gz: 4ed1bb60f5b1ddef1a3d870296d8548faa18cc36db5adadb8271f0c655c769f6
3
+ metadata.gz: 1a0aa1741561ea938be8cfdfb7d75df0b85ba24dcdf303639ac3824ffc6ddd4f
4
+ data.tar.gz: 208287487042b2ef3de93b20f9a733383e470e44473c40b398b3600ec18f11bc
5
5
  SHA512:
6
- metadata.gz: b07cc4e73b801ef79ee52b52a6c82117d7e966a2f1eadb0e415e00c608456c02f2c14694c2fc41037ad381c9c0c3bfbf1c0ed96c0c6d13bd0ce3335c38dc1e11
7
- data.tar.gz: c0aa33df12ef6ed16927a49bb9b93d0fcffeffc6f20b661f11edb350544f12e550f90fd5fa5870a43154c0097995bbb02f2f80f24e1ff821eddc2d0fa60e613d
6
+ metadata.gz: 6817a8dccfb3691bf61cfe2f8a30d0dd51fb45b40becc20fab9b36fe9b8c573e9f78f68dc12e6c8a0e91c34d2416d773f5f3a1d62359b32e2888e68b2d19113a
7
+ data.tar.gz: 0f15dcb8b29b7cbf73ba0e6932b6a0dd42a91ca883357ea0024da13b5b65867c2cf22bcae0458967ec37f70a7667607c0cb65be8aa43b17319b83595c2ee8cbd
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # ActiveAdmin Dynamic Fields [![Gem Version](https://badge.fury.io/rb/activeadmin_dynamic_fields.svg)](https://badge.fury.io/rb/activeadmin_dynamic_fields) [![CircleCI](https://circleci.com/gh/blocknotes/activeadmin_dynamic_fields.svg?style=svg)](https://circleci.com/gh/blocknotes/activeadmin_dynamic_fields)
1
+ # ActiveAdmin Dynamic Fields
2
+ [![gem version](https://badge.fury.io/rb/activeadmin_dynamic_fields.svg)](https://badge.fury.io/rb/activeadmin_dynamic_fields) [![gem downloads](https://badgen.net/rubygems/dt/activeadmin_dynamic_fields)](https://rubygems.org/gems/activeadmin_dynamic_fields) [![linters](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/linters.yml/badge.svg)](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/linters.yml) [![specs](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/specs.yml/badge.svg)](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/specs.yml)
2
3
 
3
4
  An Active Admin plugin to add dynamic behaviors to some fields.
4
5
 
5
6
  Features:
7
+
6
8
  - set conditional checks on fields
7
9
  - trigger actions on target elements
8
10
  - inline field editing
@@ -10,19 +12,39 @@ Features:
10
12
 
11
13
  The easiest way to show how this plugin works is looking the examples [below](#examples).
12
14
 
15
+ Please :star: if you like it.
16
+
13
17
  ## Install
14
- - Add to your Gemfile: `gem 'activeadmin_dynamic_fields'`
15
- - Execute bundle
16
- - Add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
18
+
19
+ First, add the gem to your ActiveAdmin project: `gem 'activeadmin_dynamic_fields'` (and execute `bundle`)
20
+
21
+ If you installed Active Admin **without Webpacker** support:
22
+ - add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
17
23
 
18
24
  ```js
19
25
  //= require activeadmin/dynamic_fields
20
26
  ```
21
27
 
28
+ Otherwise **with Webpacker**:
29
+
30
+ - Execute in your project root:
31
+
32
+ ```sh
33
+ yarn add blocknotes/activeadmin_dynamic_fields
34
+ ```
35
+
36
+ - Add to your *app/javascript/packs/active_admin.js*:
37
+
38
+ ```js
39
+ require('activeadmin_dynamic_fields')
40
+ ```
41
+
22
42
  ## Options
43
+
23
44
  Options are passed to fields using *input_html* parameter as *data* attributes.
24
45
 
25
46
  Conditions:
47
+
26
48
  - **data-if**: check a condition, values:
27
49
  + **checked**: check if a checkbox is checked (ex. `"data-if": "checked"`)
28
50
  + **not_checked**: check if a checkbox is not checked
@@ -36,6 +58,7 @@ Conditions:
36
58
  - **data-function**: check the return value of a custom function (ex. `"data-function": "my_check"`)
37
59
 
38
60
  Actions:
61
+
39
62
  - **data-then**: action to trigger (alias **data-action**), values:
40
63
  + **hide**: hides elements (ex. `"data-then": "hide", "data-target": ".errors"`)
41
64
  + **slide**: hides elements (using sliding)
@@ -49,6 +72,7 @@ Actions:
49
72
  - **data-args**: arguments passed to the callback function
50
73
 
51
74
  Targets:
75
+
52
76
  - **data-target**: target css selector (from parent fieldset, look for the closest match)
53
77
  - **data-gtarget**: target css selector globally
54
78
 
@@ -57,6 +81,7 @@ A check condition or a custom check function are required. A trigger action is r
57
81
  ## Examples
58
82
 
59
83
  ### Dynamic fields examples
84
+
60
85
  - A checkbox that hides other fields if is checked (ex. model *Article*):
61
86
 
62
87
  ```rb
@@ -128,6 +153,7 @@ function on_change_category(el) {
128
153
  ```
129
154
 
130
155
  ### Inline editing examples
156
+
131
157
  - Prepare a custom member action to save data, an *update* helper function is available (third parameter is optional, allow to filter using strong parameters):
132
158
 
133
159
  ```rb
@@ -165,6 +191,7 @@ end
165
191
  ```
166
192
 
167
193
  ### Dialog example
194
+
168
195
  Example with 2 models: *Author* and *Article*
169
196
 
170
197
  Prepare the content dialog - in Active Admin Author config:
@@ -208,13 +235,16 @@ end
208
235
  The link url is loaded via AJAX before opening the dialog.
209
236
 
210
237
  ## Do you like it? Star it!
211
- If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
212
238
 
213
- Take a look at [other ActiveAdmin components](https://github.com/blocknotes?utf8=✓&tab=repositories&q=activeadmin&type=source) that I made if you are curious.
239
+ If you use this component just star it. A developer is more motivated to improve a project when there is some interest. My other [Active Admin components](https://github.com/blocknotes?utf8=✓&tab=repositories&q=activeadmin&type=source).
240
+
241
+ Or consider offering me a coffee, it's a small thing but it is greatly appreciated: [about me](https://www.blocknot.es/about-me).
214
242
 
215
243
  ## Contributors
244
+
216
245
  - [Mattia Roccoberton](http://blocknot.es): author
217
246
  - The good guys that opened issues and pull requests from time to time
218
247
 
219
248
  ## License
249
+
220
250
  The gem is available as open-source under the terms of the [MIT](LICENSE.txt).
data/Rakefile CHANGED
@@ -1,3 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
3
+ require 'bundler/gem_tasks'
4
+
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ # t.ruby_opts = %w[-w]
10
+ t.rspec_opts = ['--color', '--format documentation']
11
+ end
12
+
13
+ task default: :spec
14
+ rescue LoadError
15
+ puts '! LoadError: no RSpec available'
16
+ end
@@ -1,6 +1,7 @@
1
1
  (function () {
2
2
  'use strict'
3
3
 
4
+ // noinspection JSUnusedGlobalSymbols
4
5
  const ACTIONS = {
5
6
  addClass: (el, name) => el.addClass(name),
6
7
  addStyle: (el, extra_style) => {
@@ -11,7 +12,8 @@
11
12
  }
12
13
  },
13
14
  callback: (el, name) => {
14
- if (window[name]) window[name](el.data('args'))
15
+ const cb_function = window.hasOwnProperty(name) ? window[name] : null
16
+ if (typeof cb_function === 'function') cb_function(el.data('args'))
15
17
  else {
16
18
  el.attr('data-df-errors', 'callback function not found')
17
19
  console.warn(`activeadmin_dynamic_fields callback function not found: ${name}`)
@@ -21,13 +23,14 @@
21
23
  hide: el => el.hide(),
22
24
  setText: (el, text) => el.text(text),
23
25
  setValue: (el, value) => {
24
- if (el.attr('type') == 'checkbox') el.prop('checked', value == '1')
26
+ if (el.attr('type') === 'checkbox') el.prop('checked', value === '1')
25
27
  else el.val(value)
26
28
  el.trigger('change')
27
29
  },
28
30
  slide: el => el.slideUp()
29
31
  }
30
32
 
33
+ // noinspection EqualityComparisonWithCoercionJS, JSUnusedGlobalSymbols
31
34
  const CONDITIONS = {
32
35
  blank: el => el.val().length === 0 || !el.val().trim(),
33
36
  changed: _el => true,
@@ -88,12 +91,21 @@
88
91
  }
89
92
 
90
93
  evaluateCondition() {
91
- let value = CONDITIONS[this.el.data('if')?.trim()]
94
+ let data_if = this.el.data('if')
95
+ let value = data_if ? CONDITIONS[data_if.trim()] : null
92
96
  if (value) return { condition: value }
93
- if (value = this.el.data('eq')) return { condition: CONDITIONS['eq'], condition_arg: value }
94
- if (value = this.el.data('not')) return { condition: CONDITIONS['not'], condition_arg: value }
95
- if (value = this.el.data('match')) return { condition: CONDITIONS['match'], condition_arg: new RegExp(value) }
96
- if (value = this.el.data('mismatch')) return { condition: CONDITIONS['mismatch'], condition_arg: new RegExp(value) }
97
+
98
+ value = this.el.data('eq')
99
+ if (value) return { condition: CONDITIONS['eq'], condition_arg: value }
100
+
101
+ value = this.el.data('not')
102
+ if (value) return { condition: CONDITIONS['not'], condition_arg: value }
103
+
104
+ value = this.el.data('match')
105
+ if (value) return { condition: CONDITIONS['match'], condition_arg: new RegExp(value) }
106
+
107
+ value = this.el.data('mismatch')
108
+ if (value) return { condition: CONDITIONS['mismatch'], condition_arg: new RegExp(value) }
97
109
 
98
110
  this.custom_function = this.el.data('function')
99
111
  if (this.custom_function) {
@@ -112,32 +124,30 @@
112
124
  // closest find for has many associations
113
125
  if (this.el.data('target')) this.target = this.el.closest('fieldset').find(this.el.data('target'))
114
126
  else if (this.el.data('gtarget')) this.target = $(this.el.data('gtarget'))
115
- if (action_name == 'callback') this.target = this.el
127
+ if (action_name === 'callback') this.target = this.el
116
128
  }
117
129
 
118
130
  isValid() {
119
131
  if (!this.condition) return false
120
- if (!this.action && !this.custom_function) return false
121
-
122
- return true
132
+ return (this.action || this.custom_function)
123
133
  }
124
134
 
125
135
  setup() {
126
136
  if (!this.isValid()) return
127
- if (this.el.data('if') != 'changed') this.apply()
137
+ if (this.el.data('if') !== 'changed') this.apply()
128
138
  this.el.on('change', () => this.apply())
129
139
  }
130
140
  }
131
141
 
132
- // Inline update - must be called binded on the editing element
142
+ // Inline update - must be called bound on the editing element
133
143
  function dfUpdateField() {
134
- if ($(this).data('loading') != '1') {
144
+ if ($(this).data('loading') !== '1') {
135
145
  $(this).data('loading', '1');
136
146
  let _this = $(this);
137
147
  let type = $(this).data('field-type');
138
148
  let new_value;
139
- if (type == 'boolean') new_value = !$(this).data('field-value');
140
- else if (type == 'select') new_value = $(this).val();
149
+ if (type === 'boolean') new_value = !$(this).data('field-value');
150
+ else if (type === 'select') new_value = $(this).val();
141
151
  else new_value = $(this).text();
142
152
  let data = {};
143
153
  data[$(this).data('field')] = new_value;
@@ -146,16 +156,16 @@
146
156
  data: { data: data },
147
157
  method: 'POST',
148
158
  url: $(this).data('save-url'),
149
- complete: function (req, status) {
159
+ complete: function (_req, _status) {
150
160
  $(this).data('loading', '0');
151
161
  },
152
- success: function (data, status, req) {
153
- if (data.status == 'error') {
162
+ success: function (data, _status, _req) {
163
+ if (data.status === 'error') {
154
164
  if ($(this).data('show-errors')) {
155
165
  let result = '';
156
166
  let message = data.message;
157
167
  for (let key in message) {
158
- if (typeof (message[key]) === 'object') {
168
+ if (message.hasOwnProperty(key) && typeof (message[key]) === 'object') {
159
169
  if (result) result += ' - ';
160
170
  result += key + ': ' + message[key].join('; ');
161
171
  }
@@ -181,8 +191,7 @@
181
191
  }
182
192
  }
183
193
 
184
- // Init
185
- $(document).ready(function () {
194
+ function dfInit() {
186
195
  // Setup dynamic fields
187
196
  const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-match], .active_admin .input [data-mismatch], .active_admin .input [data-function]'
188
197
  $(selectors).each(function () {
@@ -205,20 +214,23 @@
205
214
  $('.active_admin [data-df-dialog]').on('click', function (event) {
206
215
  event.preventDefault()
207
216
  $(this).blur()
208
- if ($('#df-dialog').data('loading') != '1') {
209
- $('#df-dialog').data('loading', '1')
210
- if ($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>')
217
+ const df_dialog = $('#df-dialog')
218
+
219
+ if (df_dialog.data('loading') !== '1') {
220
+ df_dialog.data('loading', '1')
221
+ if (df_dialog.length === 0) $('body').append('<div id="df-dialog"></div>')
211
222
  let title = $(this).attr('title')
212
223
  $.ajax({
213
224
  url: $(this).attr('href'),
214
- complete: function (req, status) {
225
+ complete: function (_req, _status) {
215
226
  $('#df-dialog').data('loading', '0')
216
227
  },
217
- success: function (data, status, req) {
218
- if (title) $('#df-dialog').attr('title', title)
219
- $('#df-dialog').html(data)
220
- $('#df-dialog').dialog({ modal: true })
221
- },
228
+ success: function (data, _status, _req) {
229
+ const dialog = $('#df-dialog')
230
+ if (title) dialog.attr('title', title)
231
+ dialog.html(data)
232
+ dialog.dialog({ modal: true })
233
+ }
222
234
  })
223
235
  }
224
236
  })
@@ -231,11 +243,14 @@
231
243
  $(this).data('field-value', $(this).text())
232
244
  let fnUpdate = $.proxy(dfUpdateField, $(this))
233
245
  $(this).on('blur', function () {
234
- if ($(this).data('field-value') != $(this).text()) fnUpdate()
246
+ if ($(this).data('field-value') !== $(this).text()) fnUpdate()
235
247
  })
236
248
  })
237
249
  $('[data-field][data-field-type="select"][data-save-url]').each(function () {
238
250
  $(this).on('change', $.proxy(dfUpdateField, $(this)))
239
251
  })
240
- })
252
+ }
253
+
254
+ $(document).ready(dfInit)
255
+ $(document).on('turbolinks:load', dfInit)
241
256
  })()
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveAdmin
4
4
  module DynamicFields
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.4'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin_dynamic_fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-04 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin
@@ -25,131 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activestorage
28
+ name: appraisal
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 6.0.3.2
33
+ version: '2.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 6.0.3.2
41
- - !ruby/object:Gem::Dependency
42
- name: capybara
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 3.33.0
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 3.33.0
55
- - !ruby/object:Gem::Dependency
56
- name: pry
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 0.13.1
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 0.13.1
69
- - !ruby/object:Gem::Dependency
70
- name: puma
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 4.3.5
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 4.3.5
83
- - !ruby/object:Gem::Dependency
84
- name: rspec_junit_formatter
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.4.1
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.4.1
97
- - !ruby/object:Gem::Dependency
98
- name: rspec-rails
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 4.0.1
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 4.0.1
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: 0.90.0
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 0.90.0
125
- - !ruby/object:Gem::Dependency
126
- name: selenium-webdriver
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 3.142.7
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 3.142.7
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 1.4.2
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 1.4.2
40
+ version: '2.4'
153
41
  description: An Active Admin plugin to add dynamic behaviors to fields
154
42
  email: mat@blocknot.es
155
43
  executables: []
@@ -167,7 +55,10 @@ files:
167
55
  homepage: https://github.com/blocknotes/activeadmin_dynamic_fields
168
56
  licenses:
169
57
  - MIT
170
- metadata: {}
58
+ metadata:
59
+ homepage_uri: https://github.com/blocknotes/activeadmin_dynamic_fields
60
+ source_code_uri: https://github.com/blocknotes/activeadmin_dynamic_fields
61
+ rubygems_mfa_required: 'true'
171
62
  post_install_message:
172
63
  rdoc_options: []
173
64
  require_paths:
@@ -183,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
74
  - !ruby/object:Gem::Version
184
75
  version: '0'
185
76
  requirements: []
186
- rubygems_version: 3.0.3
77
+ rubygems_version: 3.1.6
187
78
  signing_key:
188
79
  specification_version: 4
189
80
  summary: Dynamic fields for ActiveAdmin