|
1 | 1 | (function () { |
2 | 2 | 'use strict' |
3 | 3 |
|
4 | | - // Evaluate a condition |
5 | | - function dfEvalCondition(el, args, on_change) { |
6 | | - if (args.fn) { |
7 | | - if (args.fn && window[args.fn]) return !window[args.fn](el); |
8 | | - else console.log('Warning - activeadmin_dynamic_fields: ' + args.fn + '() not available [1]'); |
9 | | - } |
10 | | - else if (args.if == 'checked') { |
11 | | - return el.is(':checked'); |
12 | | - } |
13 | | - else if (args.if == 'not_checked') { |
14 | | - return !el.is(':checked'); |
15 | | - } |
16 | | - else if (args.if == 'blank') { |
17 | | - return el.val().length === 0 || !el.val().trim(); |
18 | | - } |
19 | | - else if (args.if == 'not_blank') { |
20 | | - return el.val().length !== 0 && el.val().trim(); |
21 | | - } |
22 | | - else if (args.if == 'changed') { |
23 | | - return on_change; |
24 | | - } |
25 | | - else if (args.eq) { |
26 | | - return el.val() == args.eq; |
27 | | - } |
28 | | - else if (args.not) { |
29 | | - return el.val() != args.not; |
30 | | - } |
| 4 | + const ACTIONS = { |
| 5 | + addClass: (el, name) => el.addClass(name), |
| 6 | + callback: (el, name) => { |
| 7 | + if (window[name]) window[name](el.data('args')) |
| 8 | + else { |
| 9 | + el.attr('data-df-errors', 'callback function not found') |
| 10 | + console.warn(`activeadmin_dynamic_fields callback function not found: ${name}`) |
| 11 | + } |
| 12 | + }, |
| 13 | + fade: el => el.fadeOut(), |
| 14 | + hide: el => el.hide(), |
| 15 | + setValue: (el, value) => dfSetValue(el, value), |
| 16 | + slide: el => el.slideUp() |
| 17 | + } |
31 | 18 |
|
32 | | - return undefined; |
| 19 | + const CONDITIONS = { |
| 20 | + blank: el => el.val().length === 0 || !el.val().trim(), |
| 21 | + changed: _el => true, |
| 22 | + checked: el => el.is(':checked'), |
| 23 | + eq: (el, value) => el.val() == value, |
| 24 | + not: (el, value) => el.val() != value, |
| 25 | + not_blank: el => el.val().trim(), |
| 26 | + not_checked: el => !el.is(':checked') |
33 | 27 | } |
34 | 28 |
|
35 | | - // Prepare a field |
36 | | - function dfSetupField(el) { |
37 | | - let action = el.data('then') || el.data('action'); |
38 | | - let target, args = {}; |
39 | | - |
40 | | - args.if = el.data('if'); |
41 | | - args.eq = el.data('eq'); |
42 | | - args.not = el.data('not'); |
43 | | - args.fn = el.data('function'); |
44 | | - if (el.data('target')) target = el.closest('fieldset').find(el.data('target')); // closest find for has many associations |
45 | | - else if (el.data('gtarget')) target = $(el.data('gtarget')); |
46 | | - |
47 | | - if (action == 'hide') { |
48 | | - if (dfEvalCondition(el, args, false)) target.hide(); |
49 | | - else target.show(); |
50 | | - el.on('change', function (event) { |
51 | | - if (dfEvalCondition($(this), args, true)) target.hide(); |
52 | | - else target.show(); |
53 | | - }); |
54 | | - } |
55 | | - else if (action == 'slide') { |
56 | | - if (dfEvalCondition(el, args, false)) target.slideDown(); |
57 | | - else target.slideUp(); |
58 | | - el.on('change', function (event) { |
59 | | - if (dfEvalCondition($(this), args, true)) target.slideDown(); |
60 | | - else target.slideUp(); |
61 | | - }); |
62 | | - } |
63 | | - else if (action == 'fade') { |
64 | | - if (dfEvalCondition(el, args, false)) target.fadeIn(); |
65 | | - else target.fadeOut(); |
66 | | - el.on('change', function (event) { |
67 | | - if (dfEvalCondition($(this), args, true)) target.fadeIn(); |
68 | | - else target.fadeOut(); |
69 | | - }); |
70 | | - } |
71 | | - else if (action.substr(0, 8) == 'setValue') { |
72 | | - let val = action.substr(8).trim(); |
73 | | - if (dfEvalCondition(el, args, false)) dfSetValue(target, val); |
74 | | - el.on('change', function (event) { |
75 | | - if (dfEvalCondition($(this), args, true)) dfSetValue(target, val); |
76 | | - }); |
77 | | - } |
78 | | - else if (action.substr(0, 8) == 'callback') { |
79 | | - let cb = action.substr(8).trim(); |
80 | | - if (cb && window[cb]) { |
81 | | - if (dfEvalCondition(el, args, false)) window[cb](el.data('args')); |
82 | | - el.on('change', function (event) { |
83 | | - if (dfEvalCondition($(this), args, true)) window[cb](el.data('args')); |
84 | | - }); |
| 29 | + const REVERSE_ACTIONS = { |
| 30 | + addClass: (el, name) => el.removeClass(name), |
| 31 | + fade: el => el.fadeIn(), |
| 32 | + hide: el => el.show(), |
| 33 | + slide: el => el.slideDown() |
| 34 | + } |
| 35 | + |
| 36 | + function dfEvalCondition(el) { |
| 37 | + let condition = CONDITIONS[el.data('if')] |
| 38 | + let condition_arg |
| 39 | + |
| 40 | + if(!condition && el.data('eq')) { |
| 41 | + condition = CONDITIONS['eq'] |
| 42 | + condition_arg = el.data('eq') |
| 43 | + } |
| 44 | + if(!condition && el.data('not')) { |
| 45 | + condition = CONDITIONS['not'] |
| 46 | + condition_arg = el.data('not') |
| 47 | + } |
| 48 | + if(!condition && el.data('function')) { |
| 49 | + condition = window[el.data('function')] |
| 50 | + if(!condition) { |
| 51 | + el.attr('data-df-errors', 'custom function not found') |
| 52 | + console.warn(`activeadmin_dynamic_fields custom function not found: ${el.data('function')}`) |
85 | 53 | } |
86 | | - else console.log('Warning - activeadmin_dynamic_fields: ' + cb + '() not available [2]'); |
87 | | - } |
88 | | - else if (action.substr(0, 8) == 'addClass') { |
89 | | - let classes = action.substr(8).trim(); |
90 | | - if (dfEvalCondition(el, args, false)) target.removeClass(classes); |
91 | | - else target.addClass(classes); |
92 | | - el.on('change', function (event) { |
93 | | - if (dfEvalCondition($(this), args, true)) target.removeClass(classes); |
94 | | - else target.addClass(classes); |
95 | | - }); |
96 | | - } |
97 | | - else if (args.fn) { // function without action |
98 | | - dfEvalCondition(el, args, false); |
99 | | - el.on('change', function (event) { |
100 | | - dfEvalCondition(el, args, true); |
101 | | - }); |
102 | 54 | } |
| 55 | + |
| 56 | + return [condition, condition_arg] |
| 57 | + } |
| 58 | + |
| 59 | + function dfInitField(el) { |
| 60 | + const [condition, condition_arg] = dfEvalCondition(el) |
| 61 | + const action_name = (el.data('then') || el.data('action') || '').substr(0, 8) |
| 62 | + const action = ACTIONS[action_name] |
| 63 | + const arg = (el.data('then') || el.data('action') || '').substr(9) |
| 64 | + const reverse_action = REVERSE_ACTIONS[action_name] |
| 65 | + if (typeof condition === 'undefined') return |
| 66 | + if (typeof action === 'undefined' && !el.data('function')) return |
| 67 | + |
| 68 | + // closest find for has many associations |
| 69 | + let target |
| 70 | + if (el.data('target')) target = el.closest('fieldset').find(el.data('target')) |
| 71 | + else if (el.data('gtarget')) target = $(el.data('gtarget')) |
| 72 | + if (action_name == 'callback') target = el |
| 73 | + |
| 74 | + if (condition(el, condition_arg) && el.data('if') != 'changed') action(target, arg) |
| 75 | + else if (reverse_action) reverse_action(target, arg) |
| 76 | + |
| 77 | + el.on('change', () => { |
| 78 | + if (condition(el, condition_arg)) action(target, arg) |
| 79 | + else if (reverse_action) reverse_action(target, arg) |
| 80 | + }) |
103 | 81 | } |
104 | 82 |
|
105 | 83 | // Set the value of an element |
106 | 84 | function dfSetValue(el, val) { |
107 | | - if (el.attr('type') != 'checkbox') el.val(val); |
108 | | - else el.prop('checked', val == '1'); |
109 | | - el.trigger('change'); |
| 85 | + if (el.attr('type') == 'checkbox') el.prop('checked', val == '1') |
| 86 | + else el.val(val) |
| 87 | + el.trigger('change') |
110 | 88 | } |
111 | 89 |
|
112 | 90 | // Inline update - must be called binded on the editing element |
|
164 | 142 | // Init |
165 | 143 | $(document).ready(function () { |
166 | 144 | // Setup dynamic fields |
167 | | - $('.active_admin .input [data-if], .active_admin .input [data-function], .active_admin .input [data-eq], .active_admin .input [data-not]').each(function () { |
168 | | - dfSetupField($(this)); |
169 | | - }); |
170 | | - // Setup dynamic fields for has many associations |
171 | | - $('.active_admin .has_many_container').on('has_many_add:after', function (e, fieldset, container) { |
172 | | - $('.active_admin .input [data-if], .active_admin .input [data-function], .active_admin .input [data-eq], .active_admin .input [data-not]').each(function () { |
173 | | - dfSetupField($(this)); |
174 | | - }); |
175 | | - }); |
| 145 | + const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-function]' |
| 146 | + $(selectors).each(function () { |
| 147 | + dfInitField($(this)) |
| 148 | + }) |
| 149 | + |
| 150 | + // Setup dynamic fields for associations |
| 151 | + $('.active_admin .has_many_container').on('has_many_add:after', () => { |
| 152 | + $(selectors).each(function () { |
| 153 | + dfInitField($(this)) |
| 154 | + }) |
| 155 | + }) |
| 156 | + |
176 | 157 | // Set dialog icon link |
177 | 158 | $('.active_admin [data-df-icon]').each(function () { |
178 | | - $(this).append(' »'); // ' •' |
179 | | - }); |
| 159 | + $(this).append(' »') |
| 160 | + }) |
| 161 | + |
180 | 162 | // Open content in dialog |
181 | 163 | $('.active_admin [data-df-dialog]').on('click', function (event) { |
182 | | - event.preventDefault(); |
183 | | - $(this).blur(); |
| 164 | + event.preventDefault() |
| 165 | + $(this).blur() |
184 | 166 | if ($('#df-dialog').data('loading') != '1') { |
185 | | - $('#df-dialog').data('loading', '1'); |
186 | | - if ($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>'); |
187 | | - let title = $(this).attr('title'); |
| 167 | + $('#df-dialog').data('loading', '1') |
| 168 | + if ($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>') |
| 169 | + let title = $(this).attr('title') |
188 | 170 | $.ajax({ |
189 | 171 | url: $(this).attr('href'), |
190 | 172 | complete: function (req, status) { |
191 | | - $('#df-dialog').data('loading', '0'); |
| 173 | + $('#df-dialog').data('loading', '0') |
192 | 174 | }, |
193 | 175 | success: function (data, status, req) { |
194 | | - if (title) $('#df-dialog').attr('title', title); |
195 | | - $('#df-dialog').html(data); |
196 | | - $('#df-dialog').dialog({ modal: true }); |
| 176 | + if (title) $('#df-dialog').attr('title', title) |
| 177 | + $('#df-dialog').html(data) |
| 178 | + $('#df-dialog').dialog({ modal: true }) |
197 | 179 | }, |
198 | | - }); |
| 180 | + }) |
199 | 181 | } |
200 | | - }); |
| 182 | + }) |
201 | 183 |
|
202 | 184 | // Inline editing |
203 | 185 | $('[data-field][data-field-type="boolean"][data-save-url]').each(function () { |
204 | | - $(this).on('click', $.proxy(dfUpdateField, $(this))); |
205 | | - }); |
| 186 | + $(this).on('click', $.proxy(dfUpdateField, $(this))) |
| 187 | + }) |
206 | 188 | $('[data-field][data-field-type="string"][data-save-url]').each(function () { |
207 | | - $(this).data('field-value', $(this).text()); |
208 | | - let fnUpdate = $.proxy(dfUpdateField, $(this)); |
| 189 | + $(this).data('field-value', $(this).text()) |
| 190 | + let fnUpdate = $.proxy(dfUpdateField, $(this)) |
209 | 191 | $(this).on('blur', function () { |
210 | | - if ($(this).data('field-value') != $(this).text()) fnUpdate(); |
211 | | - }); |
212 | | - }); |
| 192 | + if ($(this).data('field-value') != $(this).text()) fnUpdate() |
| 193 | + }) |
| 194 | + }) |
213 | 195 | $('[data-field][data-field-type="select"][data-save-url]').each(function () { |
214 | | - $(this).on('change', $.proxy(dfUpdateField, $(this))); |
215 | | - }); |
216 | | - }); |
| 196 | + $(this).on('change', $.proxy(dfUpdateField, $(this))) |
| 197 | + }) |
| 198 | + }) |
217 | 199 | })() |
0 commit comments