PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.6.0
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.6.0
3.6.0 3.5.3 3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / assets / js / admin / form-builder.js
everest-forms / assets / js / admin Last commit date
admin.js 2 months ago admin.min.js 2 months ago chart.js 2 years ago chart.min.js 1 year ago customize-controls.js 1 year ago customize-controls.min.js 1 year ago customize-preview.js 1 year ago customize-preview.min.js 1 year ago deactivation-feedback.js 2 years ago deactivation-feedback.min.js 2 years ago editor.js 8 years ago editor.min.js 5 years ago everest-forms-survey-polls-quiz-builder.js 2 years ago everest-forms-survey-polls-quiz-builder.min.js 2 years ago evf-admin-email.js 2 years ago evf-admin-email.min.js 1 year ago evf-clipboard.js 8 years ago evf-clipboard.min.js 8 years ago evf-enhanced-select.js 3 years ago evf-enhanced-select.min.js 2 years ago evf-file-uploader.js 2 years ago evf-file-uploader.min.js 2 years ago evf-setup.js 2 years ago evf-setup.min.js 2 years ago extensions.js 3 years ago extensions.min.js 2 years ago form-builder.js 2 days ago form-builder.min.js 2 days ago form-template-controller.js 3 years ago form-template-controller.min.js 3 years ago printThis.min.js 2 years ago progressbar.js 2 years ago progressbar.min.js 1 year ago randomColor.js 2 years ago randomColor.min.js 2 years ago settings.js 1 week ago settings.min.js 1 week ago shortcode-form-embed.js 2 years ago shortcode-form-embed.min.js 2 years ago tool-import-entries.js 2 years ago tool-import-entries.min.js 2 years ago tools.js 2 months ago tools.min.js 2 months ago upgrade.js 2 months ago upgrade.min.js 2 months ago
form-builder.js
9101 lines
1 /* global evf_data, jconfirm, PerfectScrollbar, evfSetClipboard, evfClearClipboard */
2 (function ($, evf_data) {
3 var $builder;
4 var evfStyleTabBaseline = null;
5
6 var EVFPanelBuilder = {
7 /**
8 * Start the panel builder.
9 */
10 init: function () {
11 $(document).ready(function ($) {
12 if (!$('evf-panel-integrations-button a').hasClass('active')) {
13 $('#everest-forms-panel-integrations')
14 .find('.everest-forms-panel-sidebar a')
15 .first()
16 .addClass('active');
17 if (
18 $('#everest-forms-panel-integrations')
19 .find('.everest-forms-panel-sidebar a')
20 .hasClass('active')
21 ) {
22 $('#everest-forms-panel-integrations')
23 .find('.everest-forms-panel-sidebar a')
24 .next('.everest-forms-active-connections')
25 .first()
26 .addClass('active');
27 }
28 $('.everest-forms-panel-content')
29 .find('.evf-panel-content-section')
30 .first()
31 .addClass('active');
32 }
33
34 //To remove script tag.
35 $(document).on(
36 'input change',
37 '.everest-forms-field-option-row-choices input[name$="[label]"]',
38 function (e) {
39 var $value = $(this).val();
40 $(this).val(
41 $value.replace(/<\s*script/gi, '').replace(/\s+on\w+\s*=/gi, ' '),
42 );
43 },
44 );
45
46 $(document).on(
47 'input change',
48 'input[name$="[required-field-message]"]',
49 function (e) {
50 var $value = $(this).val();
51
52 const htmlTagPattern = /<[^>]*>/;
53 const htmlEntityPattern = /&[a-zA-Z0-9#]+;/;
54
55 if (htmlTagPattern.test($value) || htmlEntityPattern.test($value)) {
56 $(this).val('');
57 } else {
58 $(this).val(
59 $value
60 .replace(/<\s*script/gi, '')
61 .replace(/\s+on\w+\s*=/gi, ' '),
62 );
63 }
64 },
65 );
66
67 $(document).on(
68 'click',
69 '.back-button, [href*="evf-builder"]:not([href*="form_id"])',
70 function (e) {
71 if (!window.location.search.includes('form_id')) {
72 return;
73 }
74 e.preventDefault();
75 window.location.href =
76 window.location.origin +
77 window.location.pathname +
78 '?page=evf-builder';
79 },
80 );
81
82 /**
83 * Disable row when form is disabled.
84 *
85 * @since 3.2.0
86 */
87 $('.wp-list-table .everest-forms-toggle-form input').each(function () {
88 if (!$(this).prop('checked')) {
89 $(this)
90 .closest('tr')
91 .find('td')
92 .not('.has-row-actions, .column-enabled')
93 .addClass('evf-disable-row');
94 } else {
95 $(this)
96 .closest('tr')
97 .find('td')
98 .not('.has-row-actions, .column-enabled')
99 .removeClass('evf-disable-row');
100 }
101 });
102 });
103
104 $(document).ready(function ($) {
105 if ('1' === $('.everest-forms-min-max-date-format input').val()) {
106 $('.everest-forms-min-date')
107 .addClass('flatpickr-field')
108 .flatpickr({
109 disableMobile: true,
110 onChange: function (selectedDates, dateStr, instance) {
111 $('.everest-forms-min-date').val(dateStr);
112 },
113 onOpen: function (selectedDates, dateStr, instance) {
114 instance.set('maxDate', $('.everest-forms-max-date').val());
115 },
116 });
117
118 $('.everest-forms-max-date')
119 .addClass('flatpickr-field')
120 .flatpickr({
121 disableMobile: true,
122 onChange: function (selectedDates, dateStr, instance) {
123 $('.everest-forms-max-date').val(dateStr);
124 },
125 onOpen: function (selectedDates, dateStr, instance) {
126 instance.set('minDate', $('.everest-forms-min-date').val());
127 },
128 });
129 }
130
131 $('.everest-forms-min-max-date-format').each(function () {
132 if ($(this).find('input[type="checkbox"]').is(':checked')) {
133 $(this)
134 .next('.everest-forms-min-max-date-range-format')
135 .removeClass('everest-forms-hidden');
136 $(this)
137 .next()
138 .next('.everest-forms-min-max-date-option')
139 .removeClass('everest-forms-hidden');
140 if (
141 $(this)
142 .next('.everest-forms-min-max-date-range-format')
143 .find('input[type="checkbox"]')
144 .is(':checked')
145 ) {
146 $(this)
147 .next()
148 .next()
149 .next('.everest-forms-min-max-date-range-option')
150 .removeClass('everest-forms-hidden');
151 $(this)
152 .next()
153 .next('.everest-forms-min-max-date-option')
154 .addClass('everest-forms-hidden');
155 }
156 } else {
157 $(this)
158 .next()
159 .next()
160 .next('.everest-forms-min-max-date-range-option')
161 .addClass('everest-forms-hidden');
162 $(this)
163 .next('.everest-forms-min-max-date-range-format')
164 .addClass('everest-forms-hidden');
165 $(this)
166 .next()
167 .next('.everest-forms-min-max-date-option')
168 .addClass('everest-forms-hidden');
169 }
170 });
171
172 $('.everest-forms-row-option select.evf-field-show-hide').each(
173 function () {
174 $(this).find('[selected="selected"]').prop('selected', true);
175 },
176 );
177 });
178
179 if (
180 $('#everest-forms-builder').find('.everest-forms-field-file-upload')
181 .length > 0
182 ) {
183 if (!evf_data.is_pro) {
184 $('#everest-forms-add-fields-file-upload').addClass(
185 'evf-one-time-draggable-field',
186 );
187 }
188 }
189
190 if (
191 $('#everest-forms-builder').find(
192 '.everest-forms-field-payment-gateway-selector',
193 ).length > 0
194 ) {
195 $('#everest-forms-add-fields-payment-gateway-selector').addClass(
196 'evf-one-time-draggable-field',
197 );
198 }
199 EVFPanelBuilder.syncPaymentMethodDependentFields();
200
201 // Keep Payment Gateway field availability in sync with Payments tab toggles.
202 $(document).on(
203 'change click',
204 [
205 '#everest-forms-panel-field-paymentsstripe-enable_stripe',
206 '#everest-forms-panel-field-paypal-enable_paypal',
207 // Razorpay toggle id varies by version/addon; support both.
208 '#everest-forms-panel-field-paymentsrazorpay-enable_razorpay',
209 '#everest-forms-panel-field-razorpay-enable_razorpay',
210 'input[name*="[razorpay]"][name*="enable_razorpay"]',
211 '#everest-forms-panel-field-authorize_net-enable_authorize_net',
212 '#everest-forms-panel-field-square-enable_square',
213 '#everest-forms-panel-field-paymentsmollie-enable_mollie',
214 ].join(','),
215 function () {
216 EVFPanelBuilder.syncPaymentMethodDependentFields();
217 },
218 );
219
220 // Hard-block enabling any payment gateway when Payment Gateway field is present.
221 // Some addons use custom toggle wrappers that can still flip even if the underlying checkbox is disabled,
222 // so we intercept the interaction and immediately revert.
223 (function () {
224 var blockedSelectors = [
225 '#everest-forms-panel-field-paymentsstripe-enable_stripe',
226 '#everest-forms-panel-field-paypal-enable_paypal',
227 // Razorpay toggle id varies by version/addon; support both.
228 '#everest-forms-panel-field-paymentsrazorpay-enable_razorpay',
229 '#everest-forms-panel-field-razorpay-enable_razorpay',
230 'input[name*="[razorpay]"][name*="enable_razorpay"]',
231 '#everest-forms-panel-field-authorize_net-enable_authorize_net',
232 '#everest-forms-panel-field-square-enable_square',
233 '#everest-forms-panel-field-paymentsmollie-enable_mollie',
234 ];
235
236 // Capture-phase blocker: prevents addon handlers from running at all,
237 // avoiding a brief UI flash (settings rows showing) before our popup appears.
238 // We also guard "change" to catch programmatic enables.
239 if (!window.__evfPgwPaymentsToggleCaptureBound) {
240 window.__evfPgwPaymentsToggleCaptureBound = true;
241
242 function evfPgwFieldPresent() {
243 return (
244 $('#everest-forms-builder')
245 .find('.everest-forms-field-payment-gateway-selector')
246 .length > 0
247 );
248 }
249
250 function evfFindBlockedRootFromEvent(evt) {
251 if (!evt || !evt.target || !evt.target.closest) {
252 return null;
253 }
254 return evt.target.closest(blockedSelectors.join(','));
255 }
256
257 function evfFindCheckbox($root) {
258 if (!$root || !$root.length) {
259 return $();
260 }
261 if ($root.is('input[type="checkbox"]')) {
262 return $root;
263 }
264 var $in = $root.find('input[type="checkbox"]').first();
265 if ($in.length) {
266 return $in;
267 }
268 return $root.closest('li').find('input[type="checkbox"]').first();
269 }
270
271 function evfShowPopup() {
272 var title = 'Field Unavailable';
273 var closeText = (evf_data && evf_data.i18n_close) || 'Close';
274 var content =
275 'Payment Gateway is currently in use. Remove Payment Gateway to enable this field.';
276
277 if (typeof $.confirm === 'function') {
278 $.confirm({
279 title: title,
280 content: content,
281 buttons: {
282 close: {
283 text: closeText,
284 },
285 },
286 });
287 } else {
288 window.alert(content);
289 }
290 }
291
292 function evfBlockEnable(evt) {
293 if (!evfPgwFieldPresent()) {
294 return;
295 }
296
297 var root = evfFindBlockedRootFromEvent(evt);
298 if (!root) {
299 return;
300 }
301
302 var $checkbox = evfFindCheckbox($(root));
303
304 // Only show notice when enabling (unchecked -> checked).
305 // If already checked, user is disabling; allow silently.
306 if ($checkbox.length && $checkbox.is(':checked')) {
307 return;
308 }
309
310 evt.preventDefault();
311 evt.stopPropagation();
312
313 if ($checkbox.length) {
314 $checkbox.prop('checked', false);
315 }
316
317 evfShowPopup();
318 }
319
320 ['pointerdown', 'mousedown', 'click'].forEach(function (type) {
321 document.addEventListener(type, evfBlockEnable, true);
322 });
323
324 // Catch programmatic enables (change fires after state flips).
325 document.addEventListener(
326 'change',
327 function (evt) {
328 if (!evfPgwFieldPresent()) {
329 return;
330 }
331 var root = evfFindBlockedRootFromEvent(evt);
332 if (!root) {
333 return;
334 }
335 var $checkbox = evfFindCheckbox($(root));
336 if ($checkbox.length && $checkbox.is(':checked')) {
337 evt.preventDefault();
338 evt.stopPropagation();
339 $checkbox.prop('checked', false);
340 evfShowPopup();
341 }
342 },
343 true,
344 );
345 }
346
347 // Note: we intentionally rely on the capture-phase blocker above.
348 // A bubble-phase handler can run after the checkbox state flips, which would show the
349 // notice when DISABLING. Capture-phase guarantees we only block ENABLE attempts.
350 })();
351
352
353 if (!$('evf-panel-payments-button a').hasClass('active')) {
354 $('#everest-forms-panel-payments')
355 .find('.everest-forms-panel-sidebar a')
356 .first()
357 .addClass('active');
358 $('.everest-forms-panel-content')
359 .find('.evf-payment-setting-content')
360 .first()
361 .addClass('active');
362 }
363
364 // Copy shortcode from the builder.
365 $(document.body)
366 .find('#copy-shortcode')
367 .on('click', this.copyShortcode)
368 .on('aftercopy', this.copySuccess)
369 .on('aftercopyfailure', this.copyFail);
370
371 // Copy shortcode from form list table.
372 $(document.body)
373 .find('.evf-copy-shortcode')
374 .each(function () {
375 $(this)
376 .on('click', EVFPanelBuilder.copyShortcode)
377 .on('aftercopy', EVFPanelBuilder.copySuccess)
378 .on('aftercopyfailure', EVFPanelBuilder.copyFail);
379 });
380
381 // Document ready.
382 $(document).ready(EVFPanelBuilder.ready);
383
384 // Page load.
385 $(window).on('load', EVFPanelBuilder.load);
386
387 // Initialize builder UI fields.
388 $(document.body)
389 .on('evf-init-builder-fields', function () {
390 EVFPanelBuilder.bindFields();
391 })
392 .trigger('evf-init-builder-fields');
393
394 // Adjust builder width.
395 $(document.body)
396 .on('adjust_builder_width', function () {
397 var adminMenuWidth = $('#adminmenuwrap').width();
398
399 $('#everest-forms-builder-form').css({
400 width: 'calc(100% - ' + adminMenuWidth + 'px)',
401 });
402 })
403 .trigger('adjust_builder_width');
404
405 $(document.body).on('click', '#collapse-button', function () {
406 $('#everest-forms-builder-form').width('');
407 $(document.body).trigger('adjust_builder_width');
408 });
409
410 $(window)
411 .on('resize orientationchange', function () {
412 var resizeTimer;
413
414 clearTimeout(resizeTimer);
415 resizeTimer = setTimeout(function () {
416 $('#everest-forms-builder').width('');
417 $(document.body).trigger('adjust_builder_width');
418 }, 250);
419 })
420 .trigger('resize');
421
422 EVFPanelBuilder.bindPrivacyPolicyActions();
423 $(document.body).on(
424 'evf_field_drop_complete',
425 function (e, field_type, dragged_field_id) {
426 EVFPanelBuilder.bindEditMetaKey(dragged_field_id);
427 // Keep Payment Gateway ↔ Payments tab constraints in sync after any field drop.
428 if (EVFPanelBuilder.syncPaymentMethodDependentFields) {
429 EVFPanelBuilder.syncPaymentMethodDependentFields();
430 }
431
432 // Set defaults in privacy policy field.
433 if ('privacy-policy' === field_type) {
434 var consent_message = evf_data.i18n_privacy_policy_consent_message;
435 $('#everest-forms-field-' + dragged_field_id)
436 .find('.evf-privacy-policy-consent-message')
437 .html(consent_message);
438 $('#everest-forms-field-option-' + dragged_field_id)
439 .find('.evf-privacy-policy-consent-message')
440 .val(consent_message);
441 $(
442 '.everest-forms-field-options #everest-forms-field-option-row-' +
443 dragged_field_id +
444 '-required',
445 )
446 .find('input')
447 .click();
448 }
449
450 if ('country' === field_type) {
451 $(
452 '#everest-forms-field-option-row-' +
453 dragged_field_id +
454 '-default',
455 )
456 .find('select.evf-select2-multiple > option')
457 .prop('selected', true);
458 }
459
460 // Payment Gateway field: server-rendered field-map options use saved form data;
461 // repopulate from the builder canvas so existing fields appear without reload.
462 if ('payment-gateway-selector' === field_type) {
463 EVFPanelBuilder.refreshFieldMapSelectsInContainer(
464 '#everest-forms-field-option-' + dragged_field_id,
465 dragged_field_id,
466 );
467 }
468 },
469 );
470
471 // Rating point validation error tips.
472 $(document.body)
473 .on('blur', '.evf-number-of-stars[type=number]', function () {
474 $('.evf_error_tip').fadeOut('100', function () {
475 $(this).remove();
476 });
477 })
478
479 .on('change click', '.evf-number-of-stars[type=number]', function (e) {
480 var number_of_stars = parseInt($(this).val(), 10);
481
482 if (number_of_stars > 100) {
483 $(this).val('100');
484 EVFPanelBuilder.livePreviewNumberOfRating($(this));
485 }
486 })
487
488 .on('keyup click', '.evf-number-of-stars[type=number]', function () {
489 var number_of_stars = parseInt($(this).val(), 10);
490
491 if (number_of_stars > 100) {
492 $(document.body).triggerHandler('evf_add_error_tip', [
493 $(this),
494 'i18n_field_rating_greater_than_max_value_error',
495 evf_data,
496 ]);
497 } else {
498 $(document.body).triggerHandler('evf_remove_error_tip', [
499 $(this),
500 'i18n_field_rating_greater_than_max_value_error',
501 ]);
502 }
503 });
504
505 // Live effect for Rating field Number of Stars option.
506 $(document).on(
507 'keyup mouseup',
508 '.everest-forms-field-option-row-number_of_stars input',
509 function () {
510 EVFPanelBuilder.livePreviewNumberOfRating(this);
511 },
512 );
513
514 // Live effect for Rating field icon option.
515 $(document).on(
516 'change',
517 '.everest-forms-field-option-row-rating-icon input[type=radio]',
518 function () {
519 var $this = $(this),
520 value = $this.val(),
521 id = $this.parent().data('field-id'),
522 icon_color = $('#everest-forms-field-' + id + ' .rating-icon')
523 .find('svg')
524 .first()
525 .css('fill');
526 ($icons = $('#everest-forms-field-' + id + ' .rating-icon')),
527 (iconClass =
528 '<svg width="32" height="32" viewBox="0 0 32 32" style="fill:' +
529 icon_color +
530 '"><path d="M20.33 11.45L16 2.69l-4.33 8.76L2 12.86l7 6.82-1.65 9.64L16 24.77l8.65 4.55L23 19.68l7-6.82-9.67-1.41z"/></svg>');
531 if ('heart' === value) {
532 iconClass =
533 '<svg width="32" height="32" viewBox="0 0 32 32" style="fill:' +
534 icon_color +
535 '"><path d="M27.66 16.94L16 28 4.34 16.94a7.31 7.31 0 0 1 0-10.72A8.21 8.21 0 0 1 10 4a6.5 6.5 0 0 1 5 2l1 1s.88-.89 1-1a6.5 6.5 0 0 1 5-2 8.21 8.21 0 0 1 5.66 2.22 7.31 7.31 0 0 1 0 10.72z"/></svg>';
536 } else if ('thumb' === value) {
537 iconClass =
538 '<svg width="32" height="32" viewBox="0 0 32 32" style="fill:' +
539 icon_color +
540 '"><path d="M30 14.88a3.42 3.42 0 0 0-3.36-3.36h-4.85l.14-.42a2.42 2.42 0 0 1 .2-.39c.08-.14.14-.24.17-.31.21-.4.37-.72.48-1a7.39 7.39 0 0 0 .33-1.05A5.71 5.71 0 0 0 23 4a3.48 3.48 0 0 0-3-2 1.61 1.61 0 0 0-1.43.89C18.34 3.13 17 7 17 7a5.44 5.44 0 0 1-1 2c-.57.75-2.6 3-3.2 3.71s-1.05 1-1.33 1C10 13.74 10 15.71 10 16v9c0 .3 0 2.2 1.52 2.2a12.7 12.7 0 0 1 2.76.77A15.6 15.6 0 0 0 21 30a8.9 8.9 0 0 0 5.74-1.92C30 25 30 15.88 30 14.88zM5 14a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0v-7a3 3 0 0 0-3-3zm0 11a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>';
541 } else if ('smiley' === value) {
542 iconClass =
543 '<svg width="32" height="32" viewBox="0 0 32 32" style="fill:' +
544 icon_color +
545 '"><path d="M16 2a14 14 0 1 0 14 14A14 14 0 0 0 16 2zm4 8a2 2 0 1 1-2 2 2 2 0 0 1 2-2zm-8 0a2 2 0 1 1-2 2 2 2 0 0 1 2-2zm4 14a9.23 9.23 0 0 1-8.16-4.89l1.32-.71a7.76 7.76 0 0 0 13.68 0l1.32.71A9.23 9.23 0 0 1 16 24z"/></svg>';
546 } else if ('bulb' === value) {
547 iconClass =
548 '<svg width="32" height="32" viewBox="0 0 32 32" style="fill:' +
549 icon_color +
550 '"><path d="M16 2.25A9.76 9.76 0 0 0 6.25 12c0 3.21 2 5.68 3.52 7.48A6.28 6.28 0 0 1 11.25 23a.76.76 0 0 0 .75.75h8a.74.74 0 0 0 .74-.64 10 10 0 0 1 1.53-3.69c.24-.35.49-.7.75-1.06 1.28-1.77 2.73-3.79 2.73-6.36A9.76 9.76 0 0 0 16 2.25zM20 25.25h-8a.75.75 0 0 0 0 1.5h8a.75.75 0 0 0 0-1.5zM19 28.25h-6a.75.75 0 0 0 0 1.5h6a.75.75 0 0 0 0-1.5z"/></svg>';
551 }
552
553 $icons.html(iconClass);
554 },
555 );
556
557 // Live effect for Rating field icon color option.
558 $(document).ready(function ($) {
559 $(
560 '.everest-forms-field-option-row-icon_color input.colorpicker',
561 ).wpColorPicker({
562 change: function (event) {
563 var $this = $(this),
564 value = $this.val(),
565 id = $this
566 .closest('.everest-forms-field-option-row')
567 .data('field-id'),
568 $icons = $('#everest-forms-field-' + id + ' .rating-icon svg');
569
570 $icons.css('fill', value);
571 },
572 });
573 });
574
575 $(document).on('click', '.evf-edit-meta-key-icon', function () {
576 var $wrapper = $(this).closest('.evf-meta-key-input-wrapper'),
577 $input = $wrapper.find('.evf-input-meta-key'),
578 $original_value = $(this).data('meta_key');
579
580 $input.prop('readonly', false).focus();
581
582 $(document).find('.evf-meta-key-copy-btn').hide();
583 $(this).hide();
584
585 if ($wrapper.find('.evf-meta-key-actions').length === 0) {
586 $wrapper.append(`
587 <span class="evf-meta-key-actions">
588 <span class="evf-save-meta-key-icon" style="cursor: pointer;">
589 <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
590 <rect x="1.20078" y="0.600195" width="22.8" height="22.8" rx="1.2" fill="white"/>
591 <rect x="1.20078" y="0.600195" width="22.8" height="22.8" rx="1.2" stroke="#E1E1E1" stroke-width="0.8"/>
592 <path d="M17.2689 8.5L10.8522 14.9167L7.93555 12" stroke="#383838" stroke-width="1.16667" stroke-linecap="round" stroke-linejoin="round"/>
593 </svg>
594 </span>
595 <span class="evf-cancel-meta-key-icon" style="cursor: pointer;" data-original_value="${$original_value}">
596 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
597 <rect x="0.800391" y="0.600195" width="22.8" height="22.8" rx="1.2" fill="white"/>
598 <rect x="0.800391" y="0.600195" width="22.8" height="22.8" rx="1.2" stroke="#E1E1E1" stroke-width="0.8"/>
599 <path d="M12.2026 12.8161L9.34427 15.6745C9.23733 15.7814 9.10122 15.8349 8.93594 15.8349C8.77066 15.8349 8.63455 15.7814 8.5276 15.6745C8.42066 15.5675 8.36719 15.4314 8.36719 15.2661C8.36719 15.1009 8.42066 14.9648 8.5276 14.8578L11.3859 11.9995L8.5276 9.14115C8.42066 9.0342 8.36719 8.89809 8.36719 8.73281C8.36719 8.56753 8.42066 8.43142 8.5276 8.32448C8.63455 8.21753 8.77066 8.16406 8.93594 8.16406C9.10122 8.16406 9.23733 8.21753 9.34427 8.32448L12.2026 11.1828L15.0609 8.32448C15.1679 8.21753 15.304 8.16406 15.4693 8.16406C15.6345 8.16406 15.7707 8.21753 15.8776 8.32448C15.9845 8.43142 16.038 8.56753 16.038 8.73281C16.038 8.89809 15.9845 9.0342 15.8776 9.14115L13.0193 11.9995L15.8776 14.8578C15.9845 14.9648 16.038 15.1009 16.038 15.2661C16.038 15.4314 15.9845 15.5675 15.8776 15.6745C15.7707 15.7814 15.6345 15.8349 15.4693 15.8349C15.304 15.8349 15.1679 15.7814 15.0609 15.6745L12.2026 12.8161Z" fill="#383838"/>
600 </svg>
601 </span>
602 </span>
603 `);
604 }
605
606 if ($wrapper.find('.evf-meta-key-warning').length === 0) {
607 $wrapper.after(`
608 <div class="evf-meta-key-warning" >
609 <div class="everest-forms-meta-key-warning-icon">
610 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
611 <path fill-rule="evenodd" clip-rule="evenodd" d="M7.99935 1.99984C4.68564 1.99984 1.99935 4.68613 1.99935 7.99984C1.99935 11.3135 4.68564 13.9998 7.99935 13.9998C11.3131 13.9998 13.9993 11.3135 13.9993 7.99984C13.9993 4.68613 11.3131 1.99984 7.99935 1.99984ZM0.666016 7.99984C0.666016 3.94975 3.94926 0.666504 7.99935 0.666504C12.0494 0.666504 15.3327 3.94975 15.3327 7.99984C15.3327 12.0499 12.0494 15.3332 7.99935 15.3332C3.94926 15.3332 0.666016 12.0499 0.666016 7.99984ZM7.99935 7.33317C8.36754 7.33317 8.66602 7.63165 8.66602 7.99984V10.6665C8.66602 11.0347 8.36754 11.3332 7.99935 11.3332C7.63116 11.3332 7.33268 11.0347 7.33268 10.6665V7.99984C7.33268 7.63165 7.63116 7.33317 7.99935 7.33317ZM7.99935 4.6665C7.63116 4.6665 7.33268 4.96498 7.33268 5.33317C7.33268 5.70136 7.63116 5.99984 7.99935 5.99984H8.00602C8.37421 5.99984 8.67268 5.70136 8.67268 5.33317C8.67268 4.96498 8.37421 4.6665 8.00602 4.6665H7.99935Z" fill="#EE9936"/>
612 </svg>
613 </div>
614 <div>
615 <strong>Caution:</strong> We don't recommend changing this unless necessary, as it affects data retrieval.
616 </div>
617 </div>
618 `);
619 }
620
621 $(document).on('click', '.evf-cancel-meta-key-icon', function () {
622 var $wrapper = $(this).closest('.evf-meta-key-input-wrapper'),
623 $input = $wrapper.find('.evf-input-meta-key'),
624 originalValue = $(this).data('original_value');
625 $(document).find('.evf-meta-key-copy-btn').show();
626 $input.val(originalValue);
627
628 $input.prop('readonly', true);
629
630 $wrapper.find('.evf-meta-key-actions').remove();
631 $wrapper.find('.evf-edit-meta-key-icon').show();
632 $wrapper.next('.evf-meta-key-warning').remove();
633 });
634
635 $(document).on('click', '.evf-save-meta-key-icon', function () {
636 var $wrapper = $(this).closest('.evf-meta-key-input-wrapper'),
637 $input = $wrapper.find('.evf-input-meta-key');
638 $(document).find('.evf-meta-key-copy-btn').show();
639 $input.prop('readonly', true);
640
641 $wrapper.find('.evf-meta-key-actions').remove();
642 $wrapper.find('.evf-edit-meta-key-icon').show();
643 $wrapper.next('.evf-meta-key-warning').remove();
644 });
645 });
646 },
647
648 /**
649 * Copy shortcode.
650 *
651 * @param {Object} evt Copy event.
652 */
653 copyShortcode: function (evt) {
654 evfClearClipboard();
655 evfSetClipboard(
656 $(this).closest('.evf-shortcode-field').find('input').val(),
657 $(this),
658 );
659 evt.preventDefault();
660 },
661
662 /**
663 * Display a "Copied!" tip when success copying.
664 */
665 copySuccess: function () {
666 $(this)
667 .tooltipster('content', $(this).attr('data-copied'))
668 .trigger('mouseenter')
669 .on('mouseleave', function () {
670 var $this = $(this);
671
672 setTimeout(function () {
673 $this.tooltipster('content', $this.attr('data-tip'));
674 }, 1000);
675 });
676 },
677
678 /**
679 * Displays the copy error message when failure copying.
680 */
681 copyFail: function () {
682 $(this).closest('.evf-shortcode-field').find('input').focus().select();
683 },
684
685 /**
686 * Page load.
687 *
688 * @since 1.0.0
689 */
690 load: function () {
691 $('.everest-forms-overlay').fadeOut();
692 },
693
694 /**
695 * Document ready.
696 *
697 * @since 1.0.0
698 */
699 ready: function () {
700 // Cache builder element.
701 $builder = $('#everest-forms-builder');
702
703 // Bind all actions.
704 EVFPanelBuilder.bindUIActions();
705
706 // Bind edit form actions.
707 EVFPanelBuilder.bindEditActions();
708
709 // Snapshot the just-loaded (saved) form state, to detect unsaved changes later.
710 EVFPanelBuilder.captureStyleTabBaseline();
711
712 // jquery-confirm defaults.
713 jconfirm.defaults = {
714 closeIcon: true,
715 backgroundDismiss: true,
716 escapeKey: true,
717 animationBounce: 1,
718 useBootstrap: false,
719 theme: 'modern',
720 boxWidth: '400px',
721 columnClass: 'evf-responsive-class',
722 };
723
724 // Enable Perfect Scrollbar.
725 if ('undefined' !== typeof PerfectScrollbar) {
726 var tab_content = $('.everest-forms-tab-content'),
727 evf_panel = $('.everest-forms-panel');
728
729 if (tab_content.length >= 1) {
730 window.evf_tab_scroller = new PerfectScrollbar(
731 '.everest-forms-tab-content',
732 {
733 suppressScrollX: true,
734 },
735 );
736 }
737
738 evf_panel.each(function () {
739 var section_panel = $(this);
740 var panel_id = section_panel.attr('id');
741
742 if (section_panel.find('.everest-forms-panel-sidebar').length >= 1) {
743 window.evf_setting_scroller = new PerfectScrollbar(
744 '#' + panel_id + ' .everest-forms-panel-sidebar',
745 );
746 }
747 });
748 }
749
750 // Enable Limit length.
751 $builder.on(
752 'change',
753 '.everest-forms-field-option-row-limit_enabled input',
754 function (event) {
755 EVFPanelBuilder.updateTextFieldsLimitControls(
756 $(event.target)
757 .parents('.everest-forms-field-option-row-limit_enabled')
758 .data().fieldId,
759 event.target.checked,
760 );
761 },
762 );
763
764 $builder.on(
765 'change',
766 '.everest-forms-field-option-row-min_length_enabled input',
767 function (event) {
768 EVFPanelBuilder.updateTextFieldsMinLengthControls(
769 $(event.target)
770 .parents('.everest-forms-field-option-row-min_length_enabled')
771 .data().fieldId,
772 event.target.checked,
773 );
774 },
775 );
776
777 // Enable enhanced select.
778 $builder.on(
779 'change',
780 '.everest-forms-field-option-select .everest-forms-field-option-row-enhanced_select input',
781 function (event) {
782 EVFPanelBuilder.enhancedSelectFieldStyle(
783 $(event.target)
784 .parents('.everest-forms-field-option-row-enhanced_select')
785 .data().fieldId,
786 event.target.checked,
787 );
788 },
789 );
790
791 // Enable Multiple options.
792 $builder.on(
793 'click',
794 '.everest-forms-field-option-row-choices .everest-forms-btn-group span',
795 function (event) {
796 if (
797 $(this).hasClass('upgrade-modal') &&
798 'checkbox' === $(this).data('type')
799 ) {
800 $(this).parent().find('span').addClass('is-active');
801 $(this).removeClass('is-active');
802 EVFPanelBuilder.updateEnhandedSelectField(
803 $(event.target)
804 .parents('.everest-forms-field-option-row-choices')
805 .data().fieldId,
806 false,
807 );
808 } else {
809 $(this).parent().find('span').removeClass('is-active');
810 $(this).addClass('is-active');
811 EVFPanelBuilder.updateEnhandedSelectField(
812 $(event.target)
813 .parents('.everest-forms-field-option-row-choices')
814 .data().fieldId,
815 'multiple' === $(this).data('selection'),
816 );
817 }
818
819 // Show 'Select All' Checkbox for Dropdown field only if multiple selection is active
820 if (
821 'multiple' === $(this).data('selection') &&
822 'checkbox' === $(this).data('type') &&
823 $(this).hasClass('is-active')
824 ) {
825 var $field_id = $(this).parent().parent().data('field-id');
826 $(
827 '#everest-forms-field-option-row-' + $field_id + '-select_all',
828 ).show();
829 } else {
830 var $field_id = $(this).parent().parent().data('field-id');
831 $(
832 '#everest-forms-field-option-row-' + $field_id + '-select_all',
833 ).hide();
834 }
835 },
836 );
837
838 // By default hide the 'Select All' checkbox for Dropdown field
839 $(document.body).on(
840 'click',
841 '.everest-forms-field, .everest-forms-field-select[data-field-type="select"]',
842 function () {
843 $builder
844 .find(
845 '.everest-forms-field-option-row-choices .everest-forms-btn-group span',
846 )
847 .each(function () {
848 var $field_id = $(this).parent().parent().data('field-id');
849
850 if (
851 'multiple' === $(this).data('selection') &&
852 'checkbox' === $(this).data('type') &&
853 $(this).hasClass('is-active')
854 ) {
855 $('#everest-forms-field-option-' + $field_id + '-select_all')
856 .parent()
857 .parent()
858 .parent()
859 .show();
860 } else {
861 $('#everest-forms-field-option-' + $field_id + '-select_all')
862 .parent()
863 .parent()
864 .parent()
865 .hide();
866 }
867 });
868 },
869 );
870
871 // Search fields input.
872 $builder.on('keyup', '.everest-forms-search-fields', function () {
873 var searchTerm = $(this).val().toLowerCase();
874
875 // Show/hide fields.
876 $('.evf-registered-item').each(function () {
877 var $this = $(this);
878 (field_type = $this.data('field-type')),
879 (field_label = $this.text().toLowerCase());
880
881 if (
882 field_type.search(searchTerm) > -1 ||
883 field_label.search(searchTerm) > -1
884 ) {
885 $this.addClass('evf-searched-item');
886 $this.show();
887 } else {
888 $this.removeClass('evf-searched-item');
889 $this.hide();
890 }
891 });
892
893 // Show/hide field group.
894 $('.everest-forms-add-fields-group').each(function () {
895 var count = $(this).find(
896 '.evf-registered-item.evf-searched-item',
897 ).length;
898
899 if (0 >= count) {
900 $(this).hide();
901 } else {
902 $(this).show();
903 }
904 });
905
906 // Show/hide fields not found indicator.
907 if ($('.evf-registered-item.evf-searched-item').length) {
908 $('.everest-forms-fields-not-found').addClass('hidden');
909 } else {
910 $('.everest-forms-fields-not-found').removeClass('hidden');
911 }
912 });
913
914 // Collapse the form builder
915 $builder.on('click', '#evf-collapse', function (event) {
916 event.preventDefault();
917 var $this = $(this);
918
919 if ($this.hasClass('open')) {
920 $this.removeClass('open').addClass('close');
921 $this
922 .closest('.everest-forms-panel-sidebar-content')
923 .removeClass('collapsed');
924 } else {
925 $this.removeClass('close').addClass('open');
926 $this
927 .closest('.everest-forms-panel-sidebar-content')
928 .addClass('collapsed');
929 }
930 });
931
932 // Action available for each binding.
933 $(document).trigger('everest_forms_ready');
934 },
935
936 /**
937 * Update text fields limit controls.
938 *
939 * @since 1.5.10
940 *
941 * @param {number} fieldId Field ID.
942 * @param {bool} checked Whether an option is checked or not.
943 */
944 updateTextFieldsLimitControls: function (fieldId, checked) {
945 if (!checked) {
946 $(
947 '#everest-forms-field-option-row-' + fieldId + '-limit_controls',
948 ).addClass('everest-forms-hidden');
949 } else {
950 $(
951 '#everest-forms-field-option-row-' + fieldId + '-limit_controls',
952 ).removeClass('everest-forms-hidden');
953 }
954 },
955
956 /**
957 * Update text fields min length controls.
958 *
959 * @since 1.5.10
960 *
961 * @param {number} fieldId Field ID.
962 * @param {bool} checked Whether an option is checked or not.
963 */
964 updateTextFieldsMinLengthControls: function (fieldId, checked) {
965 if (!checked) {
966 $(
967 '#everest-forms-field-option-row-' + fieldId + '-min_length_controls',
968 ).addClass('everest-forms-hidden');
969 } else {
970 $(
971 '#everest-forms-field-option-row-' + fieldId + '-min_length_controls',
972 ).removeClass('everest-forms-hidden');
973 }
974 },
975
976 /**
977 * Enhanced select fields style.
978 *
979 * @since 1.7.1
980 *
981 * @param {number} fieldId Field ID.
982 * @param {bool} checked Whether an option is checked or not.
983 */
984 enhancedSelectFieldStyle: function (fieldId, checked) {
985 var $primary = $('#everest-forms-field-' + fieldId + ' .primary-input'),
986 isEnhanced = $(
987 '#everest-forms-field-option-' + fieldId + '-enhanced_select',
988 ).is(':checked');
989
990 if (checked && isEnhanced && $primary.prop('multiple')) {
991 $primary.addClass('evf-enhanced-select');
992 $(document.body).trigger('evf-enhanced-select-init');
993 } else {
994 $primary.removeClass('evf-enhanced-select enhanced');
995 $primary.filter('.select2-hidden-accessible').selectWoo('destroy');
996 }
997 },
998
999 /**
1000 * Update enhanced select field component.
1001 *
1002 * @since 1.7.1
1003 *
1004 * @param {number} fieldId Field ID.
1005 * @param {bool} isMultiple Whether an option is multiple or not.
1006 */
1007 updateEnhandedSelectField: function (fieldId, isMultiple) {
1008 var $primary = $('#everest-forms-field-' + fieldId + ' .primary-input'),
1009 $placeholder = $primary.find('.placeholder'),
1010 $hiddenField = $(
1011 '#everest-forms-field-option-' + fieldId + '-multiple_choices',
1012 ),
1013 $optionChoicesItems = $(
1014 '#everest-forms-field-option-row-' +
1015 fieldId +
1016 '-choices input.default',
1017 ),
1018 selectedChoices = $optionChoicesItems.filter(':checked');
1019
1020 // Update hidden field value.
1021 $hiddenField.val(isMultiple ? 1 : 0);
1022
1023 // Add/remove a `multiple` attribute.
1024 $primary.prop('multiple', isMultiple);
1025
1026 // Change a `Choices` fields type:
1027 // radio - needed for single selection
1028 // checkbox - needed for multiple selection
1029 $optionChoicesItems.prop('type', isMultiple ? 'checkbox' : 'radio');
1030
1031 // For single selection we can choose only one.
1032 if (!isMultiple && selectedChoices.length) {
1033 $optionChoicesItems.prop('checked', false);
1034 $(selectedChoices.get(0)).prop('checked', true);
1035 }
1036
1037 // Toggle selection for a placeholder.
1038 if ($placeholder.length && isMultiple) {
1039 $placeholder.prop('selected', !isMultiple);
1040 }
1041
1042 // Update a primary field.
1043 EVFPanelBuilder.enhancedSelectFieldStyle(fieldId, isMultiple);
1044 },
1045
1046 /**
1047 * Element bindings.
1048 *
1049 * @since 1.0.0
1050 */
1051 bindUIActions: function () {
1052 EVFPanelBuilder.bindDefaultTabs();
1053 EVFPanelBuilder.checkEmptyGrid();
1054 EVFPanelBuilder.bindFields();
1055 EVFPanelBuilder.bindFormPreview();
1056 EVFPanelBuilder.bindFormPreviewWithKeyEvent();
1057 EVFPanelBuilder.bindFormEntriesWithKeyEvent();
1058 EVFPanelBuilder.bindGridSwitcher();
1059 EVFPanelBuilder.bindFieldSettings();
1060 EVFPanelBuilder.bindFieldDelete();
1061 EVFPanelBuilder.bindFieldDeleteWithKeyEvent();
1062 EVFPanelBuilder.bindFieldMultiSelect();
1063 EVFPanelBuilder.bindCloneField();
1064 EVFPanelBuilder.bindSaveOption();
1065 EVFPanelBuilder.bindEmbedOption();
1066 EVFPanelBuilder.bindSaveOptionWithKeyEvent();
1067 EVFPanelBuilder.bindOpenShortcutKeysModalWithKeyEvent();
1068 EVFPanelBuilder.bindLayoutContainers();
1069 EVFPanelBuilder.bindAddRowColumnPicker();
1070 EVFPanelBuilder.bindAddNewRow();
1071 EVFPanelBuilder.bindRemoveRow();
1072 EVFPanelBuilder.bindFormSettings();
1073 EVFPanelBuilder.bindFormEmail();
1074 EVFPanelBuilder.bindFormSmsNotifications();
1075 EVFPanelBuilder.bindFormConversational();
1076 EVFPanelBuilder.bindFormIntegrations();
1077 EVFPanelBuilder.bindFormPayment();
1078 EVFPanelBuilder.choicesInit();
1079 EVFPanelBuilder.bindToggleHandleActions();
1080 EVFPanelBuilder.bindLabelEditInputActions();
1081 EVFPanelBuilder.bindSyncedInputActions();
1082 EVFPanelBuilder.init_datepickers();
1083 EVFPanelBuilder.init_payment_subscription_plan_field();
1084 EVFPanelBuilder.bindBulkOptionActions();
1085 EVFPanelBuilder.bindAkismetInit();
1086 EVFPanelBuilder.bindFormSubmissionMinWaitingTime();
1087 EVFPanelBuilder.bindEditMetaKey();
1088
1089 // Fields Panel.
1090 EVFPanelBuilder.bindUIActionsFields();
1091
1092 if (evf_data.tab === 'field-options') {
1093 $('.evf-panel-field-options-button').trigger('click');
1094 }
1095
1096 $(document.body).on(
1097 'everest-forms-field-drop',
1098 '.evf-registered-buttons .evf-registered-item',
1099 function () {
1100 EVFPanelBuilder.fieldDrop($(this).clone());
1101 },
1102 );
1103
1104 $(document.body).on(
1105 'click',
1106 '.evf-registered-buttons .evf-registered-item:not(.upgrade-modal):not(.evf-upgrade-addon):not(.enable-stripe-model):not(.enable-authorize-net-model):not(.enable-payment-subscription-plan):not(.everest-forms-pro-is_square_install):not(.enable-square-model):not(.evf-one-time-draggable-field):not(.recaptcha_empty_key_validate):not(.hcaptcha_empty_key_validate):not(.turnstile_empty_key_validate)',
1107 function () {
1108 EVFPanelBuilder.fieldDrop($(this).clone());
1109 },
1110 );
1111
1112 EVFPanelBuilder.bindRowFieldPopover();
1113 },
1114 /**
1115 * Bind user action handlers for the Add Bulk Options feature.
1116 */
1117 bindBulkOptionActions: function () {
1118 // Toggle `Bulk Add` option.
1119 $(document.body).on('click', '.evf-toggle-bulk-options', function (e) {
1120 e.preventDefault();
1121 var $panel = $(this)
1122 .closest('.everest-forms-field-option')
1123 .find('.everest-forms-field-option-row-add_bulk_options');
1124 if ($panel.hasClass('everest-forms-hidden')) {
1125 $panel.stop(true, true).removeClass('everest-forms-hidden').hide().slideDown();
1126 } else {
1127 $panel.stop(true, true).slideUp(function () {
1128 $(this).addClass('everest-forms-hidden').css('display', '');
1129 });
1130 }
1131 });
1132 // Toggle presets list.
1133 $(document.body).on('click', '.evf-toggle-presets-list', function (e) {
1134 e.preventDefault();
1135 $(this)
1136 .closest('.everest-forms-field-option')
1137 .find('.everest-forms-field-option-row .evf-options-presets')
1138 .removeAttr('hidden')
1139 .slideToggle();
1140 });
1141 // Add custom list of options.
1142 $(document.body).on('click', '.evf-add-bulk-options', function (e) {
1143 var $option_row = $(this).closest('.everest-forms-field-option-row');
1144 var field_id = $option_row.data('field-id');
1145
1146 if ($option_row.length) {
1147 var $choices = $option_row
1148 .closest('.everest-forms-field-option')
1149 .find('.everest-forms-field-option-row-choices .evf-choices-list');
1150 var $bulk_options_container = $option_row.find(
1151 'textarea#everest-forms-field-option-' +
1152 field_id +
1153 '-add_bulk_options',
1154 );
1155 var options_texts = $bulk_options_container
1156 .val()
1157 .replace(/<\s*script/gi, '')
1158 .replace(/\s+on\w+\s*=/gi, ' ')
1159 .split('\n');
1160
1161 EVFPanelBuilder.addBulkOptions(options_texts, $choices);
1162 $bulk_options_container.val('');
1163 }
1164 });
1165 // Add presets of options.
1166 $(document.body).on('click', '.evf-options-preset-label', function (e) {
1167 var $option_row = $(this).closest('.everest-forms-field-option-row');
1168 var field_id = $option_row.data('field-id');
1169
1170 if ($option_row.length) {
1171 var options_texts = $(this)
1172 .closest('.evf-options-preset')
1173 .find('.evf-options-preset-value')
1174 .val();
1175
1176 $option_row
1177 .find(
1178 'textarea#everest-forms-field-option-' +
1179 field_id +
1180 '-add_bulk_options',
1181 )
1182 .val(options_texts);
1183 $(this).closest('.evf-options-presets').slideUp();
1184 }
1185 });
1186 //Add toggle option for password validation and strength meter.
1187 $(document.body).on(
1188 'click',
1189 '.everest-forms-field-option-row-password_strength',
1190 function () {
1191 if ($(this).find('[type="checkbox"]:first').prop('checked')) {
1192 $(this)
1193 .next()
1194 .find('[type="checkbox"]:first')
1195 .prop('checked', false);
1196 // $(this).prev().find('.everest-forms-inner-options').hide();
1197 }
1198 },
1199 );
1200 $(document.body).on(
1201 'click',
1202 '.everest-forms-field-option-row-password_validation',
1203 function () {
1204 if ($(this).find('[type="checkbox"]:first').prop('checked')) {
1205 $(this)
1206 .prev()
1207 .find('[type="checkbox"]:first')
1208 .prop('checked', false);
1209 $(this)
1210 .prev()
1211 .find('.everest-forms-inner-options')
1212 .addClass('everest-forms-hidden');
1213 }
1214 },
1215 );
1216 },
1217
1218 /**
1219 * Add a list of options at once.
1220 *
1221 * @param {Array<string>} options_texts List of options to add.
1222 * @param {object} $choices_container Options container where the options should be added.
1223 */
1224 addBulkOptions: function (options_texts, $choices_container) {
1225 options_texts.forEach(function (option_text) {
1226 if ('' !== option_text) {
1227 var $add_button = $choices_container.find('li').last().find('a.add');
1228 EVFPanelBuilder.choiceAdd(null, $add_button, option_text.trim());
1229 }
1230 });
1231 },
1232
1233 /**
1234 * Initialize date pickers like min/max date, disable dates etc.
1235 *
1236 * @since 1.6.6
1237 */
1238 init_datepickers: function () {
1239 var date_format = $('.everest-forms-disable-dates').data('date-format'),
1240 selection_mode = 'multiple';
1241
1242 // Initialize "Disable dates" option's date pickers that hasn't been initialized.
1243 $('.everest-forms-disable-dates').each(function () {
1244 if (!$(this).get(0)._flatpickr) {
1245 $(this).flatpickr({
1246 dateFormat: date_format,
1247 mode: selection_mode,
1248 });
1249 }
1250 });
1251
1252 // Reformat the selected dates input value for `Disable dates` option when the date format changes.
1253 $(document.body).on('change', '.evf-date-format', function (e) {
1254 var $disable_dates = $(
1255 '.everest-forms-field-option:visible .everest-forms-disable-dates',
1256 ),
1257 flatpicker = $disable_dates.get(0)._flatpickr,
1258 selectedDates = flatpicker.selectedDates,
1259 date_format = $(this).val(),
1260 formatedDates = [];
1261
1262 selectedDates.forEach(function (date) {
1263 formatedDates.push(flatpickr.formatDate(date, date_format));
1264 });
1265 flatpicker.set('dateFormat', date_format);
1266 $disable_dates.val(formatedDates.join(', '));
1267 });
1268
1269 // Clear disabled dates.
1270 $(document.body).on('click', '.evf-clear-disabled-dates', function () {
1271 $('.everest-forms-field-option:visible .everest-forms-disable-dates')
1272 .get(0)
1273 ._flatpickr.clear();
1274 });
1275
1276 // Triggring Setting Toggler.
1277 $('.everest-forms-field-date-time').each(function () {
1278 var id = $(this).attr('data-field-id');
1279 EVFPanelBuilder.dateSettingToggler(
1280 id,
1281 $('#everest-forms-field-option-' + id + '-datetime_style').val(),
1282 );
1283 });
1284
1285 if ($('.everest-forms-slot-booking input').is(':checked')) {
1286 //checked and hide past dates.
1287 disable_past_date = $(document).find(
1288 '.everest-forms-past-date-disable-format input',
1289 );
1290 required = $(document).find(
1291 '.everest-forms-field-option-row-required input',
1292 );
1293 disable_past_date.attr('checked', true);
1294 required.prop('checked', true);
1295 disable_past_date.parent().parent().parent().hide();
1296 }
1297 },
1298 /**
1299 * Normalize a date to local midnight for day comparisons.
1300 *
1301 * @param {Date} date Input date.
1302 * @return {Date}
1303 */
1304 normalize_subscription_expiry_day: function (date) {
1305 var normalized = new Date(date.getTime());
1306 normalized.setHours(0, 0, 0, 0);
1307 return normalized;
1308 },
1309
1310 /**
1311 * Whether a calendar day falls inside the active trial window (not past dates).
1312 *
1313 * @param {jQuery} $li Plan choice row.
1314 * @param {Date} dayDate Calendar day.
1315 * @return {boolean}
1316 */
1317 is_subscription_expiry_trial_day: function ($li, dayDate) {
1318 if (
1319 !dayDate ||
1320 !$li ||
1321 !$li.length ||
1322 !$li.find('.evf-enable-trial-period').is(':checked')
1323 ) {
1324 return false;
1325 }
1326
1327 var today = new Date();
1328 today.setHours(0, 0, 0, 0);
1329 var trialMin =
1330 EVFPanelBuilder.get_subscription_expiry_min_date($li);
1331 var day = EVFPanelBuilder.normalize_subscription_expiry_day(dayDate);
1332
1333 return (
1334 day.getTime() >= today.getTime() &&
1335 day.getTime() < trialMin.getTime()
1336 );
1337 },
1338
1339 /**
1340 * First allowed expiry date for a plan choice (matches SubscriptionSchedule billing_start_date).
1341 *
1342 * @param {jQuery} $li Plan choice row.
1343 * @return {Date} Midnight local date.
1344 */
1345 get_subscription_expiry_min_date: function ($li) {
1346 var min = new Date();
1347 min.setHours(0, 0, 0, 0);
1348
1349 if (!$li || !$li.length) {
1350 return min;
1351 }
1352
1353 if (!$li.find('.evf-enable-trial-period').is(':checked')) {
1354 return min;
1355 }
1356
1357 var count = parseInt(
1358 $li.find('.evf-spt-panel--trial input[type="number"]').val(),
1359 10,
1360 );
1361 if (isNaN(count) || count < 1) {
1362 count = 1;
1363 }
1364
1365 var period =
1366 $li.find('.evf-spt-panel--trial select').val() || 'day';
1367
1368 switch (period) {
1369 case 'week':
1370 min.setDate(min.getDate() + count * 7);
1371 break;
1372 case 'month':
1373 min.setMonth(min.getMonth() + count);
1374 break;
1375 case 'year':
1376 min.setFullYear(min.getFullYear() + count);
1377 break;
1378 case 'day':
1379 default:
1380 min.setDate(min.getDate() + count);
1381 break;
1382 }
1383
1384 return min;
1385 },
1386
1387 /**
1388 * Show or hide expiry hint when trial blocks early dates.
1389 *
1390 * @param {jQuery} $li Plan choice row.
1391 * @param {Date} minDate First selectable expiry date.
1392 */
1393 sync_subscription_expiry_trial_hint: function ($li, minDate) {
1394 var $detail = $li.find('.evf-spt-panel--expiry .evf-spt-panel-detail');
1395 var $hint = $detail.find('.evf-expiry-trial-hint');
1396
1397 if (!$hint.length) {
1398 $hint = $(
1399 '<p class="evf-expiry-trial-hint description" role="note"></p>',
1400 );
1401 $detail.append($hint);
1402 }
1403
1404 if (!$li.find('.evf-enable-trial-period').is(':checked')) {
1405 $hint.hide().text('');
1406 return;
1407 }
1408
1409 var label =
1410 typeof flatpickr !== 'undefined'
1411 ? flatpickr.formatDate(minDate, 'Y-m-d')
1412 : minDate.toISOString().slice(0, 10);
1413 var template =
1414 (evf_data && evf_data.i18n_expiry_trial_min_date) ||
1415 'Expiry must be on or after the trial ends (%s).';
1416
1417 $hint.text(template.replace('%s', label)).show();
1418 },
1419
1420 /**
1421 * Anchor element for positioning the expiry calendar under the date input.
1422 *
1423 * @param {jQuery} $input Expiry date input.
1424 * @return {HTMLElement}
1425 */
1426 get_subscription_expiry_picker_anchor: function ($input) {
1427 var $anchor = $input.closest('.evf-spt-panel-detail');
1428
1429 if (!$anchor.length) {
1430 $anchor = $input.closest('.evf-general-setting-field');
1431 }
1432
1433 if (!$anchor.length) {
1434 $anchor = $input.parent();
1435 }
1436
1437 return $anchor[0];
1438 },
1439
1440 /**
1441 * Close open subscription expiry flatpickr calendars.
1442 *
1443 * @param {HTMLElement|null} exceptInput Optional input to keep open.
1444 */
1445 close_subscription_expiry_pickers: function (exceptInput) {
1446 $('.evf-radio-subscription-expiry-input').each(function () {
1447 if (exceptInput && this === exceptInput) {
1448 return;
1449 }
1450
1451 if (this._flatpickr && this._flatpickr.isOpen) {
1452 this._flatpickr.close();
1453 }
1454
1455 $(this).removeClass('active');
1456 });
1457 },
1458
1459 /**
1460 * Clear subscription plan expiry date input and flatpickr state.
1461 *
1462 * @param {jQuery} $li Plan choice row.
1463 */
1464 clear_subscription_plan_expiry_date: function ($li) {
1465 var $expiryInput = $li.find('.evf-radio-subscription-expiry-input');
1466
1467 $expiryInput.val('');
1468
1469 if ($expiryInput.length && $expiryInput[0]._flatpickr) {
1470 $expiryInput[0]._flatpickr.clear();
1471 }
1472 },
1473
1474 /**
1475 * Toggle flatpickr when the expiry input is clicked.
1476 *
1477 * @param {object} instance Flatpickr instance.
1478 */
1479 bind_subscription_expiry_picker_toggle: function (instance) {
1480 var $input = $(instance.input);
1481
1482 $input.off('click.evfExpiryPicker').on('click.evfExpiryPicker', function (e) {
1483 e.preventDefault();
1484 e.stopPropagation();
1485
1486 if (instance.isOpen) {
1487 instance.close();
1488 return;
1489 }
1490
1491 EVFPanelBuilder.close_subscription_expiry_pickers(instance.input);
1492 instance.open();
1493 });
1494 },
1495
1496 /**
1497 * Update minDate on open expiry pickers after trial settings change.
1498 *
1499 * @param {jQuery} $scope Optional plan choice row.
1500 */
1501 update_subscription_expiry_min_dates: function ($scope) {
1502 var $inputs =
1503 $scope && $scope.length
1504 ? $scope.find('.evf-radio-subscription-expiry-input')
1505 : $(
1506 '.everest-forms-field-option-payment-subscription-plan .evf-radio-subscription-expiry-input',
1507 );
1508
1509 $inputs.each(function () {
1510 var el = this;
1511 var $li = $(el).closest('li');
1512
1513 if (!el._flatpickr) {
1514 return;
1515 }
1516
1517 var minDate =
1518 EVFPanelBuilder.get_subscription_expiry_min_date($li);
1519
1520 el._flatpickr.set('minDate', minDate);
1521 EVFPanelBuilder.sync_subscription_expiry_trial_hint(
1522 $li,
1523 minDate,
1524 );
1525
1526 if (
1527 el._flatpickr.selectedDates[0] &&
1528 el._flatpickr.selectedDates[0] < minDate
1529 ) {
1530 el._flatpickr.clear();
1531 }
1532
1533 el._flatpickr.redraw();
1534 });
1535 },
1536
1537 /**
1538 * Flatpickr for subscription plan expiry date (builder only).
1539 *
1540 * @param {jQuery} $scope Optional container (plan choice row).
1541 */
1542 init_subscription_expiry_date_pickers: function ($scope) {
1543 var $inputs =
1544 $scope && $scope.length
1545 ? $scope.find('.evf-radio-subscription-expiry-input')
1546 : $(
1547 '.everest-forms-field-option-payment-subscription-plan:visible .evf-radio-subscription-expiry-input',
1548 );
1549
1550 var blockedTitle =
1551 (evf_data && evf_data.i18n_expiry_trial_blocked_day) ||
1552 'This date is within the trial period and cannot be used as the expiry date.';
1553
1554 $inputs.each(function () {
1555 var $input = $(this);
1556 var el = this;
1557 var $li = $input.closest('li');
1558 var savedDate = $.trim($input.val());
1559 var dateFormat = $input.data('date-format') || 'Y-m-d';
1560
1561 if (el._flatpickr && !el._flatpickr.config.static) {
1562 el._flatpickr.destroy();
1563 }
1564
1565 if (el._flatpickr) {
1566 var minDate =
1567 EVFPanelBuilder.get_subscription_expiry_min_date($li);
1568
1569 el._flatpickr.set('minDate', minDate);
1570
1571 if (savedDate) {
1572 el._flatpickr.setDate(savedDate, false);
1573
1574 if (el._flatpickr.selectedDates[0]) {
1575 $input.val(
1576 el._flatpickr.formatDate(
1577 el._flatpickr.selectedDates[0],
1578 dateFormat,
1579 ),
1580 );
1581 } else {
1582 $input.val(savedDate);
1583 }
1584 }
1585
1586 EVFPanelBuilder.sync_subscription_expiry_trial_hint(
1587 $li,
1588 minDate,
1589 );
1590 el._flatpickr.redraw();
1591 EVFPanelBuilder.bind_subscription_expiry_picker_toggle(
1592 el._flatpickr,
1593 );
1594 return;
1595 }
1596
1597 var $anchor = $(EVFPanelBuilder.get_subscription_expiry_picker_anchor($input));
1598 $anchor.addClass('evf-subscription-expiry-picker-anchor');
1599
1600 $input.flatpickr({
1601 dateFormat: dateFormat,
1602 defaultDate: savedDate || null,
1603 disableMobile: true,
1604 allowInput: false,
1605 clickOpens: false,
1606 closeOnSelect: true,
1607 static: true,
1608 position: 'below',
1609 animate: true,
1610 minDate:
1611 EVFPanelBuilder.get_subscription_expiry_min_date($li),
1612 monthSelectorType: 'dropdown',
1613 onOpen: function (selectedDates, dateStr, instance) {
1614 $(instance.input).addClass('active');
1615 },
1616 onClose: function (selectedDates, dateStr, instance) {
1617 $(instance.input).removeClass('active');
1618 },
1619 onDayCreate: function (dObj, dStr, fp, dayElem) {
1620 var $choiceLi = $(fp.input).closest('li');
1621 var dayDate = dayElem.dateObj;
1622
1623 dayElem.classList.remove('evf-expiry-trial-blocked');
1624 dayElem.removeAttribute('title');
1625
1626 if (
1627 EVFPanelBuilder.is_subscription_expiry_trial_day(
1628 $choiceLi,
1629 dayDate,
1630 )
1631 ) {
1632 dayElem.classList.add('evf-expiry-trial-blocked');
1633 dayElem.setAttribute('title', blockedTitle);
1634 }
1635 },
1636 onChange: function (selectedDates, dateStr, instance) {
1637 var trialMin =
1638 EVFPanelBuilder.get_subscription_expiry_min_date(
1639 $(instance.input).closest('li'),
1640 );
1641
1642 if (
1643 selectedDates[0] &&
1644 selectedDates[0] < trialMin
1645 ) {
1646 instance.clear();
1647 $(instance.input).val('');
1648 return;
1649 }
1650
1651 $(instance.input).val(dateStr).trigger('change');
1652 },
1653 onReady: function (selectedDates, dateStr, instance) {
1654 var $choiceLi = $(instance.input).closest('li');
1655 var trialMin =
1656 EVFPanelBuilder.get_subscription_expiry_min_date(
1657 $choiceLi,
1658 );
1659 var storedDate = $.trim($(instance.input).val());
1660
1661 if (instance.calendarContainer) {
1662 instance.calendarContainer.classList.add(
1663 'evf-subscription-expiry-calendar',
1664 );
1665 }
1666
1667 EVFPanelBuilder.bind_subscription_expiry_picker_toggle(
1668 instance,
1669 );
1670
1671 EVFPanelBuilder.sync_subscription_expiry_trial_hint(
1672 $choiceLi,
1673 trialMin,
1674 );
1675
1676 if (storedDate) {
1677 instance.setDate(storedDate, false);
1678 $(instance.input).val(
1679 instance.formatDate(
1680 instance.selectedDates[0],
1681 instance.config.dateFormat,
1682 ),
1683 );
1684 }
1685
1686 if (
1687 instance.selectedDates[0] &&
1688 instance.selectedDates[0] < trialMin
1689 ) {
1690 instance.clear();
1691 $(instance.input).val('');
1692 }
1693 },
1694 });
1695 });
1696 },
1697
1698 /**
1699 * For the subscription plan field.
1700 *
1701 * @since 3.0.9
1702 */
1703 init_payment_subscription_plan_field: function () {
1704 EVFPanelBuilder.init_subscription_expiry_date_pickers();
1705
1706 $('.everest-forms-field-payment-subscription-plan').each(function () {
1707 var fieldId = $(this).data('field-id');
1708 if (fieldId) {
1709 EVFPanelBuilder.subscriptionPlanChoiceUpdate(fieldId);
1710 }
1711 });
1712
1713 // Tab switching — delegated so it works for dynamically added choices.
1714 $(document.body).on(
1715 'click',
1716 '.evf-spt-tab',
1717 function () {
1718 EVFPanelBuilder.close_subscription_expiry_pickers();
1719
1720 var $tab = $(this);
1721 var $planTabs = $tab.closest('.evf-subscription-plan-tabs');
1722 var targetTab = $tab.data('tab');
1723
1724 $tab.closest('.evf-spt-strip')
1725 .find('.evf-spt-tab')
1726 .removeClass('evf-spt-tab--active');
1727 $tab.addClass('evf-spt-tab--active');
1728
1729 $planTabs.find('.evf-spt-panel').hide();
1730 $planTabs.find('.evf-spt-panel--' + targetTab).show();
1731
1732 if ('expiry' === targetTab) {
1733 EVFPanelBuilder.init_subscription_expiry_date_pickers(
1734 $tab.closest('li'),
1735 );
1736 }
1737 },
1738 );
1739
1740 // Trial toggle — dim inputs and update dot indicator.
1741 $(document.body).on(
1742 'change',
1743 '.evf-enable-trial-period',
1744 function () {
1745 var $li = $(this).closest('li');
1746 var isChecked = $(this).is(':checked');
1747 $li.find('.evf-spt-panel--trial .evf-spt-panel-detail').toggle(isChecked);
1748 $li.find('.evf-spt-tab--trial .evf-spt-dot').toggle(isChecked);
1749 EVFPanelBuilder.update_subscription_expiry_min_dates($li);
1750 },
1751 );
1752
1753 // Trial length/period — block expiry dates that fall inside the trial window.
1754 $(document.body).on(
1755 'change input',
1756 '.evf-spt-panel--trial input[type="number"], .evf-spt-panel--trial select',
1757 function () {
1758 EVFPanelBuilder.update_subscription_expiry_min_dates(
1759 $(this).closest('li'),
1760 );
1761 },
1762 );
1763
1764 // Expiry toggle — dim inputs, close calendar, update dot indicator.
1765 $(document.body).on(
1766 'change',
1767 '.evf-enable-expiry-date',
1768 function () {
1769 var $li = $(this).closest('li');
1770 var isChecked = $(this).is(':checked');
1771 $li.find('.evf-spt-panel--expiry .evf-spt-panel-detail').toggle(isChecked);
1772 $li.find('.evf-spt-tab--expiry .evf-spt-dot').toggle(isChecked);
1773
1774 if (isChecked) {
1775 EVFPanelBuilder.init_subscription_expiry_date_pickers($li);
1776 } else {
1777 EVFPanelBuilder.clear_subscription_plan_expiry_date($li);
1778 EVFPanelBuilder.close_subscription_expiry_pickers();
1779 }
1780 },
1781 );
1782
1783 // Update builder preview when recurring interval or period changes.
1784 $(document.body).on(
1785 'change input',
1786 '.evf-spt-panel--recurring input[type="number"], .evf-spt-panel--recurring select',
1787 function () {
1788 var fieldId = $(this).closest('.evf-choices-list').data('field-id');
1789 if (fieldId) {
1790 EVFPanelBuilder.subscriptionPlanChoiceUpdate(fieldId);
1791 }
1792 },
1793 );
1794
1795 // Update builder preview when trial toggle, count, or period changes.
1796 $(document.body).on(
1797 'change input',
1798 '.evf-enable-trial-period, .evf-spt-panel--trial input[type="number"], .evf-spt-panel--trial select',
1799 function () {
1800 var fieldId = $(this).closest('.evf-choices-list').data('field-id');
1801 if (fieldId) {
1802 EVFPanelBuilder.subscriptionPlanChoiceUpdate(fieldId);
1803 }
1804 },
1805 );
1806
1807 // Update builder preview when expiry toggle or date changes.
1808 $(document.body).on(
1809 'change',
1810 '.evf-enable-expiry-date, .evf-radio-subscription-expiry-input',
1811 function () {
1812 var fieldId = $(this).closest('.evf-choices-list').data('field-id');
1813 if (fieldId) {
1814 EVFPanelBuilder.subscriptionPlanChoiceUpdate(fieldId);
1815 }
1816 },
1817 );
1818
1819 $(document.body).on('evf_after_field_append', function (e, element_id) {
1820 var $field = $('#' + element_id);
1821 var field_type = $field.attr('data-field-type');
1822
1823 if ('payment-subscription-plan' === field_type) {
1824 var isRecurringEnable = $(
1825 '#everest-forms-panel-field-paypal-recurring',
1826 );
1827 $('#everest-forms-panel-field-paypal-interval_count-wrap').hide();
1828 $('#everest-forms-panel-field-paypal-period-wrap').hide();
1829
1830 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1831 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1832 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1833
1834 $('#everest-forms-panel-field-mollie-subscription_description-wrap').hide();
1835 $('#everest-forms-panel-field-mollie-interval_count-wrap').hide();
1836 $('#everest-forms-panel-field-mollie-interval-wrap').hide();
1837 }
1838
1839 EVFPanelBuilder.syncPaymentMethodDependentFields();
1840 EVFPanelBuilder.refreshFieldMapSelectsFromField('add', element_id);
1841 });
1842
1843 $(document.body).on('evf_before_field_deleted', function (e, element_id) {
1844 EVFPanelBuilder.refreshFieldMapSelectsFromField(
1845 'remove',
1846 element_id,
1847 );
1848 var $field = $('#everest-forms-field-' + element_id);
1849 var field_type = $field.attr('data-field-type');
1850
1851 if ('payment-subscription-plan' === field_type) {
1852 $('#everest-forms-panel-field-paypal-interval_count-wrap').show();
1853 $('#everest-forms-panel-field-paypal-period-wrap').show();
1854
1855 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1856 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1857 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1858
1859 $('#everest-forms-panel-field-mollie-subscription_description-wrap').show();
1860 $('#everest-forms-panel-field-mollie-interval_count-wrap').show();
1861 $('#everest-forms-panel-field-mollie-interval-wrap').show();
1862 }
1863
1864 // Run after DOM removal to accurately detect selector presence.
1865 setTimeout(function () {
1866 EVFPanelBuilder.syncPaymentMethodDependentFields();
1867 }, 0);
1868 });
1869
1870 var isRecurringEnable = $('#everest-forms-panel-field-paypal-recurring');
1871
1872 var wrapper = $('.everest-forms-field-wrap');
1873
1874 if (
1875 $(wrapper).find('.everest-forms-field-payment-subscription-plan')
1876 .length > 0
1877 ) {
1878 if ($(isRecurringEnable).is(':checked')) {
1879 $('#everest-forms-panel-field-paypal-interval_count-wrap').hide();
1880 $('#everest-forms-panel-field-paypal-period-wrap').hide();
1881
1882 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1883 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1884 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1885 }
1886
1887 $(isRecurringEnable).on('click', function (e) {
1888 $('#everest-forms-panel-field-paypal-interval_count-wrap').hide();
1889 $('#everest-forms-panel-field-paypal-period-wrap').hide();
1890
1891 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1892 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1893 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1894 });
1895 }
1896
1897 var isStripeRecurringEnable = $(
1898 '#everest-forms-panel-field-stripe-recurring',
1899 );
1900
1901 var wrapper = $('.everest-forms-field-wrap');
1902
1903 if (
1904 $(wrapper).find('.everest-forms-field-payment-subscription-plan')
1905 .length > 0
1906 ) {
1907 if ($(isStripeRecurringEnable).is(':checked')) {
1908 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1909 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1910 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1911 }
1912
1913 $('#everest-forms-panel-field-mollie-subscription_description-wrap').hide();
1914 $('#everest-forms-panel-field-mollie-interval_count-wrap').hide();
1915 $('#everest-forms-panel-field-mollie-interval-wrap').hide();
1916 }
1917 $(isStripeRecurringEnable).on('click', function (e) {
1918 if (
1919 $(this).is(':checked') &&
1920 $(wrapper).find('.everest-forms-field-payment-subscription-plan')
1921 .length > 0
1922 ) {
1923 $('#everest-forms-panel-field-stripe-plan_name-wrap').hide();
1924 $('#everest-forms-panel-field-stripe-interval_count-wrap').hide();
1925 $('#everest-forms-panel-field-stripe-period-wrap').hide();
1926 }
1927 });
1928 },
1929
1930 /**
1931 * Form edit title actions.
1932 *
1933 * @since 1.6.0
1934 */
1935 bindEditActions: function () {
1936 // Delegates event to toggleEditTitle() on clicking.
1937 $('#edit-form-name').on('click', function (e) {
1938 e.stopPropagation();
1939
1940 if ('' !== $('#evf-edit-form-name').val().trim()) {
1941 EVFPanelBuilder.toggleEditTitle(e);
1942 }
1943 });
1944
1945 // Apply the title change to form name field.
1946 $('#evf-edit-form-name')
1947 .on('change keypress', function (e) {
1948 var $this = $(this);
1949
1950 e.stopPropagation();
1951
1952 if (13 === e.which && '' !== $(this).val().trim()) {
1953 EVFPanelBuilder.toggleEditTitle(e);
1954 }
1955
1956 if ('' !== $this.val().trim()) {
1957 $('#everest-forms-panel-field-settings-form_title').val(
1958 $this.val().trim(),
1959 );
1960 }
1961 })
1962 .on('click', function (e) {
1963 e.stopPropagation();
1964 });
1965
1966 // In case the user goes out of focus from title edit state.
1967 $(document)
1968 .not($('.everest-forms-title-desc'))
1969 .on('click', function (e) {
1970 var field = $('#evf-edit-form-name');
1971
1972 e.stopPropagation();
1973
1974 // Only allow flipping state if currently editing.
1975 if (
1976 !field.prop('disabled') &&
1977 field.val() &&
1978 '' !== field.val().trim()
1979 ) {
1980 EVFPanelBuilder.toggleEditTitle(e);
1981 }
1982 });
1983 },
1984
1985 // Toggles edit state.
1986 toggleEditTitle: function (event) {
1987 var $el = $('#edit-form-name'),
1988 $input_title = $el.siblings('#evf-edit-form-name');
1989
1990 event.preventDefault();
1991
1992 // Toggle disabled property.
1993 $input_title.prop('disabled', function (_, val) {
1994 return !val;
1995 });
1996
1997 if (!$input_title.hasClass('everst-forms-name-editing')) {
1998 $input_title.focus();
1999 }
2000
2001 $input_title.toggleClass('everst-forms-name-editing');
2002 },
2003
2004 //--------------------------------------------------------------------//
2005 // Fields Panel
2006 //--------------------------------------------------------------------//
2007
2008 /**
2009 * Creates a object from form elements.
2010 *
2011 * @since 1.6.0
2012 */
2013 formObject: function (el) {
2014 var form = jQuery(el),
2015 fields = form.find('[name]'),
2016 json = {},
2017 arraynames = {};
2018
2019 for (var v = 0; v < fields.length; v++) {
2020 var field = jQuery(fields[v]),
2021 name = field.prop('name').replace(/\]/gi, '').split('['),
2022 value = field.val(),
2023 lineconf = {};
2024
2025 if (
2026 (field.is(':radio') || field.is(':checkbox')) &&
2027 !field.is(':checked')
2028 ) {
2029 continue;
2030 }
2031 for (var i = name.length - 1; i >= 0; i--) {
2032 var nestname = name[i];
2033 if (typeof nestname === 'undefined') {
2034 nestname = '';
2035 }
2036 if (nestname.length === 0) {
2037 lineconf = [];
2038 if (typeof arraynames[name[i - 1]] === 'undefined') {
2039 arraynames[name[i - 1]] = 0;
2040 } else {
2041 arraynames[name[i - 1]] += 1;
2042 }
2043 nestname = arraynames[name[i - 1]];
2044 }
2045 if (i === name.length - 1) {
2046 if (value) {
2047 if (value === 'true') {
2048 value = true;
2049 } else if (value === 'false') {
2050 value = false;
2051 } else if (
2052 !isNaN(parseFloat(value)) &&
2053 parseFloat(value).toString() === value
2054 ) {
2055 value = parseFloat(value);
2056 } else if (
2057 typeof value === 'string' &&
2058 (value.substr(0, 1) === '{' || value.substr(0, 1) === '[')
2059 ) {
2060 try {
2061 value = JSON.parse(value);
2062 } catch (e) {}
2063 } else if (
2064 typeof value === 'object' &&
2065 value.length &&
2066 field.is('select')
2067 ) {
2068 var new_val = {};
2069 for (var i = 0; i < value.length; i++) {
2070 new_val['n' + i] = value[i];
2071 }
2072 value = new_val;
2073 }
2074 }
2075 lineconf[nestname] = value;
2076 } else {
2077 var newobj = lineconf;
2078 lineconf = {};
2079 lineconf[nestname] = newobj;
2080 }
2081 }
2082 $.extend(true, json, lineconf);
2083 }
2084
2085 return json;
2086 },
2087
2088 /**
2089 * Element bindings for Fields panel.
2090 *
2091 * @since 1.2.0
2092 */
2093 bindUIActionsFields: function () {
2094 // Add new field choice.
2095 $builder.on(
2096 'click',
2097 '.everest-forms-field-option-row-choices .add',
2098 function (event) {
2099 EVFPanelBuilder.choiceAdd(event, $(this));
2100 },
2101 );
2102
2103 // Delete field choice.
2104 $builder.on(
2105 'click',
2106 '.everest-forms-field-option-row-choices .remove',
2107 function (event) {
2108 EVFPanelBuilder.choiceDelete(event, $(this));
2109 },
2110 );
2111
2112 // Field choices defaults - (before change).
2113 $builder.on(
2114 'mousedown',
2115 '.everest-forms-field-option-row-choices input[type=radio]',
2116 function () {
2117 var $this = $(this);
2118
2119 if ($this.is(':checked')) {
2120 $this.attr('data-checked', '1');
2121 } else {
2122 $this.attr('data-checked', '0');
2123 }
2124 },
2125 );
2126
2127 // Field choices defaults.
2128 $builder.on(
2129 'click',
2130 '.everest-forms-field-option-row-choices input[type=radio]',
2131 function () {
2132 var $this = $(this),
2133 list = $this.parent().parent();
2134
2135 $this
2136 .parent()
2137 .parent()
2138 .find('input[type=radio]')
2139 .not(this)
2140 .prop('checked', false);
2141
2142 if ($this.attr('data-checked') === '1') {
2143 $this.prop('checked', false);
2144 $this.attr('data-checked', '0');
2145 }
2146
2147 EVFPanelBuilder.choiceUpdate(
2148 list.data('field-type'),
2149 list.data('field-id'),
2150 );
2151 },
2152 );
2153
2154 // Field choices update preview area.
2155 $builder.on(
2156 'change',
2157 '.everest-forms-field-option-row-choices input[type=checkbox]',
2158 function (e) {
2159 var list = $(this).parent().parent();
2160 EVFPanelBuilder.choiceUpdate(
2161 list.data('field-type'),
2162 list.data('field-id'),
2163 );
2164 },
2165 );
2166
2167 // Updates field choices text in almost real time.
2168 $builder.on(
2169 'keyup paste focusout',
2170 '.everest-forms-field-option-row-choices input.label, .everest-forms-field-option-row-choices input.value',
2171 function (e) {
2172 var list = $(this).parent().parent().parent();
2173 EVFPanelBuilder.choiceUpdate(
2174 list.data('field-type'),
2175 list.data('field-id'),
2176 );
2177 },
2178 );
2179
2180 // Field choices display value toggle.
2181 $builder.on(
2182 'change',
2183 '.everest-forms-field-option-row-show_values input',
2184 function (e) {
2185 $(this)
2186 .closest('.everest-forms-field-option')
2187 .find('.everest-forms-field-option-row-choices ul')
2188 .toggleClass('show-values');
2189 },
2190 );
2191
2192 // Field image choices toggle.
2193 $builder.on(
2194 'change',
2195 '.everest-forms-field-option-row-choices_images input',
2196 function () {
2197 var $this = $(this),
2198 field_id = $this.parent().parent().parent().data('field-id'),
2199 $fieldOptions = $('#everest-forms-field-option-' + field_id),
2200 $columnOptions = $(
2201 '#everest-forms-field-option-' + field_id + '-input_columns',
2202 ),
2203 type = $('#everest-forms-field-option-' + field_id)
2204 .find('.everest-forms-field-option-hidden-type')
2205 .val();
2206
2207 $this.parent().find('.notice').toggleClass('hidden');
2208 $fieldOptions
2209 .find('.everest-forms-field-option-row-choices ul')
2210 .toggleClass('show-images');
2211
2212 // Trigger columns changes.
2213 if ($this.is(':checked')) {
2214 $columnOptions.val('inline').trigger('change');
2215 } else {
2216 $columnOptions.val('').trigger('change');
2217 }
2218
2219 EVFPanelBuilder.choiceUpdate(type, field_id);
2220 },
2221 );
2222
2223 // Upload or add an image.
2224 $builder.on(
2225 'click',
2226 '.everest-forms-attachment-media-view .upload-button',
2227 function (event) {
2228 var $el = $(this),
2229 $wrapper,
2230 file_frame;
2231
2232 event.preventDefault();
2233
2234 // If the media frame already exists, reopen it.
2235 if (file_frame) {
2236 file_frame.open();
2237 return;
2238 }
2239
2240 // Create the media frame.
2241 file_frame = wp.media.frames.everestforms_media_frame = wp.media({
2242 title: evf_data.i18n_upload_image_title,
2243 className: 'media-frame everest-forms-media-frame',
2244 frame: 'select',
2245 multiple: false,
2246 library: {
2247 type: 'image',
2248 },
2249 button: {
2250 text: evf_data.i18n_upload_image_button,
2251 },
2252 });
2253
2254 // When an image is selected, run a callback.
2255 file_frame.on('select', function () {
2256 var attachment = file_frame
2257 .state()
2258 .get('selection')
2259 .first()
2260 .toJSON();
2261
2262 if ($el.hasClass('button-add-media')) {
2263 $el.hide();
2264 $wrapper = $el.parent();
2265 } else {
2266 $wrapper = $el.parent().parent().parent();
2267 }
2268
2269 $wrapper.find('.source').val(attachment.url);
2270 $wrapper.find('.attachment-thumb').remove();
2271 $wrapper
2272 .find('.thumbnail-image')
2273 .prepend(
2274 '<img class="attachment-thumb" src="' + attachment.url + '">',
2275 );
2276 $wrapper.find('.actions').show();
2277
2278 $builder.trigger('everestFormsImageUploadAdd', [$el, $wrapper]);
2279 });
2280
2281 // Finally, open the modal.
2282 file_frame.open();
2283 },
2284 );
2285
2286 // Remove and uploaded image.
2287 $builder.on(
2288 'click',
2289 '.everest-forms-attachment-media-view .remove-button',
2290 function (event) {
2291 event.preventDefault();
2292
2293 var $container = $(this).parent().parent();
2294
2295 $container.find('.attachment-thumb').remove();
2296 $container.parent().find('.source').val('');
2297 $container.parent().find('.button-add-media').show();
2298
2299 $builder.trigger('everestFormsImageUploadRemove', [
2300 $(this),
2301 $container,
2302 ]);
2303 },
2304 );
2305
2306 // Field choices image upload add/remove image.
2307 $builder.on(
2308 'everestFormsImageUploadAdd everestFormsImageUploadRemove',
2309 function (event, $this, $container) {
2310 var $el = $container.closest('.evf-choices-list'),
2311 type = $el.data('field-type'),
2312 field_id = $el.data('field-id');
2313
2314 EVFPanelBuilder.choiceUpdate(type, field_id);
2315 },
2316 );
2317
2318 // Toggle Layout advanced field option.
2319 $builder.on(
2320 'change',
2321 '.everest-forms-field-option-row-input_columns select',
2322 function () {
2323 var $this = $(this),
2324 value = $this.val(),
2325 field_id = $this.parent().data('field-id'),
2326 css_class = '';
2327
2328 if ('inline' === value) {
2329 css_class = 'everest-forms-list-inline';
2330 } else if ('' !== value) {
2331 css_class = 'everest-forms-list-' + value + '-columns';
2332 }
2333
2334 $('#everest-forms-field-' + field_id)
2335 .removeClass(
2336 'everest-forms-list-inline everest-forms-list-2-columns everest-forms-list-3-columns',
2337 )
2338 .addClass(css_class);
2339 },
2340 );
2341
2342 // Field sidebar tab toggle.
2343 $builder.on('click', '.everest-forms-fields-tab a', function (e) {
2344 e.preventDefault();
2345 EVFPanelBuilder.fieldTabChoice($(this).attr('id'));
2346 });
2347
2348 // Dragged field and hover over tab buttons - multipart.
2349 $(document).on(
2350 'mouseenter',
2351 '.everest-forms-tabs li[class*="part_"]',
2352 function () {
2353 if (
2354 false === $(this).hasClass('active') &&
2355 ($(document)
2356 .find('.everest-forms-field')
2357 .hasClass('ui-sortable-helper') ||
2358 $(document)
2359 .find('.evf-registered-buttons button.evf-registered-item')
2360 .hasClass('field-dragged'))
2361 ) {
2362 $(this).find('a').trigger('click');
2363 }
2364 },
2365 );
2366
2367 // Display toggle for "Address" field hidden option.
2368 $builder.on(
2369 'change',
2370 '.everest-forms-field-option-address input.hide',
2371 function () {
2372 var $this = $(this),
2373 id = $this.parent().parent().data('field-id'),
2374 subfield = $this.parent().parent().data('subfield');
2375 $('#everest-forms-field-' + id)
2376 .find('.everest-forms-' + subfield)
2377 .toggleClass('hidden');
2378 },
2379 );
2380
2381 // Real-time updates for "Show Label" field option.
2382 $builder.on(
2383 'input',
2384 '.everest-forms-field-option-row-label input',
2385 function () {
2386 var $this = $(this),
2387 value = $this
2388 .val()
2389 .replace(/<\s*script/gi, '')
2390 .replace(/\s+on\w+\s*=/gi, ' '),
2391 id = $this.parent().data('field-id'),
2392 $label = $('#everest-forms-field-' + id).find('.label-title .text');
2393 if ($label.hasClass('nl2br')) {
2394 $label.html(value.replace(/\n/g, '<br>'));
2395 } else if ('private-note' === $label.prevObject.data('field-type')) {
2396 value = value + ' (Admin Only)';
2397 $label.html(value);
2398 } else {
2399 $label.html(value);
2400 }
2401 },
2402 );
2403
2404 $builder.on(
2405 'change',
2406 '.everest-forms-field-option-row-enable_prepopulate input',
2407 function (event) {
2408 var id = $(this).parent().parent().parent().data('field-id');
2409
2410 $('#everest-forms-field-' + id).toggleClass('parameter_name');
2411
2412 // Toggle "Parameter Name" option.
2413 if ($(event.target).is(':checked')) {
2414 $(
2415 '#everest-forms-field-option-row-' + id + '-parameter_name',
2416 ).show();
2417 } else {
2418 $(
2419 '#everest-forms-field-option-row-' + id + '-parameter_name',
2420 ).hide();
2421 }
2422 },
2423 );
2424
2425 $builder.on(
2426 'change',
2427 '.everest-forms-field-option-row-enable_regex_validation input',
2428 function (event) {
2429 var id = $(this).parent().parent().parent().data('field-id');
2430
2431 $('#everest-forms-field-' + id).toggleClass('regex_value');
2432
2433 // Toggle "Parameter Name" option.
2434 if ($(event.target).is(':checked')) {
2435 $('#everest-forms-field-option-row-' + id + '-regex_value').show();
2436 $(
2437 '#everest-forms-field-option-row-' + id + '-regex_message',
2438 ).show();
2439 } else {
2440 $('#everest-forms-field-option-row-' + id + '-regex_value').hide();
2441 $(
2442 '#everest-forms-field-option-row-' + id + '-regex_message',
2443 ).hide();
2444 }
2445 },
2446 );
2447
2448 // Real-time updates for "Description" field option.
2449 $builder.on(
2450 'input',
2451 '.everest-forms-field-option-row-description textarea',
2452 function () {
2453 var $this = $(this);
2454 var id = $this.parent().data('field-id');
2455 var $desc = $('#everest-forms-field-' + id).find('.description');
2456 var value = $this.val();
2457
2458 // Sanitize the user input to prevent script injection, iframe injection, and remove event handlers
2459 value = value
2460 .replace(/<\s*script/gi, '')
2461 .replace(/<\s*iframe/gi, '')
2462 .replace(/\s+on\w+\s*=/gi, ' ');
2463
2464 if ($desc.hasClass('nl2br')) {
2465 $desc.html(value.replace(/\n/g, '<br>'));
2466 } else {
2467 $desc.html(value);
2468 }
2469 },
2470 );
2471
2472 // Real-time updates for "Required" field option.
2473 $builder.on(
2474 'change',
2475 '.everest-forms-field-option-row-required input',
2476 function (event) {
2477 var id = $(this).parent().parent().parent().data('field-id');
2478
2479 $('#everest-forms-field-' + id).toggleClass('required');
2480
2481 // Toggle "Required Field Message Setting" option.
2482 if ($(event.target).is(':checked')) {
2483 $(
2484 '#everest-forms-field-option-row-' +
2485 id +
2486 '-required_field_message_setting',
2487 ).show();
2488 if (
2489 $(
2490 '#everest-forms-field-option-' +
2491 id +
2492 '-required_field_message_setting-individual',
2493 ).is(':checked')
2494 ) {
2495 $(
2496 '#everest-forms-field-option-row-' +
2497 id +
2498 '-required-field-message',
2499 ).show();
2500 }
2501 } else {
2502 $(
2503 '#everest-forms-field-option-row-' +
2504 id +
2505 '-required_field_message_setting',
2506 ).hide();
2507 $(
2508 '#everest-forms-field-option-row-' +
2509 id +
2510 '-required-field-message',
2511 ).hide();
2512
2513 //unchecked the slot booking if date is not required.
2514 slot_booking = $(document).find(
2515 '.everest-forms-slot-booking input',
2516 );
2517 slot_booking.prop('checked', false);
2518 //show pass date input if hidden.
2519 $(document)
2520 .find('.everest-forms-past-date-disable-format input')
2521 .parent()
2522 .parent()
2523 .parent()
2524 .show();
2525 }
2526 },
2527 );
2528
2529 $builder.on(
2530 'change',
2531 '.everest-forms-field-option-row-required_field_message_setting input',
2532 function (event) {
2533 var id = $(this).parent().parent().parent().parent().data('field-id');
2534
2535 $('#everest-forms-field-' + id).toggleClass(
2536 'required_field_message_setting',
2537 );
2538
2539 // Toggle "Required Field Message" option.
2540 if ('individual' === $(this).val()) {
2541 $(
2542 '#everest-forms-field-option-row-' +
2543 id +
2544 '-required-field-message',
2545 ).show();
2546 } else {
2547 $(
2548 '#everest-forms-field-option-row-' +
2549 id +
2550 '-required-field-message',
2551 ).hide();
2552 }
2553 },
2554 );
2555
2556 // Real-time updates for "Confirmation" field option.
2557 $builder.on(
2558 'change',
2559 '.everest-forms-field-option-row-confirmation input',
2560 function (event) {
2561 var id = $(this).parent().parent().parent().data('field-id');
2562
2563 // Toggle "Confirmation" field option.
2564 if ($(event.target).is(':checked')) {
2565 $('#everest-forms-field-' + id)
2566 .find('.everest-forms-confirm')
2567 .removeClass('everest-forms-confirm-disabled')
2568 .addClass('everest-forms-confirm-enabled');
2569 $('#everest-forms-field-option-' + id)
2570 .removeClass('everest-forms-confirm-disabled')
2571 .addClass('everest-forms-confirm-enabled');
2572 } else {
2573 $('#everest-forms-field-' + id)
2574 .find('.everest-forms-confirm')
2575 .removeClass('everest-forms-confirm-enabled')
2576 .addClass('everest-forms-confirm-disabled');
2577 $('#everest-forms-field-option-' + id)
2578 .removeClass('everest-forms-confirm-enabled')
2579 .addClass('everest-forms-confirm-disabled');
2580 }
2581 },
2582 );
2583 // Real-time updates for slot booking
2584 $builder.on(
2585 'change',
2586 '.everest-forms-slot-booking input',
2587 function (event) {
2588 if ($(this).is(':checked')) {
2589 disable_past_date = $(document).find(
2590 '.everest-forms-past-date-disable-format input',
2591 );
2592 required = $(document).find(
2593 '.everest-forms-field-option-row-required input',
2594 );
2595
2596 //checked the required if it is not checked.
2597 if (required.is(':not(:checked)')) {
2598 required.prop('checked', true);
2599 }
2600
2601 if (disable_past_date.is(':not(:checked)')) {
2602 disable_past_date.prop('checked', true);
2603 }
2604 disable_past_date.parent().parent().parent().hide();
2605 } else {
2606 disable_past_date.parent().parent().parent().show();
2607 }
2608 },
2609 );
2610
2611 // Real-time updates for "Placeholder" field option.
2612 $builder.on(
2613 'input',
2614 '.everest-forms-field-option-row-placeholder input',
2615 function (e) {
2616 var $this = $(this),
2617 value = $this.val(),
2618 id = $this.parent().data('field-id'),
2619 $primary = $('#everest-forms-field-' + id).find(
2620 '.widefat:not(.secondary-input)',
2621 );
2622
2623 if ($primary.is('select')) {
2624 if (!value.length) {
2625 $primary.find('.placeholder').remove();
2626 } else {
2627 if ($primary.find('.placeholder').length) {
2628 $primary.find('.placeholder').text(value);
2629 } else {
2630 $primary.prepend(
2631 '<option class="placeholder" selected>' + value + '</option>',
2632 );
2633 }
2634
2635 $primary.data('placeholder', value);
2636
2637 if ($primary.hasClass('enhanced')) {
2638 $primary
2639 .parent()
2640 .find('.select2-search__field')
2641 .prop('placeholder', value);
2642 }
2643 }
2644 } else {
2645 $primary.attr('placeholder', value);
2646 }
2647 },
2648 );
2649
2650 // Real-time updates for "Address Placeholder" field options.
2651 $builder.on(
2652 'input',
2653 '.everest-forms-field-option-address input.placeholder',
2654 function (e) {
2655 var $this = $(this),
2656 value = $this.val(),
2657 id = $this.parent().parent().data('field-id'),
2658 subfield = $this.parent().parent().data('subfield');
2659 $('#everest-forms-field-' + id)
2660 .find('.everest-forms-' + subfield + ' input')
2661 .attr('placeholder', value);
2662 },
2663 );
2664
2665 // Real-time updates for "Confirmation Placeholder" field option.
2666 $builder.on(
2667 'input',
2668 '.everest-forms-field-option-row-confirmation_placeholder input',
2669 function () {
2670 var $this = $(this),
2671 value = $this.val(),
2672 id = $this.parent().data('field-id');
2673 $('#everest-forms-field-' + id)
2674 .find('.secondary-input')
2675 .attr('placeholder', value);
2676 },
2677 );
2678
2679 // Real-time updates for "Authorize.Net Card Number Placeholder" field option.
2680 $builder.on(
2681 'input',
2682 '.everest-forms-field-option-row-card_number_placeholder input',
2683 function () {
2684 var $this = $(this),
2685 value = $this.val(),
2686 id = $this.parent().data('field-id');
2687 $('#everest-forms-field-' + id)
2688 .find('.everest-forms-authorize-net-card-number input')
2689 .attr('placeholder', value);
2690 },
2691 );
2692
2693 // Real-time updates for "Authorize.Net CVC Placeholder" field option.
2694 $builder.on(
2695 'input',
2696 '.everest-forms-field-option-row-cvc_placeholder input',
2697 function () {
2698 var $this = $(this),
2699 value = $this.val(),
2700 id = $this.parent().data('field-id');
2701 $('#everest-forms-field-' + id)
2702 .find('.everest-forms-authorize-net-cvc input')
2703 .attr('placeholder', value);
2704 },
2705 );
2706
2707 // Real-time updates for "Hide Label" field option.
2708 $builder.on(
2709 'change',
2710 '.everest-forms-field-option-row-label_hide input',
2711 function () {
2712 var id = $(this).parent().parent().parent().data('field-id');
2713 $('#everest-forms-field-' + id).toggleClass('label_hide');
2714 },
2715 );
2716
2717 // Real-time updates for Sub Label visbility field option.
2718 $builder.on(
2719 'change',
2720 '.everest-forms-field-option-row-sublabel_hide input',
2721 function () {
2722 var id = $(this).parent().parent().parent().data('field-id');
2723 $('#everest-forms-field-' + id).toggleClass('sublabel_hide');
2724 },
2725 );
2726
2727 // Real-time updates for Date/Time and Name "Format" option.
2728 $builder.on(
2729 'change',
2730 '.everest-forms-field-option-row-datetime_format select, .everest-forms-field-option-row-phone_format select, .everest-forms-field-option-row-item_price select, .everest-forms-field-option-row-format select',
2731 function (e) {
2732 var $this = $(this),
2733 value = $this.val(),
2734 id = $this.parent().data('field-id');
2735 $('#everest-forms-field-' + id)
2736 .find('.format-selected')
2737 .removeClass()
2738 .addClass('format-selected format-selected-' + value);
2739 $('#everest-forms-field-option-' + id)
2740 .find('.format-selected')
2741 .removeClass()
2742 .addClass('format-selected format-selected-' + value);
2743 },
2744 );
2745
2746 // Setting options toggler.
2747 $builder.on(
2748 'change',
2749 '.everest-forms-field-option-row-datetime_style select',
2750 function () {
2751 EVFPanelBuilder.dateSettingToggler(
2752 $(this).parent().attr('data-field-id'),
2753 $(this).val(),
2754 );
2755 },
2756 );
2757
2758 // Enable Min Max Toggler.
2759 $(
2760 '.everest-forms-field-option-row-time_interval_format [id*=enable_min_max_time]',
2761 ).each(function () {
2762 if ($(this).prop('checked')) {
2763 $(this)
2764 .parent()
2765 .parent()
2766 .find('.input-group-col-2')
2767 .has(' [id*=min_time_hour]')
2768 .show();
2769 $(this)
2770 .parent()
2771 .parent()
2772 .find('.input-group-col-2')
2773 .has(' [id*=max_time_hour]')
2774 .show();
2775 $(this)
2776 .parent()
2777 .parent()
2778 .find('.input-group-col-2')
2779 .has(' [for*=select_min_time]')
2780 .show();
2781 $(this)
2782 .parent()
2783 .parent()
2784 .find('.input-group-col-2')
2785 .has('[for*=select_max_time]')
2786 .show();
2787 } else {
2788 $(this)
2789 .parent()
2790 .parent()
2791 .find('.input-group-col-2')
2792 .has('[id*=min_time_hour]')
2793 .hide();
2794 $(this)
2795 .parent()
2796 .parent()
2797 .find('.input-group-col-2')
2798 .has('[id*=max_time_hour]')
2799 .hide();
2800 $(this).parent().parent().find('[for*=select_min_time]').hide();
2801 $(this).parent().parent().find('[for*=select_max_time]').hide();
2802 }
2803 });
2804
2805 $builder.on(
2806 'click',
2807 '.everest-forms-field-option-row-time_interval_format [id*=enable_min_max_time]',
2808 function () {
2809 if ($(this).prop('checked')) {
2810 $(this)
2811 .parent()
2812 .parent()
2813 .find('.input-group-col-2')
2814 .has(' [id*=min_time_hour]')
2815 .show();
2816 $(this)
2817 .parent()
2818 .parent()
2819 .find('.input-group-col-2')
2820 .has(' [id*=max_time_hour]')
2821 .show();
2822 $(this).parent().parent().find('[for*=select_min_time]').show();
2823 $(this).parent().parent().find('[for*=select_max_time]').show();
2824 } else {
2825 $(this)
2826 .parent()
2827 .parent()
2828 .find('.input-group-col-2')
2829 .has('[id*=min_time_hour]')
2830 .hide();
2831 $(this)
2832 .parent()
2833 .parent()
2834 .find('.input-group-col-2')
2835 .has('[id*=max_time_hour]')
2836 .hide();
2837 $(this).parent().parent().find('[for*=select_min_time]').hide();
2838 $(this).parent().parent().find('[for*=select_max_time]').hide();
2839 }
2840 },
2841 );
2842
2843 // Time interval changes.
2844 $builder.on(
2845 'change',
2846 '.everest-forms-field-option-row-time_interval_format select[id*=time_format]',
2847 function () {
2848 min_hour = $(this)
2849 .parent()
2850 .siblings('.input-group-col-2')
2851 .find('[id*=min_time_hour]');
2852 max_hour = $(this)
2853 .parent()
2854 .siblings('.input-group-col-2')
2855 .find('[id*=max_time_hour]');
2856 var selected_min = min_hour.find('option:selected').val();
2857 var selected_max = max_hour.find('option:selected').val();
2858 var options = '',
2859 a,
2860 h;
2861 for (i = 0; i <= 23; i++) {
2862 if ($(this).val() === 'H:i') {
2863 options +=
2864 '<option value = "' +
2865 i +
2866 '">' +
2867 (i < 10 ? '0' + i : i) +
2868 '</option>';
2869 } else {
2870 a = ' PM';
2871 if (i < 12) {
2872 a = ' AM';
2873 h = i;
2874 } else {
2875 h = i - 12;
2876 }
2877 if (h == 0) {
2878 h = 12;
2879 }
2880 options += '<option value = "' + i + '">' + h + a + '</option>';
2881 }
2882 }
2883 min_hour.html(options);
2884 max_hour.html(options);
2885 min_hour
2886 .find('option[value=' + selected_min + ']')
2887 .prop('selected', true);
2888 max_hour
2889 .find('option[value=' + selected_max + ']')
2890 .prop('selected', true);
2891 },
2892 );
2893 },
2894
2895 /**
2896 * Setting options for Date Picker and Dropdown Toggler.
2897 */
2898 dateSettingToggler: function (id, type) {
2899 if (type == 'picker') {
2900 // Picker Date Setting Control
2901 $('#everest-forms-field-option-row-' + id + '-placeholder').show();
2902 $('#everest-forms-field-option-' + id + '-disable_dates').show();
2903 $(
2904 'label[for=everest-forms-field-option-' + id + '-disable_dates]',
2905 ).show();
2906 $('#everest-forms-field-option-' + id + '-date_mode-range')
2907 .parents()
2908 .find('everest-forms-checklist')
2909 .show();
2910 $('.everest-forms-field-option-row-date_format .time_interval').show();
2911 $('#everest-forms-field-option-' + id + '-date_localization').show();
2912 $(
2913 'label[for=everest-forms-field-option-' + id + '-date_localization]',
2914 ).show();
2915 $('#everest-forms-field-option-' + id + '-date_default')
2916 .parent()
2917 .parent()
2918 .parent()
2919 .show();
2920 $('#everest-forms-field-option-' + id + '-past_date_disable')
2921 .parent()
2922 .parent()
2923 .parent()
2924 .show();
2925 $('#everest-forms-field-option-' + id + '-enable_min_max')
2926 .parent()
2927 .parent()
2928 .parent()
2929 .show();
2930 //Check if min max date enabled.
2931 if (
2932 $('#everest-forms-field-option-' + id + '-enable_min_max').prop(
2933 'checked',
2934 )
2935 ) {
2936 $('#everest-forms-field-option-' + id + '-set_date_range')
2937 .parent()
2938 .show();
2939 if (
2940 $('#everest-forms-field-option-' + id + '-set_date_range').prop(
2941 'checked',
2942 )
2943 ) {
2944 $(
2945 '#everest-forms-field-option-row-' +
2946 id +
2947 '-date_format .everest-forms-min-max-date-range-option',
2948 ).removeClass('everest-forms-hidden');
2949 } else {
2950 $(
2951 '#everest-forms-field-option-row-' +
2952 id +
2953 '-date_format .everest-forms-min-max-date-option',
2954 ).removeClass('everest-forms-hidden');
2955 }
2956 }
2957 $('#everest-forms-field-option-' + id + '-time_interval').show();
2958 $('#everest-forms-field-option-' + id + '-enable_min_max_time')
2959 .parent()
2960 .parent()
2961 .parent()
2962 .hide();
2963 $(
2964 'label[for=everest-forms-field-option-' +
2965 id +
2966 '-enable_min_max_time]',
2967 ).hide();
2968 $(
2969 'label[for=everest-forms-field-option-' + id + '-select_min_time]',
2970 ).hide();
2971 $(
2972 'label[for=everest-forms-field-option-' + id + '-select_max_time]',
2973 ).hide();
2974 $('#everest-forms-field-option-' + id + '-min_time_hour')
2975 .parent()
2976 .hide();
2977 $('#everest-forms-field-option-' + id + '-max_time_hour')
2978 .parent()
2979 .hide();
2980 } else {
2981 // Dropdown Date Setting Control
2982 $('#everest-forms-field-option-' + id + '-date_mode-range')
2983 .parents()
2984 .find('everest-forms-checklist')
2985 .hide();
2986 $('#everest-forms-field-option-' + id + '-date_default')
2987 .parent()
2988 .parent()
2989 .parent()
2990 .hide();
2991 $('#everest-forms-field-option-' + id + '-past_date_disable')
2992 .parent()
2993 .parent()
2994 .parent()
2995 .hide();
2996 $('#everest-forms-field-option-row-' + id + '-placeholder').hide();
2997 $('#everest-forms-field-option-' + id + '-enable_min_max')
2998 .parent()
2999 .parent()
3000 .parent()
3001 .hide();
3002 $(
3003 '#everest-forms-field-option-row-' +
3004 id +
3005 '-date_format .everest-forms-min-max-date-option',
3006 ).addClass('everest-forms-hidden');
3007 $('#everest-forms-field-option-' + id + '-set_date_range')
3008 .parent()
3009 .parent()
3010 .parent()
3011 .hide();
3012 $(
3013 '#everest-forms-field-option-row-' +
3014 id +
3015 '-date_format .everest-forms-min-max-date-range-option',
3016 ).addClass('everest-forms-hidden');
3017 $('#everest-forms-field-option-' + id + '-disable_dates').hide();
3018 $(
3019 'label[for=everest-forms-field-option-' + id + '-disable_dates]',
3020 ).hide();
3021 $(
3022 '.everest-forms-field-option-row-date_format .everest-forms-checklist',
3023 ).hide();
3024 $('.everest-forms-field-option-row-date_format .time_interval').hide();
3025 $('#everest-forms-field-option-' + id + '-date_localization').hide();
3026 $(
3027 'label[for=everest-forms-field-option-' + id + '-date_localization]',
3028 ).hide();
3029 $('#everest-forms-field-option-' + id + '-time_interval').hide();
3030 $('#everest-forms-field-option-' + id + '-enable_min_max_time')
3031 .parent()
3032 .parent()
3033 .parent()
3034 .show();
3035 $(
3036 'label[for=everest-forms-field-option-' +
3037 id +
3038 '-enable_min_max_time]',
3039 ).show();
3040 //Check if min max time enabled.
3041 if (
3042 $('#everest-forms-field-option-' + id + '-enable_min_max_time').prop(
3043 'checked',
3044 )
3045 ) {
3046 $(
3047 'label[for=everest-forms-field-option-' + id + '-select_min_time]',
3048 ).show();
3049 $(
3050 'label[for=everest-forms-field-option-' + id + '-select_max_time]',
3051 ).show();
3052 $('#everest-forms-field-option-' + id + '-min_time_hour')
3053 .parent()
3054 .show();
3055 $('#everest-forms-field-option-' + id + '-max_time_hour')
3056 .parent()
3057 .show();
3058 }
3059 }
3060 },
3061
3062 /**
3063 * Make field choices sortable.
3064 *
3065 * @since 1.0.0
3066 *
3067 * @param {string} selector Selector.
3068 */
3069 choicesInit: function (selector) {
3070 selector = selector || '.everest-forms-field-option-row-choices ul';
3071
3072 $(selector).sortable({
3073 items: 'li',
3074 axis: 'y',
3075 handle: '.sort',
3076 scrollSensitivity: 40,
3077 stop: function (event) {
3078 var field_id = $(event.target).attr('data-field-id'),
3079 type = $('#everest-forms-field-option-' + field_id)
3080 .find('.everest-forms-field-option-hidden-type')
3081 .val();
3082
3083 EVFPanelBuilder.choiceUpdate(type, field_id);
3084 },
3085 });
3086 },
3087
3088 /**
3089 * Add new field choice.
3090 *
3091 * @since 1.6.0
3092 */
3093 choiceAdd: function (event, el, value) {
3094 if (event && event.preventDefault) {
3095 event.preventDefault();
3096 }
3097
3098 var $this = $(el),
3099 $parent = $this.parent(),
3100 checked = $parent.find('input.default').is(':checked'),
3101 fieldID = $this
3102 .closest('.everest-forms-field-option-row-choices')
3103 .data('field-id'),
3104 nextID = $parent.parent().attr('data-next-id'),
3105 type = $parent.parent().data('field-type'),
3106 $choice = $parent.clone().insertAfter($parent);
3107
3108 $choice.attr('data-key', nextID);
3109 $choice
3110 .find('input.label')
3111 .val(value)
3112 .attr(
3113 'name',
3114 'form_fields[' + fieldID + '][choices][' + nextID + '][label]',
3115 );
3116 $choice
3117 .find('input.value')
3118 .val(value)
3119 .attr(
3120 'name',
3121 'form_fields[' + fieldID + '][choices][' + nextID + '][value]',
3122 );
3123 $choice
3124 .find('input.source')
3125 .val('')
3126 .attr(
3127 'name',
3128 'form_fields[' + fieldID + '][choices][' + nextID + '][image]',
3129 );
3130 $choice
3131 .find('input.default')
3132 .attr(
3133 'name',
3134 'form_fields[' + fieldID + '][choices][' + nextID + '][default]',
3135 )
3136 .prop('checked', false);
3137 $choice.find('.attachment-thumb').remove();
3138 $choice.find('.button-add-media').show();
3139
3140 if ( 'payment-subscription-plan' === type ) {
3141 var oldChoiceKey = $parent.data( 'key' );
3142 $choice.find( 'input, select' ).each( function () {
3143 var name = $( this ).attr( 'name' );
3144 if ( name && name.indexOf( '[choices][' + oldChoiceKey + '][' ) !== -1 ) {
3145 $( this ).attr( 'name', name.replace(
3146 '[choices][' + oldChoiceKey + '][',
3147 '[choices][' + nextID + ']['
3148 ) );
3149 }
3150 } );
3151 $choice.find( '.evf-enable-trial-period' ).prop( 'checked', false );
3152 $choice.find( '.evf-enable-expiry-date' ).prop( 'checked', false );
3153 $choice.find( '[name*="[subscription_expiry_date]"]' ).val( '' );
3154 $choice.find( '.evf-spt-panel-detail' ).hide();
3155 $choice.find( '.evf-spt-dot' ).hide();
3156 }
3157
3158 if (checked === true) {
3159 $parent.find('input.default').prop('checked', true);
3160 }
3161
3162 nextID++;
3163 $parent.parent().attr('data-next-id', nextID);
3164 $builder.trigger('everestFormsChoiceAdd');
3165 EVFPanelBuilder.choiceUpdate(type, fieldID);
3166 },
3167
3168 /**
3169 * Delete field choice.
3170 *
3171 * @since 1.6.0
3172 */
3173 choiceDelete: function (event, el) {
3174 event.preventDefault();
3175
3176 var $this = $(el),
3177 $list = $this.parent().parent(),
3178 total = $list.find('li').length;
3179
3180 if (total < 2) {
3181 $.alert({
3182 title: false,
3183 content: evf_data.i18n_field_error_choice,
3184 icon: 'dashicons dashicons-info',
3185 type: 'blue',
3186 buttons: {
3187 ok: {
3188 text: evf_data.i18n_ok,
3189 btnClass: 'btn-confirm',
3190 keys: ['enter'],
3191 },
3192 },
3193 });
3194 } else {
3195 $this.parent().remove();
3196 EVFPanelBuilder.choiceUpdate(
3197 $list.data('field-type'),
3198 $list.data('field-id'),
3199 );
3200 $builder.trigger('everestFormsChoiceDelete');
3201 }
3202 },
3203
3204 /**
3205 * Update field choices in preview area, for the Fields panel.
3206 *
3207 * @since 1.6.0
3208 */
3209 choiceUpdate: function (type, id) {
3210 var $fieldOptions = $('#everest-forms-field-option-' + id);
3211 $primary = $('#everest-forms-field-' + id + ' .primary-input');
3212
3213 // Radio and Checkbox use _ template.
3214 if (
3215 'radio' === type ||
3216 'checkbox' === type ||
3217 'payment-multiple' === type ||
3218 'payment-checkbox' === type
3219 ) {
3220 var choices = [],
3221 formData = EVFPanelBuilder.formObject($fieldOptions),
3222 settings = formData.form_fields[id];
3223
3224 // Order of choices for a specific field.
3225 $('#everest-forms-field-option-' + id)
3226 .find('.evf-choices-list li')
3227 .each(function () {
3228 choices.push($(this).data('key'));
3229 });
3230
3231 var tmpl = wp.template('everest-forms-field-preview-choices'),
3232 type =
3233 'checkbox' === type || 'payment-checkbox' === type
3234 ? 'checkbox'
3235 : 'radio';
3236 data = {
3237 type: type,
3238 order: choices,
3239 settings: settings,
3240 amountFilter: EVFPanelBuilder.amountFilter,
3241 };
3242
3243 $('#everest-forms-field-' + id)
3244 .find('ul.primary-input')
3245 .replaceWith(tmpl(data));
3246
3247 return;
3248 }
3249
3250 if ('payment-subscription-plan' === type) {
3251 EVFPanelBuilder.subscriptionPlanChoiceUpdate(id);
3252 return;
3253 }
3254
3255 var new_choice;
3256
3257 if ('select' === type) {
3258 new_choice = '<option>{label}</option>';
3259 $primary.find('option').not('.placeholder').remove();
3260 }
3261
3262 $(
3263 '#everest-forms-field-option-row-' +
3264 id +
3265 '-choices .evf-choices-list li',
3266 ).each(function (index) {
3267 var $this = $(this),
3268 label = $this
3269 .find('input.label')
3270 .val()
3271 .replace(/<\s*script/gi, '')
3272 .replace(/\s+on\w+\s*=/gi, ' '),
3273 selected = $this.find('input.default').is(':checked'),
3274 choice = $(new_choice.replace('{label}', label));
3275
3276 $('#everest-forms-field-' + id + ' .primary-input').append(choice);
3277
3278 if (!label) {
3279 return;
3280 }
3281
3282 if (true === selected) {
3283 switch (type) {
3284 case 'select':
3285 choice.prop('selected', true);
3286 break;
3287 case 'radio':
3288 case 'checkbox':
3289 choice.find('input').prop('checked', true);
3290 break;
3291 }
3292 }
3293 });
3294 },
3295
3296 amountFilter: function (data, amount) {
3297 if ('right' === data.currency_symbol_pos) {
3298 return amount + ' ' + data.currency_symbol;
3299 } else {
3300 return data.currency_symbol + ' ' + amount;
3301 }
3302 },
3303
3304 /**
3305 * Re-render the builder canvas preview for a subscription plan field.
3306 *
3307 * @param {string|number} fieldId The field ID.
3308 */
3309 subscriptionPlanChoiceUpdate: function (fieldId) {
3310 var $optionsList = $('#everest-forms-field-option-row-' + fieldId + '-choices .evf-choices-list');
3311 var $preview = $('#everest-forms-field-' + fieldId + ' .primary-input');
3312 if (!$preview.length) {
3313 return;
3314 }
3315
3316 var periodSingular = { day: 'day', week: 'week', month: 'month', year: 'year' };
3317 var periodPlural = { day: 'days', week: 'weeks', month: 'months', year: 'years' };
3318
3319 var html = '';
3320
3321 $optionsList.find('li').each(function () {
3322 var $li = $(this);
3323 var label = $li.find('input.label').val() || '';
3324 var rawAmount = $li.find('input.value').val() || '0';
3325 var iCount = parseInt($li.find('input[name*="[interval_count]"]').val(), 10) || 1;
3326 var rPeriod = $li.find('select[name*="[recurring_period]"]').val() || 'month';
3327 var trialOn = $li.find('.evf-enable-trial-period').is(':checked');
3328 var tCount = parseInt($li.find('input[name*="[trail_interval_count]"]').val(), 10) || 1;
3329 var tPeriod = $li.find('select[name*="[trail_recurring_period]"]').val() || 'week';
3330 var isDefault = $li.find('input.default').is(':checked');
3331
3332 var pStr = iCount > 1
3333 ? (iCount + ' ' + (periodPlural[rPeriod] || rPeriod))
3334 : (periodSingular[rPeriod] || rPeriod);
3335 var periodSuffix = '/' + pStr;
3336 var amountStr = EVFPanelBuilder.amountFilter(evf_data, rawAmount);
3337
3338 var mainHtml = '<span class="evf-plan-main">'
3339 + '<span class="evf-plan-name">' + $('<span>').text(label).html() + '</span>'
3340 + '<strong class="evf-plan-price">' + $('<span>').text(amountStr + periodSuffix).html() + '</strong>'
3341 + '</span>';
3342
3343 var metaParts = [];
3344 if (trialOn) {
3345 var tStr = tCount + ' ' + (tCount > 1 ? (periodPlural[tPeriod] || tPeriod) : (periodSingular[tPeriod] || tPeriod));
3346 metaParts.push($('<span>').text(tStr + ' free trial').html());
3347 }
3348 var metaHtml = metaParts.length
3349 ? '<span class="evf-plan-meta">' + metaParts.join(' &middot; ') + '</span>'
3350 : '';
3351
3352 var liHtml = '<label class="everest-forms-field-label-inline"><span class="evf-plan-wrap">' + mainHtml + metaHtml + '</span></label>';
3353
3354 var itemClass = isDefault ? 'everest-forms-selected' : '';
3355 html += '<li class="' + itemClass + '"><input type="radio" disabled>' + liHtml + '</li>';
3356 });
3357
3358 $preview.html(html);
3359 },
3360
3361 bindFormSettings: function () {
3362 $('body').on('click', '.evf-setting-panel', function (e) {
3363 if ($(this).hasClass('upgrade-addons-settings')) {
3364 return;
3365 }
3366
3367 var data_setting_section = $(this).attr('data-section');
3368 $('.evf-setting-panel').removeClass('active');
3369 $('.everest-forms-active-email').removeClass('active');
3370 $('.everest-forms-active-sms-notifications').removeClass('active');
3371 $('.everest-forms-active-conversational-forms').removeClass('active');
3372 $('.evf-content-section').removeClass('active');
3373 $(this).addClass('active');
3374 $('.evf-content-' + data_setting_section + '-settings').addClass(
3375 'active',
3376 );
3377 e.preventDefault();
3378 });
3379
3380
3381 $('.evf-setting-panel').eq(0).trigger('click');
3382 },
3383 bindFormEmail: function () {
3384 $('body').on(
3385 'click',
3386 '.everest-forms-panel-sidebar-section-email',
3387 function (e) {
3388 $(this).siblings('.everest-forms-active-email').removeClass('active');
3389 $(this).next('.everest-forms-active-email').addClass('active');
3390 var container = $(this)
3391 .siblings('.everest-forms-active-email.active')
3392 .find('.everest-forms-active-email-connections-list li');
3393
3394 if (container.length) {
3395 container.children('.user-nickname').first().trigger('click');
3396 }
3397 e.preventDefault();
3398 },
3399 );
3400 },
3401 bindFormSmsNotifications: function () {
3402 $('body').on(
3403 'click',
3404 '.everest-forms-panel-sidebar-section-sms-notifications',
3405 function (e) {
3406 $(this)
3407 .siblings('.everest-forms-active-sms-notifications')
3408 .removeClass('active');
3409 $(this)
3410 .next('.everest-forms-active-sms-notifications')
3411 .addClass('active');
3412 var container = $(this)
3413 .siblings('.everest-forms-active-sms-notifications.active')
3414 .find(
3415 '.everest-forms-active-sms-notifications-connections-list li',
3416 );
3417
3418 if (container.length) {
3419 container.children('.user-nickname').first().trigger('click');
3420 }
3421 e.preventDefault();
3422 },
3423 );
3424 },
3425 bindFormConversational: function () {
3426 $('body').on(
3427 'click',
3428 '.everest-forms-panel-sidebar-section-conversational-forms ',
3429 function (e) {
3430 var $this = $(this);
3431 $(this)
3432 .siblings('.everest-forms-active-conversational-forms')
3433 .removeClass('active');
3434 $(this)
3435 .next('.everest-forms-active-conversational-forms')
3436 .addClass('active');
3437 var container = $(this).siblings(
3438 '.everest-forms-active-conversational-forms.active',
3439 );
3440
3441 if (container.length) {
3442 container.children('.evf-content-tab ').trigger('click');
3443 }
3444 e.preventDefault();
3445 },
3446 );
3447 },
3448 bindFormIntegrations: function () {
3449 $('body').on('click', '.evf-integrations-panel', function (e) {
3450 if ($(this).hasClass('upgrade-addons-settings')) {
3451 e.preventDefault();
3452 return;
3453 }
3454
3455 if ($(this).hasClass('evf-addon-install-trigger')) {
3456 e.preventDefault();
3457 return;
3458 }
3459
3460 var data_setting_section = $(this).attr('data-section');
3461 $('.evf-integrations-panel').removeClass('active');
3462 $('#everest-forms-panel-integrations')
3463 .find('.evf-panel-content-section')
3464 .removeClass('active');
3465 $(this).addClass('active');
3466 $(this)
3467 .parent()
3468 .find('.everest-forms-active-connections')
3469 .removeClass('active');
3470 $(this).next('.everest-forms-active-connections').addClass('active');
3471 var container = $(this)
3472 .siblings('.everest-forms-active-connections.active')
3473 .find('.everest-forms-active-connections-list li');
3474
3475 if (container.length) {
3476 container.children('.user-nickname').first().trigger('click');
3477 }
3478 $('.evf-panel-content-section-' + data_setting_section).addClass(
3479 'active',
3480 );
3481 e.preventDefault();
3482 });
3483 $('.evf-setting-panel').eq(0).trigger('click');
3484 },
3485 bindFormPayment: function () {
3486 $('body').on('click', '.evf-payments-panel', function (e) {
3487 if ($(this).hasClass('upgrade-addons-settings')) {
3488 e.preventDefault();
3489 return;
3490 }
3491
3492 var data_setting_section = $(this).attr('data-section');
3493 $('.evf-payments-panel').removeClass('active');
3494 $(this).siblings().removeClass('icon active');
3495 $(this).addClass('active');
3496 $(this)
3497 .parents('#everest-forms-panel-payments')
3498 .find('.evf-payment-setting-content')
3499 .removeClass('active')
3500 .hide();
3501 $('.evf-content-' + data_setting_section + '-settings')
3502 .addClass('active')
3503 .show();
3504 e.preventDefault();
3505 });
3506
3507 $('.evf-setting-panel').eq(0).trigger('click');
3508 },
3509 removeRow: function (row) {
3510 $.each(row.find('.everest-forms-field'), function () {
3511 var field_id = $(this).attr('data-field-id'),
3512 field_type = $(this).attr('data-field-type'),
3513 field_options = $('#everest-forms-field-option-' + field_id);
3514
3515 // Trigger before-delete event so addons can react.
3516 $(document.body).trigger('evf_before_field_deleted', [field_id]);
3517
3518 // Remove conditional logic references for this field.
3519 EVFPanelBuilder.conditionalLogicRemoveField(field_id);
3520 EVFPanelBuilder.conditionalLogicRemoveFieldIntegration(field_id);
3521 EVFPanelBuilder.paymentFieldRemoveFromQuantity(field_id);
3522 EVFPanelBuilder.oneTimeDraggableRemoveField(field_type);
3523
3524 $(this).remove();
3525
3526 field_options.remove();
3527 });
3528
3529 row.remove();
3530 },
3531 bindRemoveRow: function () {
3532 $('body').on('click', '.evf-delete-row', function () {
3533 var $this = $(this),
3534 total_rows = $('.evf-admin-row').length,
3535 current_row = $this.closest('.evf-admin-row'),
3536 row_id = current_row.attr('data-row-id'),
3537 current_part = $this
3538 .parents('.evf-admin-field-container')
3539 .attr('data-current-part'),
3540 multipart_active = $('#everest-forms-builder').hasClass(
3541 'multi-part-activated',
3542 );
3543
3544 if (current_part && multipart_active) {
3545 total_rows = $('#part_' + current_part).find('.evf-admin-row').length;
3546 }
3547
3548 if (total_rows < 2) {
3549 $.alert({
3550 title: evf_data.i18n_row_locked,
3551 content: evf_data.i18n_single_row_locked_msg,
3552 icon: 'dashicons dashicons-info',
3553 type: 'blue',
3554 buttons: {
3555 confirm: {
3556 text: evf_data.i18n_close,
3557 btnClass: 'btn-confirm',
3558 keys: ['enter'],
3559 },
3560 },
3561 });
3562 } else {
3563 $.confirm({
3564 title: false,
3565 content: evf_data.i18n_delete_row_confirm,
3566 type: 'red',
3567 closeIcon: false,
3568 backgroundDismiss: false,
3569 icon: 'dashicons dashicons-warning',
3570 buttons: {
3571 confirm: {
3572 text: evf_data.i18n_ok,
3573 btnClass: 'btn-confirm',
3574 keys: ['enter'],
3575 action: function () {
3576 EVFPanelBuilder.removeRow(current_row);
3577 $('.everest-forms-fields-tab')
3578 .find('a')
3579 .removeClass('active');
3580 $('.everest-forms-fields-tab')
3581 .find('a')
3582 .first()
3583 .addClass('active');
3584 $('.everest-forms-add-fields').show();
3585 $('#everest-forms-row-option-row_' + row_id).remove();
3586 },
3587 },
3588 cancel: {
3589 text: evf_data.i18n_cancel,
3590 },
3591 },
3592 });
3593 }
3594 });
3595 },
3596 /**
3597 * Row/canvas zones where layout presets can be dropped (main wrapper or multi-part #part_*).
3598 *
3599 * @return {jQuery}
3600 */
3601 getLayoutDropZones: function () {
3602 var $collection = $();
3603 $('.evf-admin-field-wrapper').each(function () {
3604 var $w = $(this);
3605 var $parts = $w.children('[id^="part_"]');
3606 if ($parts.length) {
3607 $collection = $collection.add($parts);
3608 } else {
3609 $collection = $collection.add($w);
3610 }
3611 });
3612 return $collection;
3613 },
3614 /**
3615 * Add a new row with a specific column layout.
3616 *
3617 * @param {number} columns Number of columns (1–4).
3618 * @param {jQuery|null} $afterRow Insert after this row.
3619 * @param {jQuery|null} $beforeRow Insert before this row (takes precedence over $afterRow).
3620 * @param {jQuery|null} $dropContext Element inside the builder (e.g. drop zone) to resolve multi-part wrapper.
3621 */
3622 addLayoutContainer: function (columns, $afterRow, $beforeRow, $dropContext) {
3623 var wrapper = $('.evf-admin-field-wrapper');
3624
3625 if ($dropContext && $dropContext.length) {
3626 var current_part = $dropContext
3627 .closest('.evf-admin-field-container')
3628 .attr('data-current-part');
3629 if (current_part) {
3630 var $partWrap = wrapper.find('#part_' + current_part);
3631 if ($partWrap.length) {
3632 wrapper = $partWrap;
3633 }
3634 }
3635 }
3636
3637 var row_ids = $('.evf-admin-row')
3638 .map(function () {
3639 return $(this).data('row-id');
3640 })
3641 .get(),
3642 max_row_id = row_ids.length ? Math.max.apply(Math, row_ids) : 0,
3643 row_clone = $('.evf-admin-row').eq(0).clone(),
3644 total_rows =
3645 parseInt($('.evf-add-row').first().attr('data-total-rows'), 10) || 0;
3646
3647 var current_part = $('.evf-admin-field-container').attr('data-current-part');
3648
3649 if (current_part) {
3650 wrapper = $('.evf-admin-field-wrapper').find('#part_' + current_part);
3651 }
3652
3653 max_row_id++;
3654 total_rows++;
3655
3656 row_clone.find('.evf-admin-grid').html('');
3657 row_clone.attr('data-row-id', max_row_id);
3658
3659 $('.evf-add-row').attr('data-total-rows', total_rows);
3660 $('.evf-add-row').attr('data-next-row-id', max_row_id);
3661
3662 if ($beforeRow && $beforeRow.length) {
3663 $beforeRow.before(row_clone);
3664 } else if ($afterRow && $afterRow.length) {
3665 $afterRow.after(row_clone);
3666 } else {
3667 wrapper.append(row_clone);
3668 }
3669
3670 row_clone
3671 .find('.evf-grid-selector[data-evf-grid="' + columns + '"]')
3672 .trigger('click');
3673
3674 EVFPanelBuilder.bindFields();
3675 EVFPanelBuilder.checkEmptyGrid();
3676
3677 if ($('.everest-forms-row-options').length) {
3678 var _row_id = max_row_id,
3679 _evf_data = window.evf_data;
3680 $.ajax({
3681 url: _evf_data.ajax_url,
3682 type: 'POST',
3683 data: {
3684 action: 'everest_forms_new_row',
3685 security: _evf_data.evf_add_row_nonce,
3686 form_id: _evf_data.form_id,
3687 row_id: _row_id,
3688 },
3689 success: function (xhr) {
3690 if (true === xhr.success && 'undefined' !== typeof xhr.data.html) {
3691 $(document)
3692 .find('.everest-forms-row-option-group')
3693 .append(xhr.data.html);
3694 EVFPanelBuilder.conditionalLogicAppendRow(_row_id);
3695 $(
3696 '#everest-forms-panel-field-form_rows-connection_row_' +
3697 _row_id +
3698 '-conditional_logic_status',
3699 ).prop('checked', false);
3700 }
3701 },
3702 });
3703 }
3704
3705 $('html, body').animate({ scrollTop: row_clone.offset().top - 100 }, 400);
3706 },
3707 bindLayoutContainers: function () {
3708 $('body').on('click', '.evf-layout-container-btn', function () {
3709 var columns = parseInt($(this).data('columns'), 10),
3710 $fieldContainer = $('.evf-admin-field-container:visible').first();
3711
3712 if (!$fieldContainer.length) {
3713 $fieldContainer = $('.evf-admin-field-container').first();
3714 }
3715
3716 var wrapper = $('.evf-admin-field-wrapper'),
3717 current_part = $fieldContainer.attr('data-current-part');
3718
3719 if (current_part) {
3720 var $partWrap = wrapper.find('#part_' + current_part);
3721 if ($partWrap.length) {
3722 wrapper = $partWrap;
3723 }
3724 }
3725
3726 var $lastRow = wrapper.children('.evf-admin-row').last();
3727 if ($lastRow.length) {
3728 EVFPanelBuilder.addLayoutContainer(
3729 columns,
3730 $lastRow,
3731 null,
3732 $fieldContainer,
3733 );
3734 } else {
3735 EVFPanelBuilder.addLayoutContainer(
3736 columns,
3737 null,
3738 null,
3739 $fieldContainer,
3740 );
3741 }
3742 });
3743 },
3744 bindAddRowColumnPicker: function () {
3745 if (!$('#evf-add-row-picker').length) {
3746 var $pickerGrid = $('<div></div>').css({
3747 display: 'grid',
3748 'grid-template-columns': 'repeat(4, 1fr)',
3749 gap: '6px',
3750 });
3751
3752 $('.evf-layout-container-btn').each(function () {
3753 var $btn = $(this),
3754 cols = parseInt($btn.data('columns'), 10),
3755 label = $btn.text().trim(),
3756 svgHtml = $btn.find('svg').prop('outerHTML') || '';
3757
3758 var $pickerBtn = $('<button type="button"></button>')
3759 .attr('data-columns', cols)
3760 .css({
3761 display: 'flex',
3762 'flex-direction': 'column',
3763 'align-items': 'center',
3764 'justify-content': 'center',
3765 padding: '10px 8px',
3766 border: '1px solid #edeff7',
3767 'border-radius': '4px',
3768 cursor: 'pointer',
3769 'font-size': '11px',
3770 'text-align': 'center',
3771 background: '#fbfbfd',
3772 color: '#383838',
3773 gap: '4px',
3774 'min-width': '80px',
3775 transition: 'border-color .12s,color .12s,background .12s',
3776 })
3777 .append(
3778 $('<span></span>')
3779 .css({ display: 'block', 'line-height': '1' })
3780 .html(svgHtml),
3781 )
3782 .append($('<span></span>').text(label));
3783
3784 $pickerGrid.append($pickerBtn);
3785 });
3786
3787 $('body').append(
3788 $('<div id="evf-add-row-picker"></div>')
3789 .css({
3790 display: 'none',
3791 position: 'fixed',
3792 background: '#fff',
3793 border: '1px solid #edeff7',
3794 'border-radius': '8px',
3795 'box-shadow': '0 8px 24px rgba(0,0,0,.08)',
3796 'z-index': '999999',
3797 padding: '10px',
3798 overflow: 'visible',
3799 })
3800 .append(
3801 '<div id="evf-add-row-picker-arrow" style="position:absolute;left:50%;transform:translateX(-50%);width:14px;height:8px;pointer-events:none;"></div>',
3802 )
3803 .append($pickerGrid),
3804 );
3805
3806 $('head').append(
3807 '<style id="evf-add-row-picker-style">' +
3808 '#evf-add-row-picker-arrow::before,#evf-add-row-picker-arrow::after{content:"";position:absolute;left:0;border-left:7px solid transparent;border-right:7px solid transparent}' +
3809 '#evf-add-row-picker-arrow::before{border-top:8px solid #edeff7;top:0}' +
3810 '#evf-add-row-picker-arrow::after{border-top:8px solid #fff;top:-1px}' +
3811 '#evf-add-row-picker-arrow.evf-arrow-down::before{border-top:none;border-bottom:8px solid #edeff7;top:auto;bottom:0}' +
3812 '#evf-add-row-picker-arrow.evf-arrow-down::after{border-top:none;border-bottom:8px solid #fff;bottom:1px}' +
3813 '</style>',
3814 );
3815
3816 $('#evf-add-row-picker svg').css({
3817 width: '24px',
3818 height: '24px',
3819 display: 'block',
3820 });
3821 }
3822
3823 // Intercept Add Row click (non-repeater) before bindAddNewRow fires.
3824 $('body').on(
3825 'click',
3826 '.evf-add-row:not(.repeater-row) span',
3827 function (e) {
3828 e.stopImmediatePropagation();
3829 var $span = $(this),
3830 $picker = $('#evf-add-row-picker'),
3831 $arrow = $('#evf-add-row-picker-arrow');
3832
3833 if ($picker.is(':visible')) {
3834 $picker.hide();
3835 return;
3836 }
3837
3838 var offset = $span.offset(),
3839 scrollLeft = $(window).scrollLeft(),
3840 scrollTop = $(window).scrollTop(),
3841 spanCX = offset.left - scrollLeft + $span.outerWidth() / 2,
3842 margin = 8;
3843
3844 $picker.show();
3845
3846 var pickerH = $picker.outerHeight(),
3847 pickerW = $picker.outerWidth(),
3848 top = offset.top - scrollTop - pickerH - 8,
3849 flipped = false;
3850
3851 if (top < margin) {
3852 top = offset.top - scrollTop + $span.outerHeight() + 8;
3853 flipped = true;
3854 }
3855
3856 var left = spanCX - pickerW / 2;
3857 left = Math.min(
3858 Math.max(margin, left),
3859 window.innerWidth - pickerW - margin,
3860 );
3861
3862 // Arrow: points toward the button
3863 var arrowX = spanCX - left - 7;
3864 arrowX = Math.min(Math.max(14, arrowX), pickerW - 28);
3865 if (flipped) {
3866 // Picker is below button — arrow at top pointing up toward button
3867 $arrow
3868 .addClass('evf-arrow-down')
3869 .css({ top: '-8px', bottom: 'auto', left: arrowX + 'px' });
3870 } else {
3871 // Picker is above button — arrow at bottom pointing down toward button
3872 $arrow
3873 .removeClass('evf-arrow-down')
3874 .css({ bottom: '-8px', top: 'auto', left: arrowX + 'px' });
3875 }
3876
3877 $picker.css({ top: top, left: left });
3878 },
3879 );
3880
3881 $(document.body).on(
3882 'click',
3883 '#evf-add-row-picker button[data-columns]',
3884 function () {
3885 var cols = parseInt($(this).data('columns'), 10);
3886 $('#evf-add-row-picker').hide();
3887 var $fieldContainer = $('.evf-admin-field-container:visible').first();
3888 if (!$fieldContainer.length) {
3889 $fieldContainer = $('.evf-admin-field-container').first();
3890 }
3891
3892 var wrapper = $('.evf-admin-field-wrapper'),
3893 current_part = $fieldContainer.attr('data-current-part');
3894
3895 if (current_part) {
3896 var $partWrap = wrapper.find('#part_' + current_part);
3897 if ($partWrap.length) {
3898 wrapper = $partWrap;
3899 }
3900 }
3901
3902 var $lastRow = wrapper.children('.evf-admin-row').last();
3903 if ($lastRow.length) {
3904 EVFPanelBuilder.addLayoutContainer(
3905 cols,
3906 $lastRow,
3907 null,
3908 $fieldContainer,
3909 );
3910 } else {
3911 EVFPanelBuilder.addLayoutContainer(
3912 cols,
3913 null,
3914 null,
3915 $fieldContainer,
3916 );
3917 }
3918 },
3919 );
3920
3921 $(document.body)
3922 .on(
3923 'mouseenter',
3924 '#evf-add-row-picker button[data-columns]',
3925 function () {
3926 $(this).css({
3927 'border-color': '#8c64c6',
3928 color: '#8c64c6',
3929 background: '#fff',
3930 });
3931 },
3932 )
3933 .on(
3934 'mouseleave',
3935 '#evf-add-row-picker button[data-columns]',
3936 function () {
3937 $(this).css({
3938 'border-color': '#edeff7',
3939 color: '#383838',
3940 background: '#fbfbfd',
3941 });
3942 },
3943 );
3944
3945 $(document).on('click.evf-add-row-picker', function (e) {
3946 if (!$(e.target).closest('#evf-add-row-picker, .evf-add-row').length) {
3947 $('#evf-add-row-picker').hide();
3948 }
3949 });
3950 },
3951 bindAddNewRow: function () {
3952 $('body').on('click', '.evf-add-row span', function () {
3953 $('#add-fields').trigger('click');
3954 var $this = $(this),
3955 wrapper = $('.evf-admin-field-wrapper'),
3956 row_ids = $('.evf-admin-row')
3957 .map(function () {
3958 return $(this).data('row-id');
3959 })
3960 .get(),
3961 max_row_id = Math.max.apply(Math, row_ids),
3962 row_clone = $('.evf-admin-row').eq(0).clone(),
3963 total_rows = $this.parent().attr('data-total-rows'),
3964 current_part = $this
3965 .parents('.evf-admin-field-container')
3966 .attr('data-current-part');
3967
3968 max_row_id++;
3969 total_rows++;
3970
3971 if (current_part) {
3972 wrapper = $('.evf-admin-field-wrapper').find('#part_' + current_part);
3973 }
3974
3975 // Row clone.
3976 row_clone.find('.evf-admin-grid').html('');
3977 row_clone.attr('data-row-id', max_row_id);
3978
3979 // Row infos.
3980 $this.parent().attr('data-total-rows', total_rows);
3981 $this.parent().attr('data-next-row-id', max_row_id);
3982
3983 if (
3984 0 < $('.everest-forms-row-options').length &&
3985 false === $this.closest('.evf-add-row').hasClass('repeater-row')
3986 ) {
3987 row_clone.find('div').hide();
3988
3989 row_clone
3990 .css({
3991 padding: '40px',
3992 })
3993 .append(
3994 '<i class="spinner is-active" style="margin:0px auto;"></i>',
3995 );
3996
3997 // Row append.
3998 wrapper.append(row_clone);
3999
4000 // Initialize fields UI.
4001 EVFPanelBuilder.bindFields();
4002 EVFPanelBuilder.checkEmptyGrid();
4003
4004 var row_id = row_clone.attr('data-row-id'),
4005 evf_data = window.evf_data;
4006 $.ajax({
4007 url: evf_data.ajax_url,
4008 type: 'POST',
4009 data: {
4010 action: 'everest_forms_new_row',
4011 security: evf_data.evf_add_row_nonce,
4012 form_id: evf_data.form_id,
4013 row_id: row_id,
4014 },
4015 success: function (xhr) {
4016 if (true === xhr.success) {
4017 if ('undefined' !== typeof xhr.data.html) {
4018 $(document)
4019 .find('.everest-forms-row-option-group')
4020 .append(xhr.data.html);
4021 EVFPanelBuilder.conditionalLogicAppendRow(row_id);
4022 // Disable conditional logic by default.
4023 $(
4024 '#everest-forms-panel-field-form_rows-connection_row_' +
4025 row_id +
4026 '-conditional_logic_status',
4027 ).prop('checked', false);
4028 }
4029 }
4030 },
4031 }).always(function () {
4032 row_clone.css({ padding: 0 });
4033
4034 row_clone.find('div').show();
4035
4036 row_clone.find('.evf-toggle-row-content').css('display', 'none');
4037
4038 row_clone.find('i').remove();
4039
4040 // Trigger event after row add.
4041 $this.trigger('everest-forms-after-add-row', row_clone);
4042 });
4043 } else {
4044 // Row append.
4045 wrapper.append(row_clone);
4046 // Initialize fields UI.
4047 EVFPanelBuilder.bindFields();
4048 EVFPanelBuilder.checkEmptyGrid();
4049 // Trigger event after row add.
4050 $this.trigger('everest-forms-after-add-row', row_clone);
4051 }
4052 });
4053 },
4054 bindCloneField: function () {
4055 $('body').on(
4056 'click',
4057 '.everest-forms-preview .everest-forms-field .everest-forms-field-duplicate',
4058 function () {
4059 var $field = $(this).closest('.everest-forms-field');
4060
4061 if ($field.hasClass('no-duplicate')) {
4062 $.alert({
4063 title: evf_data.i18n_field_locked,
4064 content: evf_data.i18n_field_locked_msg,
4065 icon: 'dashicons dashicons-info',
4066 type: 'blue',
4067 buttons: {
4068 confirm: {
4069 text: evf_data.i18n_close,
4070 btnClass: 'btn-confirm',
4071 keys: ['enter'],
4072 },
4073 },
4074 });
4075 } else {
4076 $.confirm({
4077 title: false,
4078 content: evf_data.i18n_duplicate_field_confirm,
4079 type: 'orange',
4080 closeIcon: false,
4081 backgroundDismiss: false,
4082 icon: 'dashicons dashicons-warning',
4083 buttons: {
4084 confirm: {
4085 text: evf_data.i18n_ok,
4086 btnClass: 'btn-confirm',
4087 keys: ['enter'],
4088 action: function () {
4089 EVFPanelBuilder.cloneFieldAction($field);
4090 },
4091 },
4092 cancel: {
4093 text: evf_data.i18n_cancel,
4094 },
4095 },
4096 });
4097 }
4098 },
4099 );
4100
4101 $('body').on('click', '.evf-admin-row .evf-duplicate-row', function () {
4102 var $row = $(this).closest('.evf-admin-row');
4103 if ($row.find('.everest-forms-field').hasClass('no-duplicate')) {
4104 $.alert({
4105 title: evf_data.i18n_field_locked,
4106 content: evf_data.i18n_row_locked_msg,
4107 icon: 'dashicons dashicons-info',
4108 type: 'blue',
4109 buttons: {
4110 confirm: {
4111 text: evf_data.i18n_close,
4112 btnClass: 'btn-confirm',
4113 keys: ['enter'],
4114 },
4115 },
4116 });
4117 } else {
4118 $.confirm({
4119 title: false,
4120 content: evf_data.i18n_duplicate_row_confirm,
4121 type: 'orange',
4122 closeIcon: false,
4123 backgroundDismiss: false,
4124 icon: 'dashicons dashicons-warning',
4125 buttons: {
4126 confirm: {
4127 text: evf_data.i18n_ok,
4128 btnClass: 'btn-confirm',
4129 keys: ['enter'],
4130 action: function () {
4131 EVFPanelBuilder.cloneRowAction($row);
4132 },
4133 },
4134 cancel: {
4135 text: evf_data.i18n_cancel,
4136 },
4137 },
4138 });
4139 }
4140 });
4141 },
4142 cloneRowAction: function (row) {
4143 (row_ids = $('.evf-admin-row')
4144 .map(function () {
4145 return $(this).data('row-id');
4146 })
4147 .get()),
4148 (max_row_id = Math.max.apply(Math, row_ids)),
4149 (row_clone = row.clone()),
4150 (total_rows = $('.evf-add-row').attr('data-total-rows'));
4151 max_row_id++;
4152 total_rows++;
4153
4154 // New row ID.
4155 row_clone.attr('data-row-id', max_row_id);
4156 // Initialize fields UI.
4157 $('.evf-add-row').attr('data-total-rows', total_rows);
4158 $('.evf-add-row').attr('data-next-row-id', max_row_id);
4159
4160 var data = {
4161 action: 'everest_forms_get_next_id',
4162 security: evf_data.evf_get_next_id,
4163 form_id: evf_data.form_id,
4164 fields: row_clone.find('.everest-forms-field').length,
4165 };
4166
4167 $.ajax({
4168 url: evf_data.ajax_url,
4169 data: data,
4170 type: 'POST',
4171 beforeSend: function () {
4172 $(document.body).trigger('init_field_options_toggle');
4173 },
4174 success: function (response) {
4175 if (
4176 typeof response.success === 'boolean' &&
4177 response.success === true
4178 ) {
4179 // Row append.
4180 row.after(row_clone);
4181 // Duplicating Fields
4182 $.each(response.data, function (index, data) {
4183 var field_id = data.field_id;
4184 var field_key = data.field_key;
4185 $('#everest-forms-field-id').val(field_id);
4186 field = row_clone.find('.everest-forms-field').eq(index);
4187 var element_field_id = field.attr('data-field-id');
4188 EVFPanelBuilder.render_node(field, element_field_id, field_key);
4189 field.remove();
4190 $(document.body).trigger('init_field_options_toggle');
4191 });
4192 // Binding fields.
4193 EVFPanelBuilder.bindFields();
4194 }
4195 },
4196 });
4197 },
4198 cloneFieldAction: function (field) {
4199 var element_field_id = field.attr('data-field-id');
4200 var form_id = evf_data.form_id;
4201 var data = {
4202 action: 'everest_forms_get_next_id',
4203 security: evf_data.evf_get_next_id,
4204 form_id: form_id,
4205 };
4206 $.ajax({
4207 url: evf_data.ajax_url,
4208 data: data,
4209 type: 'POST',
4210 beforeSend: function () {
4211 $(document.body).trigger('init_field_options_toggle');
4212 },
4213 success: function (response) {
4214 if (
4215 typeof response.success === 'boolean' &&
4216 response.success === true
4217 ) {
4218 var field_id = response.data.field_id;
4219 var field_key = response.data.field_key;
4220 $('#everest-forms-field-id').val(field_id);
4221 EVFPanelBuilder.render_node(field, element_field_id, field_key);
4222 $(document.body).trigger('init_field_options_toggle');
4223 }
4224 },
4225 });
4226 },
4227 render_node: function (field, old_key, new_key) {
4228 var option = $(
4229 '.everest-forms-field-options #everest-forms-field-option-' + old_key,
4230 );
4231 var old_field_label = $(
4232 '#everest-forms-field-option-' + old_key + '-label',
4233 ).val();
4234 var old_field_meta_key = $(
4235 '#everest-forms-field-option-' + old_key + '-meta-key',
4236 ).length
4237 ? $('#everest-forms-field-option-' + old_key + '-meta-key').val()
4238 : '';
4239 var field_type = field.attr('data-field-type'),
4240 newOptionHtml = option.html(),
4241 new_field_label = old_field_label + ' ' + evf_data.i18n_copy,
4242 new_meta_key =
4243 'html' !== field_type
4244 ? old_field_meta_key
4245 .replace(/\(|\)/g, '')
4246 .toLowerCase()
4247 .substring(0, old_field_meta_key.lastIndexOf('_')) +
4248 '_' +
4249 Math.floor(1000 + Math.random() * 9000)
4250 : '',
4251 newFieldCloned = field.clone();
4252 var regex = new RegExp(old_key, 'g');
4253 newOptionHtml = newOptionHtml.replace(regex, new_key);
4254 var newOption = $(
4255 '<div class="everest-forms-field-option everest-forms-field-option-' +
4256 field_type +
4257 '" id="everest-forms-field-option-' +
4258 new_key +
4259 '" data-field-id="' +
4260 new_key +
4261 '" />',
4262 );
4263 newOption.append(newOptionHtml);
4264 $.each(option.find(':input'), function () {
4265 var type = $(this).attr('type');
4266 var name = $(this).attr('name') ? $(this).attr('name') : '';
4267 var new_name = name.replace(regex, new_key);
4268 var value = '';
4269 if (type === 'text' || type === 'hidden') {
4270 value = $(this).val();
4271 newOption.find('input[name="' + new_name + '"]').val(value);
4272 newOption.find('input[value="' + old_key + '"]').val(new_key);
4273 } else if (type === 'checkbox' || type === 'radio') {
4274 if ($(this).is(':checked')) {
4275 newOption
4276 .find('input[name="' + new_name + '"]')
4277 .prop('checked', true)
4278 .attr('checked', 'checked');
4279 } else {
4280 newOption
4281 .find('[name="' + new_name + '"]')
4282 .prop('checked', false)
4283 .attr('checked', false);
4284 }
4285 } else if ($(this).is('select')) {
4286 if ($(this).find('option:selected').length) {
4287 var option_value = $(this).find('option:selected').val();
4288 newOption
4289 .find('[name="' + new_name + '"]')
4290 .find('[value="' + option_value + '"]')
4291 .prop('selected', true);
4292 }
4293 } else {
4294 if ($(this).val() !== '') {
4295 newOption.find('[name="' + new_name + '"]').val($(this).val());
4296 }
4297 }
4298 });
4299
4300 $('.everest-forms-field-options').append(newOption);
4301 $('#everest-forms-field-option-' + new_key + '-label').val(
4302 new_field_label,
4303 );
4304 $('#everest-forms-field-option-' + new_key + '-meta-key').val(
4305 new_meta_key,
4306 );
4307
4308 // Field Clone
4309 newFieldCloned.attr('class', field.attr('class'));
4310 newFieldCloned.attr('id', 'everest-forms-field-' + new_key);
4311 newFieldCloned.attr('data-field-id', new_key);
4312 newFieldCloned.attr('data-field-type', field_type);
4313 newFieldCloned.find('.label-title .text').text(new_field_label);
4314 field
4315 .closest('.evf-admin-grid')
4316 .find('[data-field-id="' + old_key + '"]')
4317 .after(newFieldCloned);
4318 $(document).trigger('everest-form-cloned', [new_key, field_type]);
4319 EVFPanelBuilder.switchToFieldOptionPanel(new_key); //switch to cloned field options
4320
4321 // Trigger an event indicating completion of render_node action for cloning.
4322 $(document.body).trigger('evf_render_node_complete', [
4323 field_type,
4324 new_key,
4325 newFieldCloned,
4326 newOption,
4327 ]);
4328 EVFPanelBuilder.updateBulkActionBar();
4329 },
4330 bindFieldDelete: function () {
4331 $('body').on(
4332 'click',
4333 '.everest-forms-preview .everest-forms-field .everest-forms-field-delete',
4334 function () {
4335 var $field = $(this).closest('.everest-forms-field');
4336 var field_id = $field.attr('data-field-id');
4337 var option_field = $('#everest-forms-field-option-' + field_id);
4338 var grid = $(this).closest('.evf-admin-grid');
4339
4340 if ($field.hasClass('no-delete')) {
4341 $.alert({
4342 title: evf_data.i18n_field_locked,
4343 content: evf_data.i18n_field_locked_msg,
4344 icon: 'dashicons dashicons-info',
4345 type: 'blue',
4346 buttons: {
4347 confirm: {
4348 text: evf_data.i18n_close,
4349 btnClass: 'btn-confirm',
4350 keys: ['enter'],
4351 },
4352 },
4353 });
4354 } else {
4355 $.confirm({
4356 title: false,
4357 content: evf_data.i18n_delete_field_confirm,
4358 type: 'red',
4359 closeIcon: false,
4360 backgroundDismiss: false,
4361 icon: 'dashicons dashicons-warning',
4362 buttons: {
4363 confirm: {
4364 text: evf_data.i18n_ok,
4365 btnClass: 'btn-confirm',
4366 keys: ['enter'],
4367 action: function () {
4368 $('.evf-panel-fields-button').trigger('click');
4369 $field.fadeOut('slow', function () {
4370 var removed_el_id = $field.attr('data-field-id');
4371 var field_type = $field.attr('data-field-type');
4372 $(document.body).trigger('evf_before_field_deleted', [
4373 removed_el_id,
4374 ]);
4375 $field.remove();
4376 option_field.remove();
4377 EVFPanelBuilder.checkEmptyGrid();
4378 $('.everest-forms-fields-tab')
4379 .find('a')
4380 .removeClass('active');
4381 $('.everest-forms-fields-tab')
4382 .find('a')
4383 .first()
4384 .addClass('active');
4385 $('.everest-forms-add-fields').show();
4386 EVFPanelBuilder.conditionalLogicRemoveField(
4387 removed_el_id,
4388 );
4389 EVFPanelBuilder.conditionalLogicRemoveFieldIntegration(
4390 removed_el_id,
4391 );
4392 EVFPanelBuilder.paymentFieldRemoveFromQuantity(
4393 removed_el_id,
4394 );
4395 EVFPanelBuilder.oneTimeDraggableRemoveField(field_type);
4396 });
4397 },
4398 },
4399 cancel: {
4400 text: evf_data.i18n_cancel,
4401 },
4402 },
4403 });
4404 }
4405 },
4406 );
4407 },
4408 bindFieldMultiSelect: function () {
4409 if (!$('#evf-multi-select-style').length) {
4410 $('head').append(
4411 '<style id="evf-multi-select-style">' +
4412 '.evf-field-selected{box-shadow:0 0 0 2px #7e3bd0!important;z-index:2;position:relative;border-radius:4px}' +
4413 '.evf-field-selected:hover{border:1px solid transparent!important;background:transparent!important}' +
4414 '.evf-field-selected::after{content:"\\2713";position:absolute;top:-8px;right:-8px;width:18px;height:18px;background:#7e3bd0;border-radius:50%;color:#fff;font-size:10px;font-weight:700;line-height:18px;text-align:center;pointer-events:none;z-index:10}' +
4415 '#evf-bulk-action-bar{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#fff;border:1px solid #edeff7;border-radius:8px;padding:8px 12px;display:none;align-items:center;gap:6px;z-index:999999;box-shadow:0 8px 24px rgba(0,0,0,.08);white-space:nowrap;font-size:12px;color:#383838}' +
4416 '#evf-bulk-action-bar .evf-bulk-count{color:#7e3bd0;font-weight:600;font-size:12px;padding-right:2px}' +
4417 '#evf-bulk-action-bar .evf-bulk-sep{width:1px;height:20px;background:#edeff7;flex-shrink:0}' +
4418 '#evf-bulk-action-bar button{background:#fbfbfd;border:1px solid #edeff7;color:#383838;cursor:pointer;display:flex;align-items:center;gap:4px;padding:5px 10px;border-radius:4px;font-size:12px;transition:border-color .12s,color .12s,background .12s;line-height:1}' +
4419 '#evf-bulk-action-bar button:hover{border-color:#8c64c6;color:#8c64c6;background:#fff}' +
4420 '#evf-bulk-action-bar .evf-bulk-delete:hover{border-color:#dc3545;color:#dc3545;background:#fff}' +
4421 '#evf-bulk-action-bar .evf-bulk-deselect{background:transparent;border-color:transparent;color:#999;padding:5px 6px}' +
4422 '#evf-bulk-action-bar .evf-bulk-deselect:hover{border-color:#edeff7;color:#383838;background:#fbfbfd}' +
4423 '#evf-bulk-action-bar button .dashicons{font-size:14px;width:14px;height:14px;line-height:14px}' +
4424 '</style>',
4425 );
4426 }
4427
4428 if (!$('#evf-bulk-action-bar').length) {
4429 $('body').append(
4430 '<div id="evf-bulk-action-bar" role="toolbar">' +
4431 '<span class="evf-bulk-count"></span>' +
4432 '<div class="evf-bulk-sep"></div>' +
4433 '<button class="evf-bulk-move-up"><span class="dashicons dashicons-arrow-up-alt2"></span>Move Up</button>' +
4434 '<button class="evf-bulk-move-down"><span class="dashicons dashicons-arrow-down-alt2"></span>Move Down</button>' +
4435 '<div class="evf-bulk-sep"></div>' +
4436 '<button class="evf-bulk-delete"><span class="dashicons dashicons-trash"></span>Delete</button>' +
4437 '<div class="evf-bulk-sep"></div>' +
4438 '<button class="evf-bulk-deselect" title="Clear selection"><span class="dashicons dashicons-no-alt"></span></button>' +
4439 '</div>',
4440 );
4441 }
4442
4443 $(document.body).on(
4444 'click',
4445 '.everest-forms-preview .everest-forms-field',
4446 function (e) {
4447 if (!e.shiftKey) return;
4448 e.preventDefault();
4449 e.stopPropagation();
4450 $(this).toggleClass('evf-field-selected');
4451 EVFPanelBuilder.updateBulkActionBar();
4452 },
4453 );
4454
4455 $(document.body).on(
4456 'click',
4457 '#evf-bulk-action-bar .evf-bulk-deselect',
4458 function () {
4459 $('.evf-field-selected').removeClass('evf-field-selected');
4460 EVFPanelBuilder.updateBulkActionBar();
4461 },
4462 );
4463
4464 $(document.body).on(
4465 'click',
4466 '#evf-bulk-action-bar .evf-bulk-move-up',
4467 function () {
4468 var moved = false;
4469 $('.everest-forms-preview .evf-field-selected').each(function () {
4470 var $prev = $(this)
4471 .prevAll('.everest-forms-field:not(.evf-field-selected)')
4472 .first();
4473 if ($prev.length) {
4474 $prev.before($(this));
4475 moved = true;
4476 }
4477 });
4478 if (moved) {
4479 $(document).trigger('evf_sort_update_complete', {
4480 event: null,
4481 ui: null,
4482 });
4483 } else {
4484 $.alert({
4485 title: false,
4486 content: 'The selected ' + ($('.everest-forms-preview .evf-field-selected').length > 1 ? 'fields are' : 'field is') + ' already at the top.',
4487 icon: 'dashicons dashicons-info',
4488 type: 'blue',
4489 buttons: {
4490 ok: { text: 'OK', btnClass: 'btn-confirm', keys: ['enter'] },
4491 },
4492 });
4493 }
4494 },
4495 );
4496
4497 $(document.body).on(
4498 'click',
4499 '#evf-bulk-action-bar .evf-bulk-move-down',
4500 function () {
4501 var moved = false;
4502 $(
4503 $('.everest-forms-preview .evf-field-selected').toArray().reverse(),
4504 ).each(function () {
4505 var $next = $(this)
4506 .nextAll('.everest-forms-field:not(.evf-field-selected)')
4507 .first();
4508 if ($next.length) {
4509 $next.after($(this));
4510 moved = true;
4511 }
4512 });
4513 if (moved) {
4514 $(document).trigger('evf_sort_update_complete', {
4515 event: null,
4516 ui: null,
4517 });
4518 } else {
4519 $.alert({
4520 title: false,
4521 content: 'The selected ' + ($('.everest-forms-preview .evf-field-selected').length > 1 ? 'fields are' : 'field is') + ' already at the bottom.',
4522 icon: 'dashicons dashicons-info',
4523 type: 'blue',
4524 buttons: {
4525 ok: { text: 'OK', btnClass: 'btn-confirm', keys: ['enter'] },
4526 },
4527 });
4528 }
4529 },
4530 );
4531
4532 $(document.body).on(
4533 'click',
4534 '#evf-bulk-action-bar .evf-bulk-delete',
4535 function () {
4536 var $selected = $('.everest-forms-preview .evf-field-selected'),
4537 count = $selected.length;
4538 $.confirm({
4539 title: false,
4540 content:
4541 'Delete ' +
4542 count +
4543 ' selected field' +
4544 (count > 1 ? 's' : '') +
4545 '?',
4546 type: 'red',
4547 closeIcon: false,
4548 backgroundDismiss: false,
4549 icon: 'dashicons dashicons-warning',
4550 buttons: {
4551 confirm: {
4552 text: 'Delete',
4553 btnClass: 'btn-danger',
4554 action: function () {
4555 var pending = $selected.length;
4556 $('.evf-panel-fields-button').trigger('click');
4557 $selected.each(function () {
4558 var $field = $(this),
4559 fieldId = $field.attr('data-field-id'),
4560 field_type = $field.attr('data-field-type');
4561 $field.fadeOut(200, function () {
4562 $(document.body).trigger('evf_before_field_deleted', [
4563 fieldId,
4564 ]);
4565 $field.remove();
4566 $('#everest-forms-field-option-' + fieldId).remove();
4567 EVFPanelBuilder.conditionalLogicRemoveField(fieldId);
4568 EVFPanelBuilder.conditionalLogicRemoveFieldIntegration(
4569 fieldId,
4570 );
4571 EVFPanelBuilder.paymentFieldRemoveFromQuantity(fieldId);
4572 EVFPanelBuilder.oneTimeDraggableRemoveField(field_type);
4573 pending--;
4574 if (0 === pending) {
4575 EVFPanelBuilder.checkEmptyGrid();
4576 $('.everest-forms-fields-tab')
4577 .find('a')
4578 .removeClass('active');
4579 $('.everest-forms-fields-tab')
4580 .find('a')
4581 .first()
4582 .addClass('active');
4583 $('.everest-forms-add-fields').show();
4584 $('#evf-bulk-action-bar').hide();
4585 }
4586 });
4587 });
4588 },
4589 },
4590 cancel: {
4591 text: evf_data.i18n_close,
4592 btnClass: 'btn-default',
4593 },
4594 },
4595 });
4596 },
4597 );
4598
4599 $(document).on('keydown.evf-multi-select', function (e) {
4600 if (27 === e.keyCode && $('.evf-field-selected').length) {
4601 $('.evf-field-selected').removeClass('evf-field-selected');
4602 EVFPanelBuilder.updateBulkActionBar();
4603 }
4604 });
4605 },
4606 updateBulkActionBar: function () {
4607 var $bar = $('#evf-bulk-action-bar'),
4608 count = $('.evf-field-selected').length;
4609 if (count > 0) {
4610 $bar
4611 .find('.evf-bulk-count')
4612 .text(count + ' field' + (count > 1 ? 's' : '') + ' selected');
4613 $bar.css('display', 'flex');
4614 } else {
4615 $bar.hide();
4616 }
4617 },
4618 bindFieldDeleteWithKeyEvent: function () {
4619 $('body').on('keyup', function (e) {
4620 var $field = $('.everest-forms-preview .everest-forms-field.active');
4621 if (
4622 46 === e.which &&
4623 true === $field.hasClass('active') &&
4624 false === $field.hasClass('evf-delete-event-active')
4625 ) {
4626 if (false == $('.evf-admin-row').hasClass('evf-hover')) {
4627 return;
4628 }
4629 $field.addClass('evf-delete-event-active');
4630 var field_id = $field.attr('data-field-id');
4631 var option_field = $('#everest-forms-field-option-' + field_id);
4632 if ($field.hasClass('no-delete')) {
4633 $.alert({
4634 title: evf_data.i18n_field_locked,
4635 content: evf_data.i18n_field_locked_msg,
4636 icon: 'dashicons dashicons-info',
4637 type: 'blue',
4638 buttons: {
4639 confirm: {
4640 text: evf_data.i18n_close,
4641 btnClass: 'btn-confirm',
4642 keys: ['enter'],
4643 action: function () {
4644 $field.removeClass('evf-delete-event-active');
4645 },
4646 },
4647 },
4648 });
4649 } else {
4650 $.confirm({
4651 title: false,
4652 content: evf_data.i18n_delete_field_confirm,
4653 type: 'red',
4654 closeIcon: false,
4655 backgroundDismiss: false,
4656 icon: 'dashicons dashicons-warning',
4657 buttons: {
4658 confirm: {
4659 text: evf_data.i18n_ok,
4660 btnClass: 'btn-confirm',
4661 keys: ['enter'],
4662 action: function () {
4663 $('.evf-panel-fields-button').trigger('click');
4664 $field.fadeOut('slow', function () {
4665 var removed_el_id = $field.attr('data-field-id');
4666 $(document.body).trigger('evf_before_field_deleted', [
4667 removed_el_id,
4668 ]);
4669 $field.remove();
4670 option_field.remove();
4671 EVFPanelBuilder.checkEmptyGrid();
4672 $('.everest-forms-fields-tab')
4673 .find('a')
4674 .removeClass('active');
4675 $('.everest-forms-fields-tab')
4676 .find('a')
4677 .first()
4678 .addClass('active');
4679 $('.everest-forms-add-fields').show();
4680 EVFPanelBuilder.conditionalLogicRemoveField(
4681 removed_el_id,
4682 );
4683 EVFPanelBuilder.conditionalLogicRemoveFieldIntegration(
4684 removed_el_id,
4685 );
4686 EVFPanelBuilder.paymentFieldRemoveFromQuantity(
4687 removed_el_id,
4688 );
4689 });
4690 $field.removeClass('evf-delete-event-active');
4691 },
4692 },
4693 cancel: {
4694 text: evf_data.i18n_cancel,
4695 action: function () {
4696 $field.removeClass('evf-delete-event-active');
4697 },
4698 },
4699 },
4700 });
4701 }
4702 }
4703 });
4704 },
4705 syncSubscriptionPlanChoiceFieldsBeforeSave: function () {
4706 $(
4707 '.everest-forms-field-option-payment-subscription-plan .evf-choices-list > li',
4708 ).each(function () {
4709 var $li = $(this);
4710 var $trialEnable = $li.find('.evf-enable-trial-period');
4711 var $expiryEnable = $li.find('.evf-enable-expiry-date');
4712 var trialOn = $trialEnable.length && $trialEnable.is(':checked');
4713 var expiryOn = $expiryEnable.length && $expiryEnable.is(':checked');
4714 var $expiryInput = $li.find('.evf-radio-subscription-expiry-input');
4715
4716 // Exclude stale trial length fields when trial is off (prevents false trial in gateways).
4717 $li.find('.evf-spt-panel--trial input, .evf-spt-panel--trial select').prop(
4718 'disabled',
4719 !trialOn,
4720 );
4721
4722 // Exclude stale expiry date when expiry is off (do not infer enable from date alone).
4723 $expiryInput.prop('disabled', !expiryOn);
4724
4725 if (!expiryOn) {
4726 EVFPanelBuilder.clear_subscription_plan_expiry_date($li);
4727 } else if ($expiryInput.length && $expiryInput[0]._flatpickr) {
4728 var fp = $expiryInput[0]._flatpickr;
4729 if (fp.selectedDates && fp.selectedDates[0]) {
4730 $expiryInput.val(
4731 fp.formatDate(
4732 fp.selectedDates[0],
4733 $expiryInput.data('date-format') || 'Y-m-d',
4734 ),
4735 );
4736 }
4737 }
4738
4739 if ($trialEnable.length) {
4740 $trialEnable.prop('checked', !!trialOn);
4741 }
4742 });
4743 },
4744 bindSaveOption: function () {
4745 $('body').on('click', '.everest-forms-save-button', function () {
4746 var $this = $(this);
4747 var $form = $('form#everest-forms-builder-form');
4748 var structure = EVFPanelBuilder.getStructure();
4749 EVFPanelBuilder.syncSubscriptionPlanChoiceFieldsBeforeSave();
4750 var form_data = $form.serializeArray();
4751
4752 // Re-enable trial/expiry inputs so the builder UI stays interactive after save.
4753 $(
4754 '.everest-forms-field-option-payment-subscription-plan .evf-spt-panel--trial input, .everest-forms-field-option-payment-subscription-plan .evf-spt-panel--trial select',
4755 ).prop('disabled', false);
4756 $(
4757 '.everest-forms-field-option-payment-subscription-plan .evf-radio-subscription-expiry-input',
4758 ).prop('disabled', false);
4759 var form_title = $('#evf-edit-form-name').val().trim();
4760
4761 // Save form args.
4762 $(document).trigger('everest_forms_save_args', [form_data]);
4763
4764 if ('' === form_title) {
4765 $.alert({
4766 title: evf_data.i18n_field_title_empty,
4767 content: evf_data.i18n_field_title_payload,
4768 icon: 'dashicons dashicons-warning',
4769 type: 'red',
4770 buttons: {
4771 ok: {
4772 text: evf_data.i18n_ok,
4773 btnClass: 'btn-confirm',
4774 keys: ['enter'],
4775 },
4776 },
4777 });
4778 return;
4779 }
4780
4781 // Trigger a handler to let addon manipulate the form data if needed.
4782 if (
4783 $form.triggerHandler('everest_forms_process_ajax_data', [
4784 $this,
4785 form_data,
4786 ])
4787 ) {
4788 form_data = $form.triggerHandler('everest_forms_process_ajax_data', [
4789 $this,
4790 form_data,
4791 ]);
4792 }
4793
4794 $('.everest-forms-panel-content-wrap').block({
4795 message: null,
4796 overlayCSS: {
4797 background: '#fff',
4798 opacity: 0.6,
4799 },
4800 });
4801
4802 /* DB unwanted data erase start */
4803 var rfields_ids = [];
4804 $('.everest-forms-field[data-field-id]').each(function () {
4805 rfields_ids.push($(this).attr('data-field-id'));
4806 });
4807
4808 var form_data_length = form_data.length;
4809 while (form_data_length--) {
4810 if (form_data[form_data_length].name.startsWith('form_fields')) {
4811 var idflag = false;
4812 rfields_ids.forEach(function (element) {
4813 if (
4814 form_data[form_data_length].name.startsWith(
4815 'form_fields[' + element + ']',
4816 )
4817 ) {
4818 idflag = true;
4819 }
4820 });
4821 if (form_data_length > -1 && idflag === false) {
4822 form_data.splice(form_data_length, 1);
4823 }
4824 }
4825 }
4826 /* DB fix end */
4827
4828 var new_form_data = form_data.concat(structure);
4829 var data = {
4830 action: 'everest_forms_save_form',
4831 security: evf_data.evf_save_form,
4832 form_data: JSON.stringify(new_form_data),
4833 };
4834 $.ajax({
4835 url: evf_data.ajax_url,
4836 data: data,
4837 type: 'POST',
4838 beforeSend: function () {
4839 $this.addClass('processing');
4840 $this.find('.loading-dot').remove();
4841 $this.append('<span class="loading-dot"></span>');
4842 },
4843 success: function (response) {
4844 $this.removeClass('processing');
4845 $this.find('.loading-dot').remove();
4846
4847 //Response data of ajax.
4848 $(document).trigger('everest_forms_save_data', response.data);
4849
4850 if (!response.success) {
4851 $.alert({
4852 title: response.data.errorTitle,
4853 content: response.data.errorMessage,
4854 icon: 'dashicons dashicons-warning',
4855 type: 'red',
4856 buttons: {
4857 ok: {
4858 text: evf_data.i18n_ok,
4859 btnClass: 'btn-confirm',
4860 keys: ['enter'],
4861 },
4862 },
4863 });
4864 } else {
4865 EVFPanelBuilder.captureStyleTabBaseline();
4866 $(document).trigger('everest_forms_form_saved');
4867 EVFPanelBuilder.toggleUnsavedStyleNotice();
4868 }
4869
4870 $('.everest-forms-panel-content-wrap').unblock();
4871 },
4872 });
4873 });
4874 },
4875 bindEmbedOption: function () {
4876 $('body').on('click', '.everest-forms-embed-button', function () {
4877 var data = {
4878 action: 'everest_forms_embed_form',
4879 security: evf_data.evf_embed_form,
4880 };
4881 var $this = $(this);
4882
4883 $.ajax({
4884 url: evf_data.ajax_url,
4885 data: data,
4886 type: 'POST',
4887 beforeSend: function () {
4888 $this.addClass('processing');
4889 $this.find('.loading-dot').remove();
4890 $this.append('<span class="loading-dot"></span>');
4891 },
4892 success: function (response) {
4893 $this.removeClass('processing');
4894 $this.find('.loading-dot').remove();
4895
4896 var $title = '<h4>Embed in Page</h4>';
4897
4898 var modelContent = '';
4899 var $message =
4900 '<div class="everest_forms_hide_container"><p>We can help embed your form with just a few clicks!</p>';
4901 var $selectExistingPage =
4902 '<button class="everest-forms-btn everest-forms-select-existing-page">Select Existing Page</button>';
4903 var $createNewPage =
4904 '<button class="everest-forms-btn everest-forms-create-new-page">Create New Page</button></div><div class="everest-forms-show-exist-page"></div>';
4905 modelContent = $message + $selectExistingPage + $createNewPage;
4906
4907 $.alert({
4908 title: $title,
4909 content: modelContent,
4910 type: 'blue',
4911 draggable:false,
4912 onContentReady: function () {
4913 var $formId = $('.everest-forms-embed-button').attr(
4914 'data-form_id',
4915 );
4916 $('.jconfirm-buttons').hide();
4917 //when clicked on 'Select Existing Page' button
4918 $('.everest-forms-select-existing-page').click(function () {
4919 $('.everest_forms_hide_container').hide();
4920 var $selectStart =
4921 '<div class="everest-forms-select-existing-post-container"><p>Select the page you would like to embed your form in.</p><select name="everest-forms-select-existing-page-name" id="everest-forms-select-existing-page-name">';
4922 var $option =
4923 '<option disabled selected>Select Page</option>';
4924
4925 response.data.forEach((page) => {
4926 $option +=
4927 '<option data-id="' +
4928 page.ID +
4929 '" value="' +
4930 page.ID +
4931 '">' +
4932 page.post_title +
4933 '</option>';
4934 });
4935
4936 var $selectEnd =
4937 '</select><button class="everest-forms-lets-go-btn" style="cursor:pointer">Lets Go!</button>';
4938 var $backBtn =
4939 '<div style="cursor:pointer" class="everest-forms-show-container">Go Back</div></div>';
4940
4941 modelContent = $selectStart + $option + $selectEnd + $backBtn;
4942
4943 $('.everest-forms-show-exist-page').append(modelContent);
4944
4945 $('.everest-forms-show-container').click(function () {
4946 $('.everest_forms_hide_container').show();
4947 $('.everest-forms-select-existing-post-container').remove();
4948 });
4949
4950 //When page is selected
4951 $('.everest-forms-select-existing-post-container').change(
4952 function () {
4953 var $pageId = $(this).find(':selected').val();
4954
4955 $('.everest-forms-lets-go-btn').click(function () {
4956 var data = {
4957 action: 'everest_forms_goto_edit_page',
4958 security: evf_data.evf_goto_edit_page,
4959 page_id: $pageId,
4960 form_id: $formId,
4961 };
4962 $.ajax({
4963 url: evf_data.ajax_url,
4964 type: 'POST',
4965 data: data,
4966 success: function (response) {
4967 if (response.success) {
4968 window.location = response.data;
4969 }
4970 },
4971 });
4972 });
4973 },
4974 );
4975 });
4976
4977 //when click on 'Create New Page' button
4978 $('.everest-forms-create-new-page').click(function () {
4979 $('.everest_forms_hide_container').hide();
4980
4981 var $title =
4982 '<div class="everest-forms-select-existing-post-container"><p>What would you like to call the new page?</p>';
4983 var $pageName = '<div><input type="text" name="page_title"/>';
4984 var $goBtn =
4985 '<button class="everest-forms-lets-go-btn" style="cursor:pointer">Lets Go!</button></div>';
4986 var $backBtn =
4987 '<div style="cursor:pointer" class="everest-forms-show-container">Go Back</div></div>';
4988
4989 modelContent = $title + $pageName + $goBtn + $backBtn;
4990 $(' .everest-forms-show-exist-page').append(modelContent);
4991
4992 $('.everest-forms-show-container').click(function () {
4993 $('.everest_forms_hide_container').show();
4994 $('.everest-forms-select-existing-post-container').remove();
4995 });
4996
4997 $('.everest-forms-lets-go-btn').click(function () {
4998 var $pageTitle = $("[name='page_title']").val();
4999
5000 var data = {
5001 action: 'everest_forms_goto_edit_page',
5002 security: evf_data.evf_goto_edit_page,
5003 page_title: $pageTitle,
5004 form_id: $formId,
5005 };
5006 $.ajax({
5007 url: evf_data.ajax_url,
5008 type: 'POST',
5009 data: data,
5010 success: function (response) {
5011 if (response.success) {
5012 window.location = response.data;
5013 }
5014 },
5015 });
5016 });
5017 });
5018 },
5019 });
5020 },
5021 });
5022 });
5023 },
5024 bindPreviewConfirmation: function () {
5025 $('.everest-preview-confirmation').each(function () {
5026 const $checkbox = $(this);
5027 const $target = $checkbox
5028 .closest('.everest-forms-panel-field-toggle')
5029 .next('.preview-confirm-select-wrapper');
5030
5031 if ($checkbox.is(':checked')) {
5032 $target.show();
5033 } else {
5034 $target.hide();
5035 }
5036
5037 $checkbox.on('change', function () {
5038 if ($(this).is(':checked')) {
5039 $target.show();
5040 } else {
5041 $target.hide();
5042 }
5043 });
5044 });
5045 },
5046 bindSaveOptionWithKeyEvent: function () {
5047 $('body').on('keydown', function (e) {
5048 if (e.ctrlKey || e.metaKey) {
5049 if (
5050 's' === String.fromCharCode(e.which).toLowerCase() ||
5051 83 === e.which
5052 ) {
5053 e.preventDefault();
5054 $('.everest-forms-save-button').trigger('click');
5055 }
5056 }
5057 });
5058 },
5059 bindOpenShortcutKeysModalWithKeyEvent: function () {
5060 $('body').on('keydown', function (e) {
5061 if (e.ctrlKey || e.metaKey) {
5062 if (
5063 'h' === String.fromCharCode(e.which).toLowerCase() ||
5064 72 === e.which
5065 ) {
5066 e.preventDefault();
5067 var shortcut_keys_html = '';
5068
5069 $.each(evf_data.i18n_shortcut_keys, function (key, value) {
5070 shortcut_keys_html += `
5071 <ul class="evf-shortcut-keyword">
5072 <li>
5073 <div class="evf-shortcut-title">${value}</div>
5074 <div class="evf-key">
5075 <span>${key.split('+')[0]}</span>
5076 <span>${key.split('+')[1]}</span>
5077 </div>
5078 </li>
5079 </ul>
5080 `;
5081 });
5082
5083 $.alert({
5084 title: evf_data.i18n_shortcut_key_title,
5085 content: shortcut_keys_html,
5086 icon: 'dashicons dashicons-info',
5087 type: 'blue',
5088 boxWidth: '550px',
5089 buttons: {
5090 confirm: {
5091 text: evf_data.i18n_close,
5092 btnClass: 'btn-confirm',
5093 keys: ['enter'],
5094 },
5095 },
5096 onContentReady: function () {
5097 $('body').on('keydown', function (e) {
5098 if (
5099 e.ctrlKey ||
5100 (e.metaKey &&
5101 'h' === String.fromCharCode(e.which).toLowerCase()) ||
5102 72 === e.which
5103 ) {
5104 $('.btn-confirm').trigger('click');
5105 }
5106 });
5107 },
5108 });
5109 }
5110 }
5111 });
5112 },
5113 getStructure: function () {
5114 var wrapper = $('.evf-admin-field-wrapper');
5115 var structure = [];
5116
5117 $.each(wrapper.find('.evf-admin-row'), function () {
5118 var $row = $(this),
5119 row_id = $row.attr('data-row-id');
5120
5121 $.each($row.find('.evf-admin-grid'), function () {
5122 var $grid = $(this),
5123 grid_id = $grid.attr('data-grid-id');
5124
5125 var array_index = 0;
5126 $.each($grid.find('.everest-forms-field'), function () {
5127 var structure_object = { name: '', value: '' };
5128 var field_id = $(this).attr('data-field-id');
5129 structure_object.name =
5130 'structure[row_' +
5131 row_id +
5132 '][grid_' +
5133 grid_id +
5134 '][' +
5135 array_index +
5136 ']';
5137 array_index++;
5138 structure_object.value = field_id;
5139 structure.push(structure_object);
5140 });
5141 if ($grid.find('.everest-forms-field').length < 1) {
5142 structure.push({
5143 name: 'structure[row_' + row_id + '][grid_' + grid_id + ']',
5144 value: '',
5145 });
5146 }
5147 });
5148 });
5149
5150 return structure;
5151 },
5152 getFieldArray: function (grid) {
5153 var fields = [];
5154 $.each(grid.find('.everest-forms-field'), function () {
5155 var field_id = $(this).attr('data-field-id');
5156 fields.push(field_id);
5157 });
5158 return fields;
5159 },
5160 checkEmptyGrid: function ($force) {
5161 $.each($('.evf-admin-grid'), function () {
5162 var $fields = $(this).find(
5163 '.everest-forms-field, .evf-registered-item:not(.ui-draggable-dragging)',
5164 );
5165 if ($fields.not('.ui-sortable-helper').length < 1) {
5166 $(this).addClass('evf-empty-grid');
5167 } else {
5168 $(this).removeClass('evf-empty-grid');
5169 }
5170 });
5171 EVFPanelBuilder.choicesInit();
5172 },
5173 captureStyleTabBaseline: function () {
5174 var $form = $('form#everest-forms-builder-form');
5175 if ($form.length) {
5176 evfStyleTabBaseline = $form.serialize();
5177 }
5178 },
5179 hasUnsavedFieldChanges: function () {
5180 var $form = $('form#everest-forms-builder-form');
5181 if (null === evfStyleTabBaseline || !$form.length) {
5182 return false;
5183 }
5184 return $form.serialize() !== evfStyleTabBaseline;
5185 },
5186 bindDefaultTabs: function () {
5187 $(document).on('click', '.evf-nav-tab-wrapper a', function (e) {
5188 e.preventDefault();
5189 EVFPanelBuilder.switchTab($(this).data('panel'));
5190 });
5191 },
5192 toggleUnsavedStyleNotice: function () {
5193 if ('function' === typeof window.evfScv2SetFormDirty) {
5194 window.evfScv2SetFormDirty(EVFPanelBuilder.hasUnsavedFieldChanges());
5195 }
5196 },
5197 switchTab: function (panel) {
5198 var $panel = $('#everest-forms-panel-' + panel),
5199 $panelBtn = $('.evf-panel-' + panel + '-button');
5200
5201 // Guard against silently losing unsaved Style Customizer changes when switching
5202 // away via this in-app tab click — the existing `beforeunload` handler only
5203 // catches a real page close/reload, not this SPA-style panel switch.
5204 var currentPanel = $('.evf-nav-tab-wrapper').find('a.nav-tab-active').data('panel');
5205 if (
5206 'style' === currentPanel &&
5207 panel !== currentPanel &&
5208 'function' === typeof window.evfScv2IsDirty &&
5209 window.evfScv2IsDirty()
5210 ) {
5211 if (!window.confirm(evf_data.i18n_unsaved_style_changes)) {
5212 return;
5213 }
5214 }
5215
5216 $('.evf-nav-tab-wrapper').find('a').removeClass('nav-tab-active');
5217 $panelBtn.addClass('nav-tab-active');
5218 $panel
5219 .closest('.evf-tab-content')
5220 .find('.everest-forms-panel')
5221 .removeClass('active');
5222 $panel.addClass('active');
5223
5224 if ('integrations' === panel) {
5225 var $firstConnected = $panel
5226 .find('.everest-forms-panel-sidebar a')
5227 .not('.evf-addon-install-trigger')
5228 .not('.upgrade-addons-settings')
5229 .first();
5230 if ($firstConnected.length) {
5231 $firstConnected.trigger('click');
5232 } else {
5233 $panel
5234 .find('.everest-forms-panel-sidebar a')
5235 .first()
5236 .addClass('active');
5237 }
5238 } else if ('payments' === panel) {
5239 if (!$panel.find('.everest-forms-panel-sidebar a').hasClass('active')) {
5240 $panel
5241 .find('.everest-forms-panel-sidebar a')
5242 .first()
5243 .addClass('active');
5244 }
5245
5246 if (
5247 !$('.everest-forms-panel-content')
5248 .find('.evf-panel-content-section')
5249 .hasClass('active')
5250 ) {
5251 $('.everest-forms-panel-content')
5252 .find('.evf-panel-content-section')
5253 .first()
5254 .addClass('active');
5255 }
5256 }
5257
5258 history.replaceState(
5259 {},
5260 null,
5261 EVFPanelBuilder.updateQueryString('tab', panel),
5262 );
5263 EVFPanelBuilder.switchPanel(panel);
5264 EVFPanelBuilder.toggleUnsavedStyleNotice();
5265 },
5266 updateQueryString: function (key, value, url) {
5267 if (!url) url = window.location.href;
5268 var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'),
5269 hash;
5270
5271 if (re.test(url)) {
5272 if (typeof value !== 'undefined' && value !== null)
5273 return url.replace(re, '$1' + key + '=' + value + '$2$3');
5274 else {
5275 hash = url.split('#');
5276 url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
5277 if (typeof hash[1] !== 'undefined' && hash[1] !== null)
5278 url += '#' + hash[1];
5279 return url;
5280 }
5281 } else {
5282 if (typeof value !== 'undefined' && value !== null) {
5283 var separator = url.indexOf('?') !== -1 ? '&' : '?';
5284 hash = url.split('#');
5285 url = hash[0] + separator + key + '=' + value;
5286 if (typeof hash[1] !== 'undefined' && hash[1] !== null)
5287 url += '#' + hash[1];
5288 return url;
5289 } else {
5290 return url;
5291 }
5292 }
5293 },
5294 switchPanel: function (panel) {
5295 if (panel === 'field-options') {
5296 EVFPanelBuilder.switchToFieldOptionPanel();
5297 }
5298 },
5299 switchToFieldOptionPanel: function (field_id) {
5300 $('.everest-forms-field-options').find('.no-fields').hide();
5301 $('.evf-admin-field-wrapper .everest-forms-field').removeClass('active');
5302 $('#everest-forms-panel-fields').addClass('active');
5303 $('.everest-forms-fields-tab').find('a').removeClass('active');
5304 $('.everest-forms-fields-tab').find('a').last().addClass('active');
5305 $('.everest-forms-add-fields').hide();
5306 $('.everest-forms-field-options').show();
5307 $('.everest-forms-field-options')
5308 .find('.everest-forms-field-option')
5309 .hide();
5310 $('.evf-tab-lists').find('li a').removeClass('active');
5311 $('.evf-tab-lists')
5312 .find('li.evf-panel-field-options-button a')
5313 .addClass('active');
5314
5315 $(document.body).trigger('evf-init-switch-field-options');
5316
5317 if (typeof field_id !== 'undefined') {
5318 var $fieldOptions = $('#everest-forms-field-option-' + field_id);
5319 if ($fieldOptions.length > 0) {
5320 var $basicGroup = $('#everest-forms-field-option-basic-' + field_id);
5321 $basicGroup
5322 .removeClass('closed')
5323 .addClass('open')
5324 .find('.everest-forms-field-option-group-inner')
5325 .show();
5326 const $tempLink = $('<a href="#field-options"></a>').appendTo(
5327 document.body,
5328 );
5329
5330 $tempLink[0].click();
5331
5332 setTimeout(() => {
5333 $tempLink.remove();
5334 }, 100);
5335 }
5336 $('#everest-forms-field-option-' + field_id).show();
5337
5338 /**
5339 * Close all field option groups except basic group
5340 * This is to ensure that only basic group is open when switching to field options.
5341 *
5342 * @since 3.2.4
5343 */
5344 $('#everest-forms-field-option-' + field_id)
5345 .find('.everest-forms-field-option-group')
5346 .each(function () {
5347 $field_options_element = $(this);
5348 if (
5349 !$field_options_element.hasClass(
5350 'everest-forms-field-option-group-basic',
5351 )
5352 ) {
5353 if ($field_options_element.hasClass('open')) {
5354 $field_options_element.removeClass('open').addClass('closed');
5355 $field_options_element
5356 .find('.everest-forms-field-option-group-inner')
5357 .hide();
5358 }
5359 }
5360 });
5361
5362 $('#everest-forms-field-' + field_id).addClass('active');
5363 } else {
5364 if ($('.evf-admin-field-wrapper .everest-forms-field').length > 0) {
5365 $('.evf-admin-field-wrapper .everest-forms-field')
5366 .eq(0)
5367 .addClass('active');
5368 $(
5369 '#everest-forms-field-option-' +
5370 $('.evf-admin-field-wrapper .everest-forms-field')
5371 .eq(0)
5372 .attr('data-field-id'),
5373 ).show();
5374 } else {
5375 $('.everest-forms-field-options').find('.no-fields').show();
5376 }
5377 }
5378 },
5379 bindFields: function () {
5380 $('.evf-admin-field-wrapper')
5381 .sortable({
5382 items: '.evf-admin-row',
5383 axis: 'y',
5384 cursor: 'move',
5385 opacity: 0.65,
5386 scrollSensitivity: 40,
5387 forcePlaceholderSize: true,
5388 placeholder: 'evf-sortable-placeholder',
5389 containment: '.everest-forms-panel-content',
5390 start: function (event, ui) {
5391 ui.item.css({
5392 backgroundColor: '#f7fafc',
5393 border: '1px dashed #5d96ee',
5394 });
5395 },
5396 stop: function (event, ui) {
5397 ui.item.removeAttr('style');
5398 },
5399 })
5400 .disableSelection();
5401
5402 $('.evf-admin-grid')
5403 .sortable({
5404 items: '> .everest-forms-field[data-field-type!="repeater-fields"]',
5405 delay: 100,
5406 opacity: 0.65,
5407 cursor: 'move',
5408 scrollSensitivity: 40,
5409 forcePlaceholderSize: true,
5410 connectWith: '.evf-admin-grid',
5411 appendTo: document.body,
5412 tolerance: 'pointer',
5413
5414 out: function (event) {
5415 $('.evf-admin-grid').removeClass('evf-hover');
5416 $(event.target).removeClass('evf-item-hover');
5417 $(event.target).closest('.evf-admin-row').removeClass('evf-hover');
5418 EVFPanelBuilder.checkEmptyGrid();
5419 },
5420 over: function (event, ui) {
5421 if (!ui.item.hasClass('required')) {
5422 ui.item.find('.required').remove();
5423 }
5424 $('.evf-admin-grid').addClass('evf-hover');
5425 $(event.target).addClass('evf-item-hover');
5426 $(event.target).closest('.evf-admin-row').addClass('evf-hover');
5427 EVFPanelBuilder.checkEmptyGrid();
5428 // Resize helper to fit the target column on entry
5429 if (ui.helper.data('origWidth') === undefined) {
5430 ui.helper.data('origWidth', ui.helper.width());
5431 }
5432 var newWidth = Math.min(ui.helper.data('origWidth'), $(this).width());
5433 ui.helper.css('width', newWidth + 'px');
5434 },
5435 sort: function (event, ui) {
5436 // sort() fires continuously on the SOURCE grid on every mousemove.
5437 // Use ui.placeholder to find the DESTINATION grid regardless of which
5438 // grid's sort handler is executing, then pin helper to that column.
5439 var dragInst = $.ui.ddmanager && $.ui.ddmanager.current;
5440 if (!dragInst || !dragInst.offset || !dragInst.offset.click) return;
5441 if (!ui.placeholder) return;
5442
5443 // Cache the destination grid and its offset to reduce DOM queries
5444 if (!dragInst._evf_destGrid || dragInst._evf_destGrid !== ui.placeholder[0].parentElement) {
5445 dragInst._evf_destGrid = ui.placeholder.closest('.evf-admin-grid')[0];
5446 if (!dragInst._evf_destGrid) return;
5447 dragInst._evf_destGridOffset = null; // Invalidate cached offset when grid changes
5448 }
5449
5450 var destGrid = dragInst._evf_destGrid;
5451 if (!dragInst._evf_destGridOffset) {
5452 dragInst._evf_destGridOffset = $(destGrid).offset().left;
5453 }
5454
5455 if (ui.helper.data('origWidth') === undefined) {
5456 ui.helper.data('origWidth', ui.helper.width());
5457 }
5458 dragInst.offset.click.left = Math.max(5, Math.min(event.pageX - dragInst._evf_destGridOffset, ui.helper.width() - 5));
5459 },
5460 receive: function (event, ui) {
5461 if (ui.sender.is('button')) {
5462 EVFPanelBuilder.fieldDrop(ui.helper);
5463 }
5464 },
5465 update: function (event, ui) {
5466 $(document).trigger('evf_sort_update_complete', {
5467 event: event,
5468 ui: ui,
5469 });
5470 },
5471 stop: function (event, ui) {
5472 if (!ui.item.hasClass('required')) {
5473 const labelTitle = ui.item.find('.label-title');
5474 if (labelTitle.length > 0) {
5475 labelTitle.append('<span class="required">*</span>');
5476 }
5477 }
5478 ui.item.removeAttr('style');
5479 EVFPanelBuilder.checkEmptyGrid();
5480 },
5481 })
5482 .disableSelection();
5483
5484 $(
5485 '.evf-registered-buttons button.evf-registered-item:not(.evf-layout-container-btn):not(.upgrade-modal):not(.evf-upgrade-addon):not(.enable-stripe-model):not(.enable-authorize-net-model):not(.enable-payment-subscription-plan):not(.everest-forms-pro-is_square_install):not(.enable-square-model):not(.evf-one-time-draggable-field):not(.recaptcha_empty_key_validate):not(.hcaptcha_empty_key_validate):not(.turnstile_empty_key_validate)',
5486 )
5487 .draggable({
5488 delay: 200,
5489 cancel: false,
5490 scroll: false,
5491 revert: 'invalid',
5492 scrollSensitivity: 40,
5493 forcePlaceholderSize: true,
5494 start: function () {
5495 $(this).addClass('field-dragged');
5496 },
5497 helper: function () {
5498 return $(this)
5499 .clone()
5500 .insertAfter(
5501 $(this)
5502 .closest('.everest-forms-tab-content')
5503 .siblings('.everest-forms-fields-tab'),
5504 );
5505 },
5506 stop: function () {
5507 $(this).removeClass('field-dragged');
5508 },
5509 opacity: 0.75,
5510 containment: '#everest-forms-builder',
5511 connectToSortable: '.evf-admin-grid',
5512 })
5513 .disableSelection();
5514
5515 // Layout presets (sidebar): draggable onto canvas only — always creates a new row (never a grid cell).
5516 $('.evf-layout-container-btn').each(function () {
5517 var $btn = $(this);
5518 if ($btn.data('ui-draggable')) {
5519 $btn.draggable('destroy');
5520 }
5521 var cursorLeft = Math.round($btn.outerWidth() / 2),
5522 cursorTop = Math.round($btn.outerHeight() / 2);
5523 $btn.draggable({
5524 delay: 0,
5525 distance: 2,
5526 cancel: false,
5527 scroll: false,
5528 revert: 'invalid',
5529 appendTo: 'body',
5530 zIndex: 100050,
5531 start: function (event, ui) {
5532 $(this).addClass('field-dragged');
5533 $('#everest-forms-builder').addClass(
5534 'evf-is-dragging-layout-container',
5535 );
5536 var cx = event.clientX - cursorLeft,
5537 cy = event.clientY - cursorTop;
5538 ui.helper.css({
5539 position: 'fixed',
5540 margin: 0,
5541 left: cx,
5542 top: cy,
5543 pointerEvents: 'none',
5544 boxSizing: 'border-box',
5545 });
5546 setTimeout(function () {
5547 ui.helper.css({ left: cx, top: cy });
5548 }, 0);
5549 },
5550 helper: function () {
5551 return $(this)
5552 .clone()
5553 .addClass('evf-layout-container-drag-helper')
5554 .css({
5555 width: $(this).outerWidth(),
5556 boxSizing: 'border-box',
5557 })
5558 .appendTo(document.body);
5559 },
5560 drag: function (event, ui) {
5561 ui.position.left = event.clientX - cursorLeft;
5562 ui.position.top = event.clientY - cursorTop;
5563 var $activeZone = $('#everest-forms-builder').data(
5564 'evf-layout-active-drop-zone',
5565 );
5566 if ($activeZone && $activeZone.length) {
5567 updateLayoutDropIndicator($activeZone, event.pageY);
5568 }
5569 },
5570 stop: function () {
5571 $(this).removeClass('field-dragged');
5572 $('#everest-forms-builder').removeClass(
5573 'evf-is-dragging-layout-container',
5574 );
5575 $('#everest-forms-builder').removeData(
5576 'evf-layout-active-drop-zone',
5577 );
5578 $('.evf-layout-drop-target-hover').removeClass(
5579 'evf-layout-drop-target-hover',
5580 );
5581 clearLayoutDropIndicators();
5582 },
5583 opacity: 0.92,
5584 });
5585 });
5586
5587 var layoutDropAccept = function (draggable) {
5588 return $(draggable).hasClass('evf-layout-container-btn');
5589 };
5590 var clearLayoutDropIndicators = function () {
5591 $('.evf-admin-row').removeClass(
5592 'evf-layout-insert-before evf-layout-insert-after',
5593 );
5594 $(
5595 '.evf-admin-field-wrapper, [id^="part_"], .evf-add-row:not(.repeater-row)',
5596 ).removeClass('evf-layout-insert-empty evf-layout-insert-after-all');
5597 };
5598 var updateLayoutDropIndicator = function ($zone, pageY) {
5599 var $rows = $zone.children('.evf-admin-row'),
5600 $beforeRow = null,
5601 $afterRow = null;
5602
5603 $rows.removeClass('evf-layout-insert-before evf-layout-insert-after');
5604 $zone.removeClass('evf-layout-insert-empty');
5605
5606 if (!$rows.length) {
5607 $zone.addClass('evf-layout-insert-empty');
5608 return;
5609 }
5610
5611 $rows.each(function () {
5612 var $r = $(this),
5613 top = $r.offset().top,
5614 mid = top + $r.outerHeight() / 2;
5615 if (pageY < mid) {
5616 $beforeRow = $r;
5617 return false;
5618 }
5619 $afterRow = $r;
5620 });
5621
5622 if ($beforeRow && $beforeRow.length) {
5623 $beforeRow.addClass('evf-layout-insert-before');
5624 } else if ($afterRow && $afterRow.length) {
5625 $afterRow.addClass('evf-layout-insert-after');
5626 }
5627 };
5628 var queueLayoutInsert = function (callback) {
5629 window.setTimeout(callback, 0);
5630 };
5631
5632 EVFPanelBuilder.getLayoutDropZones().each(function () {
5633 var $zone = $(this);
5634 if ($zone.data('ui-droppable')) {
5635 $zone.droppable('destroy');
5636 }
5637 $zone.droppable({
5638 accept: layoutDropAccept,
5639 tolerance: 'pointer',
5640 greedy: false,
5641 over: function (event) {
5642 var $zone = $(this);
5643 $zone.addClass('evf-layout-drop-target-hover');
5644 $('#everest-forms-builder').data(
5645 'evf-layout-active-drop-zone',
5646 $zone,
5647 );
5648 updateLayoutDropIndicator($zone, event.pageY);
5649 },
5650 out: function () {
5651 $(this).removeClass('evf-layout-drop-target-hover');
5652 $('#everest-forms-builder').removeData(
5653 'evf-layout-active-drop-zone',
5654 );
5655 clearLayoutDropIndicators();
5656 },
5657 drop: function (event, ui) {
5658 $(this).removeClass('evf-layout-drop-target-hover');
5659 $('#everest-forms-builder').removeData(
5660 'evf-layout-active-drop-zone',
5661 );
5662 clearLayoutDropIndicators();
5663 var columns = parseInt(ui.draggable.data('columns'), 10);
5664 if (!columns || columns < 1) {
5665 return;
5666 }
5667 var $z = $(this),
5668 y = event.pageY,
5669 $rows = $z.children('.evf-admin-row'),
5670 $beforeRow = null,
5671 $afterRow = null;
5672
5673 $rows.each(function () {
5674 var $r = $(this),
5675 top = $r.offset().top,
5676 mid = top + $r.outerHeight() / 2;
5677 if (y < mid) {
5678 $beforeRow = $r;
5679 return false;
5680 }
5681 $afterRow = $r;
5682 });
5683
5684 if ($beforeRow && $beforeRow.length) {
5685 queueLayoutInsert(function () {
5686 EVFPanelBuilder.addLayoutContainer(
5687 columns,
5688 null,
5689 $beforeRow,
5690 $z,
5691 );
5692 });
5693 } else if ($afterRow && $afterRow.length) {
5694 queueLayoutInsert(function () {
5695 EVFPanelBuilder.addLayoutContainer(
5696 columns,
5697 $afterRow,
5698 null,
5699 $z,
5700 );
5701 });
5702 } else {
5703 queueLayoutInsert(function () {
5704 EVFPanelBuilder.addLayoutContainer(
5705 columns,
5706 null,
5707 null,
5708 $z,
5709 );
5710 });
5711 }
5712 },
5713 });
5714 });
5715
5716 $('.evf-add-row:not(.repeater-row)').each(function () {
5717 var $addStrip = $(this);
5718 if ($addStrip.data('ui-droppable')) {
5719 $addStrip.droppable('destroy');
5720 }
5721 $addStrip.droppable({
5722 accept: layoutDropAccept,
5723 tolerance: 'pointer',
5724 over: function () {
5725 $(this).addClass('evf-layout-drop-target-hover');
5726 $(this).addClass('evf-layout-insert-after-all');
5727 },
5728 out: function () {
5729 $(this).removeClass('evf-layout-drop-target-hover');
5730 $(this).removeClass('evf-layout-insert-after-all');
5731 },
5732 drop: function (event, ui) {
5733 $(this).removeClass('evf-layout-drop-target-hover');
5734 $(this).removeClass('evf-layout-insert-after-all');
5735 clearLayoutDropIndicators();
5736 var columns = parseInt(ui.draggable.data('columns'), 10);
5737 if (!columns || columns < 1) {
5738 return;
5739 }
5740 var $ctx = $(this),
5741 wrapper = $('.evf-admin-field-wrapper'),
5742 current_part = $ctx
5743 .closest('.evf-admin-field-container')
5744 .attr('data-current-part');
5745
5746 if (current_part) {
5747 var $pw = wrapper.find('#part_' + current_part);
5748 if ($pw.length) {
5749 wrapper = $pw;
5750 }
5751 }
5752
5753 var $last = wrapper.children('.evf-admin-row').last();
5754 if ($last.length) {
5755 queueLayoutInsert(function () {
5756 EVFPanelBuilder.addLayoutContainer(
5757 columns,
5758 $last,
5759 null,
5760 $ctx,
5761 );
5762 });
5763 } else {
5764 queueLayoutInsert(function () {
5765 EVFPanelBuilder.addLayoutContainer(
5766 columns,
5767 null,
5768 null,
5769 $ctx,
5770 );
5771 });
5772 }
5773 },
5774 });
5775 });
5776
5777 // Repeatable grid connect to sortable setter.
5778 $('.evf-registered-item.evf-repeater-field').draggable(
5779 'option',
5780 'connectToSortable',
5781 '.evf-repeatable-grid',
5782 );
5783
5784 // Adapt hover behaviour on mouse event.
5785 $('.evf-admin-row').on('mouseenter mouseleave', function (event) {
5786 if (1 > event.buttons) {
5787 if ('mouseenter' === event.type) {
5788 $(this).addClass('evf-hover');
5789 } else {
5790 $('.evf-admin-row:not(.evf-popover-open)').removeClass('evf-hover');
5791 }
5792 }
5793 });
5794
5795 // Refresh the position of placeholders on drag scroll.
5796 $('.everest-forms-panel-content').on('scroll', function () {
5797 $('.evf-admin-grid').sortable('refreshPositions');
5798 $('.evf-admin-field-wrapper').sortable('refreshPositions');
5799 });
5800
5801 $('.evf-admin-field-wrapper .evf-admin-row').each(function () {
5802 if (!$(this).find('.evf-add-field-to-row').length) {
5803 $(this)
5804 .find('.evf-toggle-row')
5805 .prepend(
5806 '<div class="evf-add-field-to-row">' +
5807 '<span class="dashicons dashicons-plus" title="Add Field to Row"></span>' +
5808 '</div>',
5809 );
5810 }
5811 });
5812
5813 $('.evf-admin-field-wrapper .everest-forms-field').each(function () {
5814 if (!$(this).find('.evf-add-field-below').length) {
5815 $(this).append(
5816 '<div class="evf-add-field-below">' +
5817 '<span class="dashicons dashicons-plus" title="Add Field Below"></span>' +
5818 '</div>',
5819 );
5820 }
5821 });
5822 },
5823
5824 /**
5825 * Populate the row field popover with tabs and field items from the sidebar.
5826 */
5827 populateRowPopover: function () {
5828 var $tabs = $('#evf-row-field-popover .evf-popover-tabs').empty(),
5829 $fields = $('#evf-row-field-popover .evf-popover-fields').empty(),
5830 blocked = [
5831 'upgrade-modal',
5832 'evf-upgrade-addon',
5833 'enable-stripe-model',
5834 'enable-authorize-net-model',
5835 'enable-payment-subscription-plan',
5836 'everest-forms-pro-is_square_install',
5837 'enable-square-model',
5838 'evf-one-time-draggable-field',
5839 'recaptcha_empty_key_validate',
5840 'hcaptcha_empty_key_validate',
5841 'turnstile_empty_key_validate',
5842 ];
5843
5844 $tabs.append(
5845 '<button type="button" class="evf-popover-tab active" data-group="all">All</button>',
5846 );
5847
5848 $('.everest-forms-add-fields-group').each(function () {
5849 // Exclude the layout group from the field-picker popover entirely.
5850 if ($(this).hasClass('evf-layout-group')) {
5851 return;
5852 }
5853
5854 var $heading = $(this).find('.everest-forms-add-fields-heading'),
5855 groupKey = $heading.data('group'),
5856 groupLabel = $heading.clone().children().remove().end().text().trim();
5857
5858 if (groupKey) {
5859 $tabs.append(
5860 '<button type="button" class="evf-popover-tab" data-group="' +
5861 groupKey +
5862 '">' +
5863 groupLabel +
5864 '</button>',
5865 );
5866 }
5867
5868 $(this)
5869 .find('.evf-registered-item')
5870 .each(function () {
5871 var $btn = $(this),
5872 fieldType = $btn.data('field-type'),
5873 fieldLabel = $btn.text().trim(),
5874 iconHtml = $btn.find('i').length
5875 ? $btn.find('i').prop('outerHTML')
5876 : '',
5877 blockedClass = (function () {
5878 for (var i = 0; i < blocked.length; i++) {
5879 if ($btn.hasClass(blocked[i])) {
5880 return blocked[i];
5881 }
5882 }
5883 return '';
5884 }()),
5885 isBlocked = blockedClass !== '',
5886 isProLocked =
5887 $btn.hasClass('upgrade-modal') ||
5888 $btn.hasClass('evf-upgrade-addon');
5889
5890 // Skip items with no field type or no label — avoids blank popover entries.
5891 if (!fieldType || !fieldLabel) {
5892 return;
5893 }
5894
5895 $fields.append(
5896 $(
5897 '<div class="evf-popover-field-item' +
5898 (isBlocked ? ' evf-field-blocked' : '') +
5899 (isProLocked ? ' evf-field-upgrade' : '') +
5900 '"></div>',
5901 )
5902 .attr('data-field-type', fieldType)
5903 .attr('data-field-label', fieldLabel)
5904 .attr('data-field-group', groupKey || '')
5905 .attr('data-blocked-class', blockedClass || null)
5906 .append(
5907 '<span class="evf-popover-field-icon">' +
5908 iconHtml +
5909 '</span>',
5910 )
5911 .append(
5912 '<span class="evf-popover-field-label">' +
5913 fieldLabel +
5914 '</span>',
5915 ),
5916 );
5917 });
5918 });
5919 },
5920
5921 /**
5922 * Bind the row-level "+" button and its field-picker popover.
5923 */
5924 bindRowFieldPopover: function () {
5925 var proIconUrl = ( function () {
5926 var locked = document.querySelector(
5927 '.evf-registered-item.upgrade-modal',
5928 );
5929 if ( ! locked ) {
5930 return '';
5931 }
5932 return window
5933 .getComputedStyle( locked, '::before' )
5934 .backgroundImage.replace( /^url\(["']?/, '' )
5935 .replace( /["']?\)$/, '' );
5936 }() );
5937
5938 if (!$('#evf-row-popover-style').length) {
5939 $('head').append(
5940 '<style id="evf-row-popover-style">' +
5941 '.evf-add-field-to-row{cursor:pointer}' +
5942 '.evf-add-field-to-row span.dashicons{border-right:1px solid rgba(255,255,255,.2)}' +
5943 '.evf-add-field-to-row:hover span.dashicons{background:#0095ff!important;color:#fff!important}' +
5944 '.evf-admin-row.evf-popover-open .evf-toggle-row{opacity:1!important;visibility:visible!important}' +
5945 '.everest-forms-field.evf-field-popover-open .evf-field-action{opacity:1!important;visibility:visible!important}' +
5946 '.everest-forms-field{position:relative}' +
5947 '.evf-add-field-below{position:absolute;bottom:-15px;left:50%;transform:translateX(-50%);z-index:10;cursor:pointer;line-height:1;opacity:0;visibility:hidden;transition:opacity .15s,visibility .15s}' +
5948 '.everest-forms-field:hover>.evf-add-field-below,.everest-forms-field.evf-field-popover-open>.evf-add-field-below{opacity:1;visibility:visible}' +
5949 '.evf-add-field-below span.dashicons{background:#e9e9e9;color:#666;border-radius:50%;font-size:16px;width:28px;height:28px;display:flex;align-items:center;justify-content:center}' +
5950 '.evf-add-field-below:hover span.dashicons,.evf-add-field-below:focus span.dashicons{background:#7e3bd0;color:#fff}' +
5951 '.evf-row-field-popover{position:fixed;background:#fff;border:1px solid #edeff7;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.08);width:480px;z-index:999999;display:none;overflow:visible}' +
5952 '.evf-popover-arrow{position:absolute;bottom:100%;width:14px;height:8px;pointer-events:none;margin-bottom:-1px}' +
5953 '.evf-popover-arrow::before,.evf-popover-arrow::after{content:"";position:absolute;left:0;border-left:7px solid transparent;border-right:7px solid transparent}' +
5954 '.evf-popover-arrow::before{border-bottom:8px solid #edeff7;top:0}' +
5955 '.evf-popover-arrow::after{border-bottom:8px solid #fff;top:1px}' +
5956 '.evf-row-field-popover.evf-popover-flipped .evf-popover-arrow{bottom:auto;top:100%;margin-bottom:0;margin-top:-1px}' +
5957 '.evf-row-field-popover.evf-popover-flipped .evf-popover-arrow::before{border-bottom:none;border-top:8px solid #edeff7;top:auto;bottom:0}' +
5958 '.evf-row-field-popover.evf-popover-flipped .evf-popover-arrow::after{border-bottom:none;border-top:8px solid #fff;top:auto;bottom:1px}' +
5959 '.evf-popover-search-wrap{padding:10px 12px;border-bottom:1px solid #f0f0f1;display:flex;align-items:center;gap:6px}' +
5960 '.evf-popover-search-wrap .dashicons{color:#c3c3c3;flex-shrink:0;font-size:16px}' +
5961 '#evf-popover-search{border:1px solid #e1e1e1;border-radius:4px;padding:5px 8px;width:100%;font-size:12px;outline:none;box-shadow:none;color:#383838}' +
5962 '#evf-popover-search:focus{border-color:#7e3bd0;box-shadow:0 0 0 2px rgba(126,59,208,.1)}' +
5963 '.evf-popover-tabs-nav{position:relative;border-bottom:1px solid #f0f0f1}' +
5964 '.evf-popover-tabs{display:flex;flex-wrap:nowrap;gap:3px;padding:8px 12px;overflow-x:auto;scrollbar-width:none;scroll-behavior:smooth}' +
5965 '.evf-popover-tabs::-webkit-scrollbar{display:none}' +
5966 '.evf-tabs-arrow{position:absolute;top:0;bottom:0;width:32px;display:none;align-items:center;justify-content:center;border:none;padding:0;cursor:pointer;z-index:2}' +
5967 '.evf-tabs-arrow.evf-tabs-arrow-visible{display:flex}' +
5968 '.evf-tabs-arrow-left{left:0;background:linear-gradient(to right,#fff 55%,transparent)}' +
5969 '.evf-tabs-arrow-right{right:0;background:linear-gradient(to left,#fff 55%,transparent)}' +
5970 '.evf-tabs-arrow .dashicons{font-size:14px;color:#888;pointer-events:none}' +
5971 '.evf-tabs-arrow:hover .dashicons{color:#7e3bd0}' +
5972 '.evf-popover-tab{background:transparent;border:none;border-radius:20px;padding:3px 10px;font-size:12px;cursor:pointer;white-space:nowrap;color:#666;transition:background .12s,color .12s}' +
5973 '.evf-popover-tab:hover{background:#f5f5f7;color:#383838}' +
5974 '.evf-popover-tab.active{background:rgba(126,59,208,.1);color:#7e3bd0;font-weight:600}' +
5975 '.evf-popover-fields-wrap{max-height:320px;overflow-y:auto;padding:10px 12px}' +
5976 '.evf-popover-fields-wrap::-webkit-scrollbar{width:4px}' +
5977 '.evf-popover-fields-wrap::-webkit-scrollbar-track{background:transparent}' +
5978 '.evf-popover-fields-wrap::-webkit-scrollbar-thumb{background:#e1e1e1;border-radius:4px}' +
5979 '.evf-popover-fields{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}' +
5980 '.evf-popover-field-item{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:10px 6px 8px;border:1px solid #edeff7;border-radius:4px;cursor:pointer;font-size:11px;text-align:center;gap:4px;background:#fbfbfd;color:#383838;transition:border-color .12s,color .12s,background .12s;line-height:1.4}' +
5981 '.evf-popover-field-item:hover{border-color:#8c64c6;color:#8c64c6;background:#fff}' +
5982 '.evf-popover-field-item .evf-popover-field-icon i{font-size:18px}' +
5983 '.evf-popover-field-item .evf-popover-field-icon svg{width:24px;height:24px;display:block}' +
5984 '.evf-popover-field-item.evf-field-blocked{opacity:.45;cursor:default;pointer-events:none}' +
5985 '.evf-popover-field-item.evf-field-upgrade{opacity:.55;cursor:pointer;pointer-events:auto;position:relative}' +
5986 '.evf-popover-field-item.evf-field-upgrade:hover{opacity:1;border-color:#e6a817;background:#fffdf5}' +
5987 ( proIconUrl ? '.evf-popover-field-item.evf-field-upgrade::before{content:"";background-image:url("' + proIconUrl + '");background-repeat:no-repeat;background-position:center;background-size:100%;position:absolute;width:14px;height:14px;top:4px;right:4px}' : '' ) +
5988 '.evf-popover-no-results{grid-column:1/-1;text-align:center;padding:20px 0;color:#999;font-size:12px}' +
5989 '.evf-field-loading-wrap{display:flex;align-items:center;justify-content:center;gap:8px;padding:12px}' +
5990 '.evf-field-loading-wrap .spinner{float:none;margin:0}' +
5991 '.evf-field-loading-label{font-size:12px;color:#666}' +
5992 '.evf-admin-grid.evf-empty-grid,.evf-admin-grid.evf-empty-grid::before{cursor:pointer!important}' +
5993 '.evf-admin-grid.evf-empty-grid::before{width:36px!important;height:36px!important;border-radius:50%!important;background:#e9e9e9!important;color:#666!important;font-size:20px!important;display:flex!important;align-items:center!important;justify-content:center!important;line-height:1!important}' +
5994 '.evf-admin-grid.evf-empty-grid:hover::before{background:rgba(126,59,208,.12)!important;color:#7e3bd0!important}' +
5995 '.evf-admin-row.evf-popover-open .evf-admin-grid.evf-empty-grid::before{background:rgba(126,59,208,.12)!important;color:#7e3bd0!important}' +
5996 '.evf-admin-grid.evf-empty-grid.evf-item-hover::before{display:none!important}' +
5997 '</style>',
5998 );
5999 }
6000
6001 if (!$('#evf-row-field-popover').length) {
6002 $('body').append(
6003 '<div id="evf-row-field-popover" class="evf-row-field-popover">' +
6004 '<div class="evf-popover-arrow"></div>' +
6005 '<div class="evf-popover-search-wrap">' +
6006 '<span class="dashicons dashicons-search"></span>' +
6007 '<input type="text" id="evf-popover-search" placeholder="Search for a field" autocomplete="off" />' +
6008 '</div>' +
6009 '<div class="evf-popover-tabs-nav">' +
6010 '<button type="button" class="evf-tabs-arrow evf-tabs-arrow-left" aria-label="Scroll left"><span class="dashicons dashicons-arrow-left-alt2"></span></button>' +
6011 '<div class="evf-popover-tabs"></div>' +
6012 '<button type="button" class="evf-tabs-arrow evf-tabs-arrow-right" aria-label="Scroll right"><span class="dashicons dashicons-arrow-right-alt2"></span></button>' +
6013 '</div>' +
6014 '<div class="evf-popover-fields-wrap"><div class="evf-popover-fields"></div></div>' +
6015 '</div>',
6016 );
6017 }
6018
6019 EVFPanelBuilder.populateRowPopover();
6020
6021 var positionPopover = function ($anchor, $pop, forceFlipped) {
6022 var offset = $anchor.offset(),
6023 scrollLeft = $(window).scrollLeft(),
6024 scrollTop = $(window).scrollTop(),
6025 vpW = window.innerWidth,
6026 vpH = window.innerHeight,
6027 popW = $pop.outerWidth(),
6028 $fieldsWrap = $pop.find('.evf-popover-fields-wrap'),
6029 defaultFieldsMaxHeight = 320,
6030 popH,
6031 margin = 8,
6032 anchorCX = offset.left - scrollLeft + $anchor.outerWidth() / 2,
6033 anchorTop = offset.top - scrollTop,
6034 belowTop = anchorTop + $anchor.outerHeight() + 6,
6035 aboveTop,
6036 top,
6037 left = anchorCX - popW / 2,
6038 flipped = false;
6039
6040 $fieldsWrap.css('max-height', defaultFieldsMaxHeight + 'px');
6041 popH = $pop.outerHeight();
6042 var maxPopoverHeight = vpH - margin * 2;
6043 if (popH > maxPopoverHeight) {
6044 var staticHeight = popH - $fieldsWrap.outerHeight();
6045 $fieldsWrap.css(
6046 'max-height',
6047 Math.max(140, maxPopoverHeight - staticHeight) + 'px',
6048 );
6049 popH = $pop.outerHeight();
6050 }
6051
6052 aboveTop = anchorTop - popH - 6;
6053 left = Math.min(Math.max(margin, left), vpW - popW - margin);
6054 var fitsBelow = belowTop + popH <= vpH - margin,
6055 fitsAbove = aboveTop >= margin;
6056 if (forceFlipped !== undefined) {
6057 flipped = forceFlipped;
6058 if (flipped && !fitsAbove && fitsBelow) {
6059 flipped = false;
6060 } else if (!flipped && !fitsBelow && fitsAbove) {
6061 flipped = true;
6062 }
6063 } else if (fitsBelow) {
6064 flipped = false;
6065 } else if (fitsAbove) {
6066 flipped = true;
6067 } else {
6068 var spaceBelow = vpH - margin - belowTop,
6069 spaceAbove = anchorTop - margin - 6;
6070 flipped = spaceAbove > spaceBelow;
6071 }
6072
6073 top = flipped ? aboveTop : belowTop;
6074 top = Math.max(margin, Math.min(top, vpH - popH - margin));
6075
6076 var arrowX = anchorCX - left - 7;
6077 arrowX = Math.min(Math.max(14, arrowX), popW - 28);
6078 $pop
6079 .toggleClass('evf-popover-flipped', flipped)
6080 .find('.evf-popover-arrow')
6081 .css('left', arrowX + 'px');
6082
6083 return { top: top, left: left };
6084 };
6085
6086 var updateTabArrows = function () {
6087 var tabs = document.querySelector(
6088 '#evf-row-field-popover .evf-popover-tabs',
6089 );
6090 if (!tabs) return;
6091 $('.evf-tabs-arrow-left').toggleClass(
6092 'evf-tabs-arrow-visible',
6093 tabs.scrollLeft > 1,
6094 );
6095 $('.evf-tabs-arrow-right').toggleClass(
6096 'evf-tabs-arrow-visible',
6097 Math.ceil(tabs.scrollLeft + tabs.clientWidth) < tabs.scrollWidth,
6098 );
6099 };
6100
6101 $(document.body).on(
6102 'click',
6103 '#evf-row-field-popover .evf-tabs-arrow',
6104 function (e) {
6105 e.stopPropagation();
6106 var tabs = document.querySelector(
6107 '#evf-row-field-popover .evf-popover-tabs',
6108 );
6109 if (!tabs) return;
6110 var step = 120;
6111 tabs.scrollLeft += $(this).hasClass('evf-tabs-arrow-left')
6112 ? -step
6113 : step;
6114 setTimeout(updateTabArrows, 200);
6115 },
6116 );
6117
6118 $(document.body).on(
6119 'scroll',
6120 '#evf-row-field-popover .evf-popover-tabs',
6121 updateTabArrows,
6122 );
6123
6124 $(document.body).on('click', '.evf-add-field-to-row', function (e) {
6125 e.stopPropagation();
6126 var $btn = $(this),
6127 $row = $btn.closest('.evf-admin-row'),
6128 $popover = $('#evf-row-field-popover');
6129
6130 if ($popover.is(':visible') && $row.hasClass('evf-popover-open')) {
6131 $popover.hide();
6132 $row.removeClass('evf-popover-open');
6133 $('.everest-forms-field.evf-field-popover-open').removeClass(
6134 'evf-field-popover-open',
6135 );
6136 return;
6137 }
6138
6139 EVFPanelBuilder.populateRowPopover();
6140
6141 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6142 $('.everest-forms-field.evf-field-popover-open').removeClass(
6143 'evf-field-popover-open',
6144 );
6145
6146 $row.addClass('evf-popover-open');
6147
6148 var pos = positionPopover($btn, $popover);
6149 $popover
6150 .data('target-row', $row)
6151 .data('insert-after-field', null)
6152 .data('anchor', $btn)
6153 .css(pos)
6154 .show();
6155
6156 updateTabArrows();
6157 $('#evf-popover-search').val('').trigger('input').focus();
6158 });
6159
6160 $(document.body).on('click', '.evf-add-field-below', function (e) {
6161 e.stopPropagation();
6162 var $btn = $(this),
6163 $field = $btn.closest('.everest-forms-field'),
6164 $row = $field.closest('.evf-admin-row'),
6165 $popover = $('#evf-row-field-popover');
6166
6167 var $prevField = $popover.data('insert-after-field');
6168 if (
6169 $popover.is(':visible') &&
6170 $row.hasClass('evf-popover-open') &&
6171 $prevField &&
6172 $prevField[0] === $field[0]
6173 ) {
6174 $popover.hide();
6175 $row.removeClass('evf-popover-open');
6176 $field.removeClass('evf-field-popover-open');
6177 return;
6178 }
6179
6180 EVFPanelBuilder.populateRowPopover();
6181
6182 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6183 $('.everest-forms-field.evf-field-popover-open').removeClass(
6184 'evf-field-popover-open',
6185 );
6186
6187 $row.addClass('evf-popover-open');
6188 $field.addClass('evf-field-popover-open');
6189
6190 var pos = positionPopover($btn, $popover);
6191 $popover
6192 .data('target-row', $row)
6193 .data('insert-after-field', $field)
6194 .data('anchor', $btn)
6195 .css(pos)
6196 .show();
6197
6198 updateTabArrows();
6199 $('#evf-popover-search').val('').trigger('input').focus();
6200 });
6201
6202 $(document.body).on(
6203 'click',
6204 '.evf-admin-grid.evf-empty-grid',
6205 function (e) {
6206 e.stopPropagation();
6207 var $grid = $(this),
6208 $row = $grid.closest('.evf-admin-row'),
6209 $popover = $('#evf-row-field-popover');
6210
6211 var $prevGrid = $popover.data('insert-into-grid');
6212 if (
6213 $popover.is(':visible') &&
6214 $row.hasClass('evf-popover-open') &&
6215 $prevGrid &&
6216 $prevGrid[0] === $grid[0]
6217 ) {
6218 $popover.hide().removeData('insert-into-grid');
6219 $row.removeClass('evf-popover-open');
6220 return;
6221 }
6222
6223 EVFPanelBuilder.populateRowPopover();
6224
6225 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6226 $('.everest-forms-field.evf-field-popover-open').removeClass(
6227 'evf-field-popover-open',
6228 );
6229
6230 $row.addClass('evf-popover-open');
6231
6232 var pos = positionPopover($grid, $popover);
6233 $popover
6234 .data('target-row', $row)
6235 .data('insert-after-field', null)
6236 .data('insert-into-grid', $grid)
6237 .data('anchor', $grid)
6238 .css(pos)
6239 .show();
6240
6241 updateTabArrows();
6242 $('#evf-popover-search').val('').trigger('input').focus();
6243 },
6244 );
6245
6246 $(document).on('click.evf-row-popover', function (e) {
6247 if (
6248 !$(e.target).closest(
6249 '#evf-row-field-popover, .evf-add-field-to-row, .evf-add-field-below, .evf-admin-grid.evf-empty-grid',
6250 ).length
6251 ) {
6252 $('#evf-row-field-popover').hide().removeData('insert-into-grid');
6253 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6254 $('.everest-forms-field.evf-field-popover-open').removeClass(
6255 'evf-field-popover-open',
6256 );
6257 }
6258 });
6259
6260 $(document.body).on('evf_after_field_append', function (e, fieldId) {
6261 var $field = $('#' + fieldId);
6262 if ($field.length && !$field.find('.evf-add-field-below').length) {
6263 $field.append(
6264 '<div class="evf-add-field-below">' +
6265 '<span class="dashicons dashicons-plus" title="Add Field Below"></span>' +
6266 '</div>',
6267 );
6268 }
6269 });
6270
6271 $(document.body).on('input', '#evf-popover-search', function () {
6272 var term = $(this).val().toLowerCase().trim();
6273 $('#evf-row-field-popover .evf-popover-field-item').each(function () {
6274 $(this).toggle(
6275 !term ||
6276 $(this).data('field-label').toLowerCase().indexOf(term) >= 0,
6277 );
6278 });
6279 $('.evf-popover-tab').removeClass('active');
6280 $('.evf-popover-tab[data-group="all"]').addClass('active');
6281 $('.evf-popover-no-results').remove();
6282 if (
6283 !$('#evf-row-field-popover .evf-popover-field-item:visible').length
6284 ) {
6285 $('#evf-row-field-popover .evf-popover-fields').append(
6286 '<div class="evf-popover-no-results">No fields found.</div>',
6287 );
6288 }
6289 });
6290
6291 $(document.body).on(
6292 'click',
6293 '#evf-row-field-popover .evf-popover-tab',
6294 function () {
6295 var group = $(this).data('group');
6296 $('.evf-popover-tab').removeClass('active');
6297 $(this).addClass('active');
6298 $('#evf-popover-search').val('');
6299 $('#evf-row-field-popover .evf-popover-field-item').each(function () {
6300 $(this).toggle(
6301 'all' === group || $(this).data('field-group') === group,
6302 );
6303 });
6304 $('.evf-popover-no-results').remove();
6305 var $pop = $('#evf-row-field-popover'),
6306 $storedAnchor = $pop.data('anchor');
6307 if ($storedAnchor && $storedAnchor.length) {
6308 $pop.css(
6309 positionPopover(
6310 $storedAnchor,
6311 $pop,
6312 $pop.hasClass('evf-popover-flipped'),
6313 ),
6314 );
6315 }
6316 this.scrollIntoView({
6317 behavior: 'smooth',
6318 block: 'nearest',
6319 inline: 'nearest',
6320 });
6321 setTimeout(updateTabArrows, 200);
6322 },
6323 );
6324
6325 $(document.body).on(
6326 'click',
6327 '#evf-row-field-popover .evf-popover-field-item:not(.evf-field-blocked)',
6328 function () {
6329 var $item = $(this),
6330 fieldType = $item.data('field-type'),
6331 fieldLabel = $item.data('field-label'),
6332 $popover = $('#evf-row-field-popover'),
6333 $insertAfterField = $popover.data('insert-after-field'),
6334 $insertIntoGrid = $popover.data('insert-into-grid'),
6335 $placeholder = $('<button class="evf-registered-item" />')
6336 .attr('data-field-type', fieldType)
6337 .attr('data-field-label', fieldLabel);
6338
6339 if ($insertAfterField && $insertAfterField.length) {
6340 $insertAfterField.after($placeholder);
6341 } else if ($insertIntoGrid && $insertIntoGrid.length) {
6342 $insertIntoGrid.append($placeholder);
6343 } else {
6344 $popover
6345 .data('target-row')
6346 .find('.evf-admin-grid')
6347 .last()
6348 .append($placeholder);
6349 }
6350
6351 EVFPanelBuilder.fieldDrop($placeholder);
6352 $popover.hide().removeData('insert-into-grid');
6353 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6354 $('.everest-forms-field.evf-field-popover-open').removeClass(
6355 'evf-field-popover-open',
6356 );
6357 },
6358 );
6359
6360 // Handle layout container items clicked inside the popover.
6361 $(document.body).on(
6362 'click',
6363 '#evf-row-field-popover .evf-layout-container-item',
6364 function () {
6365 var columns = parseInt($(this).data('columns'), 10),
6366 $popover = $('#evf-row-field-popover'),
6367 $targetRow = $popover.data('target-row');
6368
6369 $popover.hide().removeData('insert-into-grid');
6370 $('.evf-admin-row.evf-popover-open').removeClass('evf-popover-open');
6371 $('.everest-forms-field.evf-field-popover-open').removeClass(
6372 'evf-field-popover-open',
6373 );
6374
6375 EVFPanelBuilder.addLayoutContainer(
6376 columns,
6377 $targetRow,
6378 null,
6379 $targetRow,
6380 );
6381 },
6382 );
6383 },
6384
6385 /**
6386 * Toggle fields tabs (Add Fields, Field Options).
6387 */
6388 fieldTabChoice: function (id) {
6389 $('.everest-forms-tab-content').scrollTop(0);
6390 $('.everest-forms-fields-tab a').removeClass('active');
6391 $('.everest-forms-field, .everest-forms-title-desc').removeClass(
6392 'active',
6393 );
6394
6395 $('#' + id).addClass('active');
6396
6397 if ('add-fields' === id) {
6398 $('.everest-forms-add-fields').show();
6399 $('.everest-forms-field-options').hide();
6400 } else {
6401 if ('field-options' === id) {
6402 id = $('.everest-forms-field').first().data('field-id');
6403 $('.everest-forms-field-options').show();
6404 $('.everest-forms-field').first().addClass('active');
6405 } else {
6406 $('#everest-forms-field-' + id).addClass('active');
6407 }
6408 $('.everest-forms-field-option').hide();
6409 $('#everest-forms-field-option-' + id).show();
6410 $('.everest-forms-add-fields').hide();
6411 }
6412 },
6413 bindFormPreview: function () {},
6414 bindFormPreviewWithKeyEvent: function () {
6415 $('body').on('keydown', function (e) {
6416 if (e.ctrlKey || e.metaKey) {
6417 if (
6418 'p' === String.fromCharCode(e.which).toLowerCase() ||
6419 80 === e.which
6420 ) {
6421 e.preventDefault();
6422 window.open(evf_data.preview_url);
6423 }
6424 }
6425 });
6426 },
6427 bindFormEntriesWithKeyEvent: function () {
6428 $('body').on('keydown', function (e) {
6429 if (e.ctrlKey || e.metaKey) {
6430 if (
6431 'e' === String.fromCharCode(e.which).toLowerCase() ||
6432 69 === e.which
6433 ) {
6434 e.preventDefault();
6435 window.open(evf_data.entries_url);
6436 }
6437 }
6438 });
6439 },
6440 bindGridSwitcher: function () {
6441 $('body').on('click', '.evf-show-grid', function (e) {
6442 e.stopPropagation();
6443 EVFPanelBuilder.checkEmptyGrid();
6444 $(this)
6445 .closest('.evf-toggle-row')
6446 .find('.evf-toggle-row-content')
6447 .stop(true)
6448 .slideToggle(200);
6449 });
6450 $(document).on('click', function () {
6451 EVFPanelBuilder.checkEmptyGrid();
6452 $('.evf-show-grid')
6453 .closest('.evf-toggle-row')
6454 .find('.evf-toggle-row-content')
6455 .stop(true)
6456 .slideUp(200);
6457 });
6458 var max_number_of_grid = 4;
6459 $('body').on('click', '.evf-grid-selector', function () {
6460 var $this_single_row = $(this).closest('.evf-admin-row');
6461 if ($(this).hasClass('active')) {
6462 return;
6463 }
6464 var grid_id = parseInt($(this).attr('data-evf-grid'), 10);
6465 if (grid_id > max_number_of_grid) {
6466 return;
6467 }
6468
6469 var grid_node = $(
6470 '<div class="evf-admin-grid evf-grid-' +
6471 grid_id +
6472 ' ui-sortable evf-empty-grid" />',
6473 );
6474 var grids = $('<div/>');
6475
6476 $.each($this_single_row.find('.evf-admin-grid'), function () {
6477 $(this)
6478 .children('*')
6479 .each(function () {
6480 grids.append($(this).clone());
6481 });
6482 });
6483
6484 var $gridLists = $('<div class="evf-grid-lists"></div>');
6485
6486 for (var $grid_number = 1; $grid_number <= grid_id; $grid_number++) {
6487 grid_node.attr('data-grid-id', $grid_number);
6488 $gridLists.append(grid_node.clone());
6489 }
6490 $gridLists.append('<div class="clear evf-clear"></div>');
6491
6492 $this_single_row.find('.evf-grid-lists').remove();
6493 $this_single_row.find('.evf-admin-grid').remove();
6494 $this_single_row.find('.evf-clear').remove();
6495
6496 $this_single_row.append('<div class="clear evf-clear"></div>');
6497 $this_single_row.append($gridLists);
6498
6499 $this_single_row.find('.evf-admin-grid').eq(0).append(grids.html());
6500
6501 $this_single_row.find('.evf-grid-selector').removeClass('active');
6502 $(this).addClass('active');
6503 EVFPanelBuilder.bindFields();
6504 });
6505 },
6506 fieldDrop: function (field) {
6507 var field_type = field.attr('data-field-type');
6508
6509 // One-time-draggable fields (e.g. File Upload in the free version) are limited to a
6510 // single instance per form. Reject any extra drop of the same field type, including
6511 // rapid re-drops fired before the first field finishes loading (AJAX still in flight).
6512 var oneTimeDraggableFields = evf_data.form_one_time_draggable_fields || [];
6513 var isOneTimeDraggableField =
6514 $.inArray(field_type, oneTimeDraggableFields) >= 0;
6515 if (isOneTimeDraggableField) {
6516 if (
6517 $('#everest-forms-add-fields-' + field_type).hasClass(
6518 'evf-one-time-draggable-field',
6519 )
6520 ) {
6521 field.remove();
6522 EVFPanelBuilder.checkEmptyGrid();
6523 return false;
6524 }
6525 // Lock the sidebar field immediately so concurrent drops during the
6526 // loading state are blocked by the check above. The draggable itself is
6527 // torn down later in the AJAX success handler (oneTimeDraggableField),
6528 // once the drop event has fully settled.
6529 $('#everest-forms-add-fields-' + field_type).addClass(
6530 'evf-one-time-draggable-field',
6531 );
6532 }
6533
6534 var invalid_fields = ['payment-total'];
6535 if (
6536 invalid_fields.includes(field_type) &&
6537 field.closest('.evf-admin-row').hasClass('evf-repeater-fields')
6538 ) {
6539 $.confirm({
6540 title: false,
6541 content: 'This field cannot be added to Repeater Fields',
6542 type: 'red',
6543 closeIcon: false,
6544 backgroundDismiss: false,
6545 icon: 'dashicons dashicons-warning',
6546 buttons: {
6547 cancel: {
6548 text: evf_data.i18n_close,
6549 btnClass: 'btn-default',
6550 },
6551 },
6552 });
6553
6554 field.remove();
6555 return false;
6556 }
6557
6558 if (!$.contains(document.body, field[0])) {
6559 $('.evf-admin-grid').last().append(field);
6560 }
6561
6562 var fieldLoadingLabel = field.attr('data-field-label');
6563 field
6564 .css({
6565 left: '0',
6566 width: '100%',
6567 })
6568 .append(
6569 '<span class="evf-field-loading-wrap">' +
6570 '<i class="spinner is-active"></i>' +
6571 (fieldLoadingLabel
6572 ? '<span class="evf-field-loading-label">' +
6573 fieldLoadingLabel +
6574 '</span>'
6575 : '') +
6576 '</span>',
6577 );
6578
6579 $.ajax({
6580 url: evf_data.ajax_url,
6581 type: 'POST',
6582 data: {
6583 action: 'everest_forms_new_field_' + field_type,
6584 security: evf_data.evf_field_drop_nonce,
6585 field_type: field_type,
6586 form_id: evf_data.form_id,
6587 },
6588 beforeSend: function () {
6589 $(document.body).trigger('init_field_options_toggle');
6590 },
6591 error: function () {
6592 // Adding the field failed; remove the loading placeholder and unlock the
6593 // sidebar field so a one-time-draggable field can be dragged again.
6594 field.remove();
6595 if (isOneTimeDraggableField) {
6596 EVFPanelBuilder.oneTimeDraggableRemoveField(field_type);
6597 }
6598 EVFPanelBuilder.checkEmptyGrid();
6599 },
6600 success: function (response) {
6601 var field_preview = response.data.preview,
6602 field_options = response.data.options,
6603 form_field_id = response.data.form_field_id,
6604 field_type = response.data.field.type,
6605 dragged_el_id = $(field_preview).attr('id'),
6606 dragged_field_id = $(field_preview).attr('data-field-id');
6607
6608 $('#everest-forms-field-id').val(form_field_id);
6609 $('.everest-forms-field-options').find('.no-fields').hide();
6610 $('.everest-forms-field-options').append(field_options);
6611 $(
6612 '.everest-forms-field-option-row-icon_color input.colorpicker',
6613 ).wpColorPicker({
6614 change: function (event) {
6615 var $this = $(this),
6616 value = $this.val(),
6617 field_id = $this
6618 .closest('.everest-forms-field-option-row')
6619 .data('field-id');
6620
6621 $('#everest-forms-field-' + field_id + ' .rating-icon svg').css(
6622 'fill',
6623 value,
6624 );
6625 },
6626 });
6627
6628 if ( field_type === 'repeater-fields' ) {
6629 field.remove();
6630 $(document.body).trigger('init_tooltips');
6631 $(document.body).trigger('init_field_options_toggle');
6632 $(document.body).trigger('evf_after_field_append', [dragged_el_id]);
6633 EVFPanelBuilder.conditionalLogicAppendField(dragged_el_id);
6634 EVFPanelBuilder.conditionalLogicAppendFieldIntegration(dragged_el_id);
6635 EVFPanelBuilder.paymentFieldAppendToQuantity(dragged_el_id);
6636 EVFPanelBuilder.paymentFieldAppendToDropdown(dragged_field_id, field_type);
6637 EVFPanelBuilder.oneTimeDraggableField(dragged_field_id, field_type);
6638 EVFPanelBuilder.init_datepickers();
6639 EVFPanelBuilder.init_payment_subscription_plan_field();
6640 $(
6641 '#everest-forms-field-option-' +
6642 dragged_field_id +
6643 '-enable_min_max_time',
6644 ).hide();
6645 $(
6646 'label[for=everest-forms-field-option-' +
6647 dragged_field_id +
6648 '-enable_min_max_time]',
6649 ).hide();
6650 $(
6651 'label[for=everest-forms-field-option-' +
6652 dragged_field_id +
6653 '-select_min_time]',
6654 ).hide();
6655 $(
6656 'label[for=everest-forms-field-option-' +
6657 dragged_field_id +
6658 '-select_max_time]',
6659 ).hide();
6660 $(
6661 '#everest-forms-field-option-' +
6662 dragged_field_id +
6663 '-min_time_hour',
6664 )
6665 .parent()
6666 .hide();
6667 $(
6668 '#everest-forms-field-option-' +
6669 dragged_field_id +
6670 '-max_time_hour',
6671 )
6672 .parent()
6673 .hide();
6674 $(document.body).trigger('evf_field_drop_complete', [
6675 field_type,
6676 dragged_field_id,
6677 field_preview,
6678 field_options,
6679 ]);
6680 EVFPanelBuilder.checkEmptyGrid();
6681 return;
6682 }
6683
6684 if ($.contains(document.body, field[0])) {
6685 field.after(field_preview);
6686 } else {
6687 $('.evf-admin-grid').last().append(field_preview);
6688 }
6689
6690 if (
6691 null !== $('#everest-forms-panel-field-settings-enable_survey') &&
6692 $('#everest-forms-panel-field-settings-enable_survey').prop(
6693 'checked',
6694 )
6695 ) {
6696 $(
6697 '#everest-forms-field-option-' +
6698 dragged_field_id +
6699 '-survey_status',
6700 ).prop('checked', true);
6701 }
6702
6703 if (
6704 null !== $('#everest-forms-panel-field-settings-enable_quiz') &&
6705 $('#everest-forms-panel-field-settings-enable_quiz').prop('checked')
6706 ) {
6707 $(
6708 '#everest-forms-field-option-' +
6709 dragged_field_id +
6710 '-quiz_status',
6711 ).prop('checked', true);
6712 $(
6713 '#everest-forms-field-option-' +
6714 dragged_field_id +
6715 '-quiz_status',
6716 )
6717 .closest('.everest-forms-field-option-row-quiz_status')
6718 .siblings('.everst-forms-field-quiz-settings')
6719 .removeClass('everest-forms-hidden')
6720 .addClass('everest-forms-show');
6721 }
6722
6723 field.remove();
6724
6725 // Triggers.
6726 $(document.body).trigger('init_tooltips');
6727 $(document.body).trigger('init_field_options_toggle');
6728 $(document.body).trigger('evf_after_field_append', [dragged_el_id]);
6729 // Conditional logic append rules.
6730 EVFPanelBuilder.conditionalLogicAppendField(dragged_el_id);
6731 EVFPanelBuilder.conditionalLogicAppendFieldIntegration(dragged_el_id);
6732 EVFPanelBuilder.paymentFieldAppendToQuantity(dragged_el_id);
6733 EVFPanelBuilder.paymentFieldAppendToDropdown(
6734 dragged_field_id,
6735 field_type,
6736 );
6737
6738 //One Time draggable.
6739 EVFPanelBuilder.oneTimeDraggableField(dragged_field_id, field_type);
6740
6741 // Initialization Datepickers.
6742 EVFPanelBuilder.init_datepickers();
6743 EVFPanelBuilder.init_payment_subscription_plan_field();
6744
6745 // Hiding time min max options in setting for Datepickers.
6746 $(
6747 '#everest-forms-field-option-' +
6748 dragged_field_id +
6749 '-enable_min_max_time',
6750 ).hide();
6751 $(
6752 'label[for=everest-forms-field-option-' +
6753 dragged_field_id +
6754 '-enable_min_max_time]',
6755 ).hide();
6756 $(
6757 'label[for=everest-forms-field-option-' +
6758 dragged_field_id +
6759 '-select_min_time]',
6760 ).hide();
6761 $(
6762 'label[for=everest-forms-field-option-' +
6763 dragged_field_id +
6764 '-select_max_time]',
6765 ).hide();
6766 $(
6767 '#everest-forms-field-option-' +
6768 dragged_field_id +
6769 '-min_time_hour',
6770 )
6771 .parent()
6772 .hide();
6773 $(
6774 '#everest-forms-field-option-' +
6775 dragged_field_id +
6776 '-max_time_hour',
6777 )
6778 .parent()
6779 .hide();
6780
6781 // Trigger an event indicating completion of field_drop action.
6782 $(document.body).trigger('evf_field_drop_complete', [
6783 field_type,
6784 dragged_field_id,
6785 field_preview,
6786 field_options,
6787 ]);
6788 EVFPanelBuilder.checkEmptyGrid();
6789 },
6790 });
6791 },
6792
6793 conditionalLogicAppendField: function (id) {
6794 var dragged_el = $('#' + id);
6795 var dragged_index = dragged_el.index();
6796
6797 var fields = $('.evf-field-conditional-field-select');
6798
6799 var field_type = dragged_el.attr('data-field-type');
6800 var field_id = dragged_el.attr('data-field-id');
6801 var field_label = dragged_el.find('.label-title .text ').text();
6802
6803 $.fn.insertAt = function (elements, index, selected_id) {
6804 var array = $.makeArray(this.children().clone(true));
6805 array.splice(index, 0, elements);
6806 $.each(array, function (index, el) {
6807 if (selected_id === $(el)[0]['value']) {
6808 $(el)[0]['selected'] = true;
6809 array[index] = el;
6810 }
6811 });
6812 this.empty().append(array);
6813 };
6814 var dragged_field_id = field_id;
6815 fields.each(function (index, el) {
6816 var selected_id = $(el).val();
6817 var id_key = id.replace('everest-forms-field-', '');
6818 var name = $(el).attr('name');
6819 var name_key = name.substring(name.indexOf('[') + 1, name.indexOf(']'));
6820
6821 if (id_key === name_key) {
6822 $('.evf-admin-row .evf-admin-grid .everest-forms-field').each(
6823 function () {
6824 var form_field_type = $(this).data('field-type'),
6825 form_field_id = $(this).data('field-id'),
6826 form_field_label = $(this)
6827 .find('.label-title span')
6828 .first()
6829 .text();
6830 field_to_be_restricted = [];
6831 field_to_be_restricted = [
6832 'html',
6833 'title',
6834 'address',
6835 'image-upload',
6836 'file-upload',
6837 'date-time',
6838 'hidden',
6839 'scale-rating',
6840 'likert',
6841 'yes-no',
6842 ];
6843 if (
6844 $.inArray(form_field_type, field_to_be_restricted) === -1 &&
6845 dragged_field_id !== form_field_id
6846 ) {
6847 if (
6848 0 ===
6849 fields
6850 .eq(index)
6851 .find('option[data-field_id="' + form_field_id + '"]')
6852 .length
6853 ) {
6854 fields
6855 .eq(index)
6856 .append(
6857 '<option class="evf-conditional-fields" data-field_type="' +
6858 form_field_type +
6859 '" data-field_id="' +
6860 form_field_id +
6861 '" value="' +
6862 form_field_id +
6863 '">' +
6864 form_field_label +
6865 '</option>',
6866 );
6867 }
6868 }
6869 },
6870 );
6871 } else {
6872 var el_to_append =
6873 '<option class="evf-conditional-fields" data-field_type="' +
6874 field_type +
6875 '" data-field_id="' +
6876 field_id +
6877 '" value="' +
6878 field_id +
6879 '">' +
6880 field_label +
6881 '</option>';
6882 if (
6883 'html' !== field_type &&
6884 'title' !== field_type &&
6885 'address' !== field_type &&
6886 'image-upload' !== field_type &&
6887 'file-upload' !== field_type &&
6888 'hidden' !== field_type &&
6889 'likert' !== field_type &&
6890 'scale-rating' !== field_type &&
6891 'yes-no' !== field_type &&
6892 'divider' !== field_type
6893 ) {
6894 fields.eq(index).insertAt(el_to_append, 1, selected_id);
6895 }
6896 }
6897 if (
6898 fields.eq(index).find('option:not(.evf-conditional-fields)').length >
6899 1
6900 ) {
6901 fields
6902 .eq(index)
6903 .find('option:not(.evf-conditional-fields):gt(0)')
6904 .remove();
6905 }
6906 });
6907 },
6908 conditionalLogicAppendRow: function (id) {
6909 var new_row_option = $('#everest-forms-row-option-row_' + id);
6910
6911 var fields = $('.everest-forms-field');
6912
6913 fields.each(function () {
6914 var field = $(this),
6915 field_id = field.attr('data-field-id'),
6916 field_type = field.attr('data-field-type'),
6917 field_label = '';
6918
6919 field.find('.required').remove();
6920 field_label = field.find('.label-title').html();
6921
6922 var el_to_append =
6923 '<option class="evf-conditional-fields" data-field_type="' +
6924 field_type +
6925 '" data-field_id="' +
6926 field_id +
6927 '" value="' +
6928 field_id +
6929 '">' +
6930 field_label +
6931 '</option>';
6932
6933 if (
6934 0 ===
6935 $(document).find(
6936 '.evf-admin-row[data-row-id="' +
6937 id +
6938 '"] #everest-forms-field-' +
6939 field_id,
6940 ).length &&
6941 0 ===
6942 new_row_option.find(
6943 '.evf-field-conditional-field-select option[data-field_id="' +
6944 field_id +
6945 '"]',
6946 ).length &&
6947 'html' !== field_type &&
6948 'title' !== field_type &&
6949 'address' !== field_type &&
6950 'image-upload' !== field_type &&
6951 'file-upload' !== field_type &&
6952 'date-time' !== field_type &&
6953 'hidden' !== field_type &&
6954 'likert' !== field_type &&
6955 'scale-rating' !== field_type &&
6956 'divider' !== field_type
6957 ) {
6958 new_row_option
6959 .find('.evf-field-conditional-field-select')
6960 .append(el_to_append);
6961 }
6962 if (
6963 new_row_option.find(
6964 '.evf-field-conditional-field-select option:not(.evf-conditional-fields)',
6965 ).length > 1
6966 ) {
6967 new_row_option
6968 .find(
6969 '.evf-field-conditional-field-select option:not(.evf-conditional-fields):gt(0)',
6970 )
6971 .remove();
6972 }
6973 new_row_option.hide();
6974 });
6975 },
6976
6977 paymentFieldAppendToQuantity: function (id) {
6978 var dragged_el = $('#' + id);
6979
6980 var fields = $('.everest-forms-field-option-row-map_field select');
6981 var field_type = dragged_el.attr('data-field-type');
6982 var field_id = dragged_el.attr('data-field-id');
6983 var field_label = dragged_el.find('.label-title .text ').text();
6984
6985 var el_to_append =
6986 '<option value="' + field_id + '">' + field_label + '</option>';
6987 if (
6988 'payment-single' === field_type ||
6989 'payment-multiple' === field_type ||
6990 'payment-checkbox' === field_type
6991 ) {
6992 fields.append(el_to_append);
6993 }
6994 },
6995
6996 paymentFieldAppendToDropdown: function (dragged_field_id, field_type) {
6997 if (
6998 'payment-quantity' === field_type ||
6999 'payment-coupon' === field_type ||
7000 'payment-subtotal' === field_type
7001 ) {
7002 var match_fields = [
7003 'payment-checkbox',
7004 'payment-multiple',
7005 'payment-single',
7006 'range-slider',
7007 ],
7008 qty_dropdown = $(
7009 '#everest-forms-field-option-' + dragged_field_id + '-map_field',
7010 );
7011 match_fields.forEach(function (single_field) {
7012 $('.everest-forms-field-' + single_field).each(function () {
7013 if ('range-slider' === $(this).attr('data-field-type')) {
7014 if (
7015 'true' ===
7016 $(this)
7017 .find('.evf-range-slider-preview')
7018 .attr('data-enable-payment-slider')
7019 ) {
7020 var id = $(this).attr('data-field-id'),
7021 label = $(this).find('.label-title .text').text();
7022 var el_to_append =
7023 '<option value="' + id + '">' + label + '</option>';
7024 } else {
7025 return;
7026 }
7027 }
7028 var id = $(this).attr('data-field-id'),
7029 label = $(this).find('.label-title .text').text();
7030 var el_to_append =
7031 '<option value="' + id + '">' + label + '</option>';
7032 qty_dropdown.append(el_to_append);
7033 });
7034 });
7035 }
7036 },
7037
7038 oneTimeDraggableField: function (dragged_field_id, field_type) {
7039 var singleDraggableFields = evf_data.form_one_time_draggable_fields;
7040 var draggedFieldElement = $('#everest-forms-add-fields-' + field_type);
7041
7042 if (
7043 singleDraggableFields.length > 0 &&
7044 $.inArray(field_type, singleDraggableFields) >= 0 &&
7045 draggedFieldElement.length
7046 ) {
7047 draggedFieldElement.addClass('evf-one-time-draggable-field');
7048 // Destroy the jQuery UI draggable so the locked sidebar field can no longer
7049 // be dragged onto the canvas (mirrors oneTimeDraggableRemoveField).
7050 EVFPanelBuilder.refreshRegisteredSidebarFieldDraggable(
7051 draggedFieldElement,
7052 );
7053 }
7054 },
7055
7056 conditionalLogicAppendFieldIntegration: function (id) {
7057 var dragged_el = $('#' + id);
7058 var dragged_index = dragged_el.index();
7059
7060 var fields = $('.evf-provider-conditional').find(
7061 '.evf-conditional-field-select',
7062 );
7063
7064 var field_type = dragged_el.attr('data-field-type');
7065 var field_id = dragged_el.attr('data-field-id');
7066 var field_label = dragged_el.find('.label-title .text ').text();
7067
7068 $.fn.insertAt = function (elements, index) {
7069 var array = $.makeArray(this.children().clone(true));
7070 array.splice(index, 0, elements);
7071 this.empty().append(array);
7072 };
7073
7074 fields.each(function (index, el) {
7075 var id_key = id.replace('everest-forms-field-', '');
7076 var name = $(el).attr('name');
7077 var name_key = name.substring(name.indexOf('[') + 1, name.indexOf(']'));
7078
7079 if (id_key === name_key) {
7080 $('.evf-admin-row .evf-admin-grid .everest-forms-field').each(
7081 function () {
7082 var field_type = $(this).data('field-type'),
7083 field_id = $(this).data('field-id'),
7084 field_label = $(this).find('.label-title span').first().text();
7085 field_to_be_restricted = [];
7086 field_to_be_restricted = [
7087 'html',
7088 'title',
7089 'address',
7090 'image-upload',
7091 'file-upload',
7092 'signature',
7093 'divider',
7094 'date-time',
7095 'hidden',
7096 'scale-rating',
7097 'likert',
7098 'yes-no',
7099 dragged_el.attr('data-field-type'),
7100 ];
7101
7102 if ($.inArray(field_type, field_to_be_restricted) === -1) {
7103 fields
7104 .eq(index)
7105 .append(
7106 '<option class="evf-conditional-fields" data-field_type="' +
7107 field_type +
7108 '" data-field_id="' +
7109 field_id +
7110 '" value="' +
7111 field_id +
7112 '">' +
7113 field_label +
7114 '</option>',
7115 );
7116 }
7117 },
7118 );
7119 } else {
7120 var el_to_append =
7121 '<option class="evf-conditional-fields" data-field_type="' +
7122 field_type +
7123 '" data-field_id="' +
7124 field_id +
7125 '" value="' +
7126 field_id +
7127 '">' +
7128 field_label +
7129 '</option>';
7130 if (
7131 'html' !== field_type &&
7132 'title' !== field_type &&
7133 'address' !== field_type &&
7134 'image-upload' !== field_type &&
7135 'file-upload' !== field_type &&
7136 'date-time' !== field_type &&
7137 'hidden' !== field_type &&
7138 'likert' !== field_type &&
7139 'scale-rating' !== field_type &&
7140 'yes-no' !== field_type
7141 ) {
7142 fields.eq(index).insertAt(el_to_append, dragged_index);
7143 }
7144 }
7145 });
7146 },
7147
7148 conditionalLogicRemoveField: function (id) {
7149 $(
7150 '.evf-field-conditional-field-select option[value = ' + id + ' ]',
7151 ).remove();
7152 },
7153
7154 conditionalLogicRemoveFieldIntegration: function (id) {
7155 $(
7156 '.evf-provider-conditional .evf-conditional-field-select option[value = ' +
7157 id +
7158 ' ]',
7159 ).remove();
7160 },
7161
7162 paymentFieldRemoveFromQuantity: function (id) {
7163 $(
7164 '.everest-forms-field-option-row-map_field select option[value = ' +
7165 id +
7166 ' ]',
7167 ).remove();
7168 },
7169
7170 /**
7171 * Keep Payments / gateway panel field-map selects in sync when fields are added or removed
7172 * (e.g. phone appears for Stripe "customer_phone" mapping without reloading).
7173 *
7174 * @param {string} action 'add' or 'remove'.
7175 * @param {string} fieldRef For add: preview element id (e.g. everest-forms-field-12). For remove: data-field-id.
7176 */
7177 refreshFieldMapSelectsFromField: function (action, fieldRef) {
7178 var $form = $('form#everest-forms-builder-form');
7179 if (!$form.length) {
7180 return;
7181 }
7182
7183 if ('remove' === action) {
7184 var rid = String(fieldRef);
7185 $form
7186 .find('select.everest-forms-field-map-select')
7187 .each(function () {
7188 $(this).find('option[value="' + rid + '"]').remove();
7189 });
7190 return;
7191 }
7192
7193 var raw = String(fieldRef || '').replace(/^#/, '');
7194 var $field = $('#' + raw);
7195 if (!$field.length && /^\d+$/.test(raw)) {
7196 $field = $('#everest-forms-field-' + raw);
7197 }
7198 if (!$field.length) {
7199 return;
7200 }
7201
7202 var field_type = $field.attr('data-field-type');
7203 var element_id = $field.attr('data-field-id');
7204 if (!field_type || !element_id) {
7205 return;
7206 }
7207
7208 var label = $field.find('.label-title .text').first().text();
7209 if (!label) {
7210 label = '#' + element_id;
7211 }
7212
7213 $form.find('select.everest-forms-field-map-select').each(function () {
7214 var $select = $(this);
7215 var allowedAttr = $select.attr('data-field-map-allowed');
7216 if (!allowedAttr) {
7217 return;
7218 }
7219 var field_allowed = allowedAttr.split(/\s+/);
7220 if (
7221 field_allowed.indexOf(field_type) === -1 &&
7222 field_allowed.indexOf('all-fields') === -1
7223 ) {
7224 return;
7225 }
7226 if ($select.find('option[value="' + element_id + '"]').length) {
7227 return;
7228 }
7229 $select.append(
7230 $('<option></option>').attr('value', element_id).text(label),
7231 );
7232 });
7233 },
7234
7235 /**
7236 * Rebuild every field-map select inside a container from fields currently on the builder canvas.
7237 *
7238 * @param {string|jQuery} container Field option root, e.g. #everest-forms-field-option-{id}.
7239 * @param {string} excludeFieldId Optional data-field-id to omit (e.g. the gateway selector itself).
7240 */
7241 refreshFieldMapSelectsInContainer: function (container, excludeFieldId) {
7242 var $container =
7243 container instanceof jQuery ? container : $(container);
7244 if (!$container.length) {
7245 return;
7246 }
7247
7248 var exclude = excludeFieldId ? String(excludeFieldId) : '';
7249 var $canvasFields = $('#everest-forms-builder').find(
7250 '.evf-admin-field-wrapper .everest-forms-field',
7251 );
7252
7253 $container
7254 .find('select.everest-forms-field-map-select')
7255 .each(function () {
7256 var $select = $(this);
7257 var allowedAttr = $select.attr('data-field-map-allowed');
7258 if (!allowedAttr) {
7259 return;
7260 }
7261 var fieldAllowed = allowedAttr.split(/\s+/).filter(Boolean);
7262 var currentVal = $select.val();
7263 var placeholder = $select.attr('data-field-map-placeholder');
7264
7265 if ($select.hasClass('select2-hidden-accessible')) {
7266 try {
7267 $select.selectWoo('destroy');
7268 } catch (err) {
7269 // Ignore if selectWoo was not initialized.
7270 }
7271 $select.removeClass('enhanced');
7272 }
7273
7274 $select.empty();
7275 if (placeholder) {
7276 $select.append(
7277 $('<option></option>').attr('value', '').text(placeholder),
7278 );
7279 } else {
7280 $select.append($('<option></option>').attr('value', ''));
7281 }
7282
7283 $canvasFields.each(function () {
7284 var $f = $(this);
7285 var ft = $f.attr('data-field-type');
7286 var fid = String($f.attr('data-field-id') || '');
7287 if (!ft || !fid) {
7288 return;
7289 }
7290 if (exclude && fid === exclude) {
7291 return;
7292 }
7293 if (
7294 fieldAllowed.indexOf(ft) === -1 &&
7295 fieldAllowed.indexOf('all-fields') === -1
7296 ) {
7297 return;
7298 }
7299 var lbl = $f.find('.label-title .text').first().text();
7300 if (!lbl) {
7301 lbl = '#' + fid;
7302 }
7303 $select.append(
7304 $('<option></option>').attr('value', fid).text(lbl),
7305 );
7306 });
7307
7308 if (currentVal) {
7309 var match = false;
7310 $select.find('option').each(function () {
7311 if ($(this).val() === String(currentVal)) {
7312 match = true;
7313 return false;
7314 }
7315 });
7316 if (match) {
7317 $select.val(currentVal);
7318 }
7319 }
7320 });
7321
7322 $(document.body).trigger('evf-enhanced-select-init');
7323 },
7324
7325 oneTimeDraggableRemoveField: function (field_type) {
7326 var dragged_field_id = $('#everest-forms-add-fields-' + field_type);
7327 if (dragged_field_id.hasClass('evf-one-time-draggable-field')) {
7328 dragged_field_id.removeClass('upgrade-modal');
7329 dragged_field_id.removeClass('evf-one-time-draggable-field');
7330 EVFPanelBuilder.refreshRegisteredSidebarFieldDraggable(
7331 dragged_field_id,
7332 );
7333 }
7334 },
7335
7336 /**
7337 * Whether a sidebar field button should not be draggable (blocked state).
7338 *
7339 * @param {jQuery} $item Sidebar registered field button.
7340 * @return {boolean}
7341 */
7342 isRegisteredSidebarFieldBlocked: function ($item) {
7343 if (!$item || !$item.length) {
7344 return true;
7345 }
7346
7347 return $item.is(
7348 '.upgrade-modal, .evf-upgrade-addon, .enable-stripe-model, .enable-authorize-net-model, .enable-payment-subscription-plan, .everest-forms-pro-is_square_install, .enable-square-model, .evf-one-time-draggable-field, .recaptcha_empty_key_validate, .hcaptcha_empty_key_validate, .turnstile_empty_key_validate',
7349 );
7350 },
7351
7352 /**
7353 * Apply or remove jQuery UI draggable on sidebar field buttons after dynamic class changes.
7354 *
7355 * @param {jQuery} [$items] Optional buttons to refresh; defaults to all registered sidebar fields.
7356 */
7357 refreshRegisteredSidebarFieldDraggable: function ($items) {
7358 if (!$items || !$items.length) {
7359 $items = $(
7360 '.evf-registered-buttons button.evf-registered-item:not(.evf-layout-container-btn)',
7361 );
7362 }
7363
7364 $items.each(function () {
7365 var $btn = $(this);
7366
7367 if (EVFPanelBuilder.isRegisteredSidebarFieldBlocked($btn)) {
7368 if ($btn.data('ui-draggable')) {
7369 $btn.draggable('destroy');
7370 }
7371 return;
7372 }
7373
7374 if ($btn.data('ui-draggable')) {
7375 return;
7376 }
7377
7378 $btn
7379 .draggable({
7380 delay: 200,
7381 cancel: false,
7382 scroll: false,
7383 revert: 'invalid',
7384 scrollSensitivity: 40,
7385 forcePlaceholderSize: true,
7386 start: function () {
7387 $(this).addClass('field-dragged');
7388 },
7389 helper: function () {
7390 return $(this)
7391 .clone()
7392 .insertAfter(
7393 $(this)
7394 .closest('.everest-forms-tab-content')
7395 .siblings('.everest-forms-fields-tab'),
7396 );
7397 },
7398 stop: function () {
7399 $(this).removeClass('field-dragged');
7400 },
7401 opacity: 0.75,
7402 containment: '#everest-forms-builder',
7403 connectToSortable: '.evf-admin-grid',
7404 })
7405 .disableSelection();
7406 });
7407 },
7408
7409 syncPaymentMethodDependentFields: function () {
7410 var $builder = $('#everest-forms-builder');
7411 var hasPaymentMethodField =
7412 $builder.find('.everest-forms-field-payment-gateway-selector').length > 0;
7413 // Credit Card (Stripe) on the canvas blocks adding Payment Gateway; Payments tab
7414 // toggles can also block it. Legacy Credit Card / Authorize.Net / Square fields are
7415 // not mutually disabled with Payment Gateway for drag purposes beyond this.
7416 var $paymentGatewayAdd = $(
7417 '#everest-forms-add-fields-payment-gateway-selector',
7418 );
7419 if ($paymentGatewayAdd.length) {
7420 var hasEnabledPayments =
7421 EVFPanelBuilder.isAnyPaymentEnabled &&
7422 EVFPanelBuilder.isAnyPaymentEnabled();
7423
7424 // If any payment is enabled in Payments tab, force-disable Payment Gateway field.
7425 if (hasEnabledPayments) {
7426 $paymentGatewayAdd.addClass('evf-one-time-draggable-field');
7427 $paymentGatewayAdd.addClass('evf-payment-method-dependent-disabled');
7428 $paymentGatewayAdd.attr('data-evf-disabled-reason', 'enabled-payments');
7429 } else {
7430 var hasCreditCardField =
7431 $builder.find('.everest-forms-field-credit-card').length > 0;
7432
7433 if (hasCreditCardField) {
7434 $paymentGatewayAdd.addClass('evf-one-time-draggable-field');
7435 $paymentGatewayAdd.addClass('evf-payment-method-dependent-disabled');
7436 $paymentGatewayAdd.attr(
7437 'data-evf-disabled-reason',
7438 'credit-card-field',
7439 );
7440 } else {
7441 $paymentGatewayAdd.removeAttr('data-evf-disabled-reason');
7442 $paymentGatewayAdd.removeClass(
7443 'evf-payment-method-dependent-disabled',
7444 );
7445 if (!hasPaymentMethodField) {
7446 $paymentGatewayAdd.removeClass('evf-one-time-draggable-field');
7447 }
7448 }
7449 }
7450
7451 EVFPanelBuilder.refreshRegisteredSidebarFieldDraggable(
7452 $paymentGatewayAdd,
7453 );
7454 }
7455
7456 // If Payment Gateway field is used, block enabling payment gateways from Payments tab.
7457 if (EVFPanelBuilder.syncPaymentsTabEnableToggles) {
7458 EVFPanelBuilder.syncPaymentsTabEnableToggles(hasPaymentMethodField);
7459 }
7460
7461 // Payment Gateway selector replaces the legacy Credit Card field on the sidebar.
7462 var $creditCardAdd = $('#everest-forms-add-fields-credit-card');
7463 if ($creditCardAdd.length) {
7464 if (hasPaymentMethodField) {
7465 $creditCardAdd.addClass('enable-stripe-model');
7466 } else if (
7467 typeof EverestFormsProBuilder !== 'undefined' &&
7468 EverestFormsProBuilder.checkEnabledPayments
7469 ) {
7470 EverestFormsProBuilder.checkEnabledPayments();
7471 }
7472 EVFPanelBuilder.refreshRegisteredSidebarFieldDraggable($creditCardAdd);
7473 }
7474 },
7475
7476 /**
7477 * Whether any payment gateway is enabled in the Payments tab.
7478 *
7479 * This is used to restrict the Payment Gateway (selector) field: if a gateway is already enabled,
7480 * the selector field must stay off until those toggles are disabled.
7481 *
7482 * @return {boolean}
7483 */
7484 isAnyPaymentEnabled: function () {
7485 var selectors = [
7486 '#everest-forms-panel-field-paymentsstripe-enable_stripe',
7487 '#everest-forms-panel-field-paypal-enable_paypal',
7488 // Razorpay toggle id varies by version/addon; support both.
7489 '#everest-forms-panel-field-paymentsrazorpay-enable_razorpay',
7490 '#everest-forms-panel-field-razorpay-enable_razorpay',
7491 'input[name*="[razorpay]"][name*="enable_razorpay"]',
7492 '#everest-forms-panel-field-authorize_net-enable_authorize_net',
7493 '#everest-forms-panel-field-square-enable_square',
7494 '#everest-forms-panel-field-paymentsmollie-enable_mollie',
7495 ];
7496
7497 for (var i = 0; i < selectors.length; i++) {
7498 var $el = $(selectors[i]);
7499 if ($el.length && $el.is(':checked')) {
7500 return true;
7501 }
7502 }
7503 return false;
7504 },
7505
7506 bindFieldSettings: function () {
7507 $('body').on(
7508 'click',
7509 '.everest-forms-preview .everest-forms-field, .everest-forms-preview .everest-forms-field .everest-forms-field-setting',
7510 function (e) {
7511 e.preventDefault();
7512 var field_id = $(this)
7513 .closest('.everest-forms-field')
7514 .attr('data-field-id');
7515 $('.everest-forms-tab-content').scrollTop(0);
7516 EVFPanelBuilder.switchToFieldOptionPanel(field_id);
7517 },
7518 );
7519 },
7520
7521 toggleLabelEdit: function (label, input) {
7522 $(label).toggleClass('everest-forms-hidden');
7523 $(input).toggleClass('everest-forms-hidden');
7524
7525 if ($(input).is(':visible')) {
7526 $(input).focus();
7527 }
7528 },
7529
7530 bindToggleHandleActions: function () {
7531 $('body').on('click', '.toggle-handle', function (e) {
7532 var label = $(this).data('label'),
7533 input = $(this).data('input');
7534
7535 if (!$(input).is(':visible')) {
7536 EVFPanelBuilder.toggleLabelEdit(label, input);
7537 }
7538 });
7539 },
7540
7541 bindLabelEditInputActions: function () {
7542 $('body').on('focusout', '.label-edit-input', function (e) {
7543 var label = $(this).data('label'),
7544 input = this;
7545
7546 EVFPanelBuilder.toggleLabelEdit(label, input);
7547 });
7548 },
7549
7550 /**
7551 * Sync an input element with other elements like labels. An element with `sync-input` class will be synced to the elements
7552 * specified in `sync-targets` data.
7553 *
7554 * `Warning:` This is an one way sync, meaning only the text `sync-targets` will be updated when the source element's value changes
7555 * and the source element's value will not be updated if the value of `sync-targets` changes.
7556 */
7557 bindSyncedInputActions: function () {
7558 $('body').on('input', '.sync-input', function (e) {
7559 var changed_value = $(this).val(),
7560 sync_targets = $(this).data('sync-targets');
7561
7562 if (changed_value && sync_targets) {
7563 $(sync_targets).text(changed_value);
7564 }
7565 });
7566 },
7567 /**
7568 * Akismet anti-spam protection.
7569 *
7570 * @since 2.4.0
7571 */
7572 bindAkismetInit: function () {
7573 var akismetEnabler = $(document).find(
7574 '#everest-forms-panel-field-settings-akismet',
7575 );
7576 EVFPanelBuilder.akismetTogger(akismetEnabler);
7577 $(document).on(
7578 'change',
7579 '#everest-forms-panel-field-settings-akismet',
7580 function () {
7581 EVFPanelBuilder.akismetTogger($(this));
7582 },
7583 );
7584 },
7585 /**
7586 * Akismet Toggler.
7587 *
7588 * @param {object} akismetEnabler
7589 */
7590 akismetTogger: function (akismetEnabler) {
7591 if ($(akismetEnabler).is(':checked')) {
7592 $(document).find('.everest-forms-akismet-protection-type').show();
7593 } else {
7594 $(document).find('.everest-forms-akismet-protection-type').hide();
7595 }
7596 },
7597
7598 /**
7599 * Form Submission minimum waiting time.
7600 *
7601 * @since 3.0.2
7602 */
7603 bindFormSubmissionMinWaitingTime: function () {
7604 var submissionWaitingTimeEnabler = $(document).find(
7605 '#everest-forms-panel-field-settings-form_submission_min_waiting_time',
7606 );
7607 EVFPanelBuilder.formSubmissionMinTimeToggler(
7608 submissionWaitingTimeEnabler,
7609 );
7610 $(document).on(
7611 'change',
7612 '#everest-forms-panel-field-settings-form_submission_min_waiting_time',
7613 function () {
7614 EVFPanelBuilder.formSubmissionMinTimeToggler($(this));
7615 },
7616 );
7617 },
7618 /**
7619 * Form Submission waiting time Toggler.
7620 *
7621 * @param {object} submissionWaitingTimeEnabler
7622 */
7623 formSubmissionMinTimeToggler: function (submissionWaitingTimeEnabler) {
7624 if ($(submissionWaitingTimeEnabler).is(':checked')) {
7625 $(document)
7626 .find('.everest-forms-form-submission-minimum-waiting-time')
7627 .show();
7628 } else {
7629 $(document)
7630 .find('.everest-forms-form-submission-minimum-waiting-time')
7631 .hide();
7632 }
7633 },
7634 bindEditMetaKey: function (field_id = '') {
7635 $(document).on('click', '.evf-meta-key-copy-btn', function () {
7636 const $wrapper = $(this).closest('.evf-meta-key-input-wrapper');
7637 const $input = $wrapper.find('.evf-input-meta-key');
7638 const metaKey = $input.val();
7639
7640 $(this)
7641 .tooltipster('content', $(this).attr('data-copied'))
7642 .trigger('mouseenter')
7643 .on('mouseleave', function () {
7644 var $this = $(this);
7645
7646 setTimeout(function () {
7647 $this.tooltipster('content', $this.attr('data-tip'));
7648 }, 1000);
7649 });
7650
7651 navigator.clipboard.writeText(metaKey);
7652 });
7653
7654 if ('' === field_id) {
7655 $(document)
7656 .find('.evf-input-meta-key')
7657 .each(function () {
7658 var $this = $(this);
7659
7660 appendEditIcon($this);
7661 });
7662 } else {
7663 var $this = $('#everest-forms-field-option-' + field_id + '-meta-key');
7664 appendEditIcon($this);
7665 }
7666
7667 function appendEditIcon($this) {
7668 $this.wrap('<div class="evf-meta-key-input-wrapper"></div>');
7669
7670 $this.before(
7671 `<span class="evf-edit-meta-key-icon" data-meta_key="${$this.val()}">Edit</span>`,
7672 );
7673
7674 const $copyBtn = $(`
7675 <span class="evf-meta-key-copy-btn" data-copied="Copied!" data-tip="Copy to clipboard">
7676 <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
7677 <path d="M15.002 5.99902H7.50195C6.67353 5.99902 6.00195 6.6706 6.00195 7.49902V14.999C6.00195 15.8274 6.67353 16.499 7.50195 16.499H15.002C15.8304 16.499 16.502 15.8274 16.502 14.999V7.49902C16.502 6.6706 15.8304 5.99902 15.002 5.99902Z" stroke="#6B6B6B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7678 <path d="M3.00195 11.999C2.17695 11.999 1.50195 11.324 1.50195 10.499V2.99902C1.50195 2.17402 2.17695 1.49902 3.00195 1.49902H10.502C11.327 1.49902 12.002 2.17402 12.002 2.99902" stroke="#6B6B6B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7679 </svg>
7680 </span>
7681 `);
7682
7683 $this.after($copyBtn);
7684
7685 // Initialize Tooltipster
7686 $copyBtn.tooltipster({
7687 theme: 'tooltipster-default',
7688 delay: 100,
7689 side: 'top',
7690 updateAnimation: 'null',
7691 });
7692 }
7693 },
7694
7695 bindPrivacyPolicyActions: function () {
7696 // Consent message change handler.
7697 $(document.body).on(
7698 'input',
7699 '.everest-forms-field-option .evf-privacy-policy-consent-message',
7700 function (e) {
7701 var new_message = EVFPanelBuilder.processSyntaxes($(this).val());
7702
7703 // Update with the new processed consent message.
7704 $('.everest-forms-field.active')
7705 .find('.evf-privacy-policy-consent-message')
7706 .html(new_message);
7707 },
7708 );
7709
7710 // Local page add handler.
7711 $(document.body).on(
7712 'click',
7713 '.everest-forms-field-option .evf-add-local-privacy-policy-page',
7714 function (e) {
7715 var new_message = $(
7716 '.everest-forms-field-option:visible .evf-privacy-policy-consent-message',
7717 ).val(),
7718 selected_page_id = $(
7719 '.everest-forms-field-option:visible .evf-select-local-privacy-policy-page',
7720 ).val(),
7721 selected_page_title = $(
7722 '.everest-forms-field-option:visible .evf-select-local-privacy-policy-page option:selected',
7723 ).html();
7724
7725 // Append a hyperlink syntax containing the selected page to the consent message.
7726 if (selected_page_id) {
7727 new_message +=
7728 '[' +
7729 selected_page_title +
7730 '](?page_id=' +
7731 selected_page_id +
7732 ')';
7733
7734 // Update with the new consent message.
7735 $(
7736 '.everest-forms-field-option:visible .evf-privacy-policy-consent-message',
7737 ).val(new_message);
7738 new_message = EVFPanelBuilder.processSyntaxes(new_message);
7739 $('.everest-forms-field.active')
7740 .find('.evf-privacy-policy-consent-message')
7741 .html(new_message);
7742 }
7743 },
7744 );
7745
7746 // Custom page add handler.
7747 $(document.body).on(
7748 'click',
7749 '.everest-forms-field-option .evf-privacy-policy-add-custom-url',
7750 function (e) {
7751 var new_message = $(
7752 '.everest-forms-field-option:visible .evf-privacy-policy-consent-message',
7753 ).val(),
7754 label = $(
7755 '.everest-forms-field-option:visible .evf-privacy-policy-custom-link-label',
7756 )
7757 .val()
7758 .trim(),
7759 url = $(
7760 '.everest-forms-field-option:visible .evf-privacy-policy-custom-link-url',
7761 )
7762 .val()
7763 .trim();
7764
7765 // Prepend `http` protocol in the url.
7766 if (url.search('http') < 0) {
7767 url = 'http://' + url;
7768 }
7769
7770 // Append a hyperlink syntax containing the custom URL to the consent message.
7771 if ('' !== url) {
7772 new_message += '[' + label + '](' + url + ')';
7773
7774 // Update with the new consent message.
7775 $(
7776 '.everest-forms-field-option:visible .evf-privacy-policy-consent-message',
7777 ).val(new_message);
7778 new_message = EVFPanelBuilder.processSyntaxes(new_message);
7779 $('.everest-forms-field.active')
7780 .find('.evf-privacy-policy-consent-message')
7781 .html(new_message);
7782
7783 // Empty the input fields.
7784 $(
7785 '.everest-forms-field-option:visible .evf-privacy-policy-custom-link-label',
7786 ).val('');
7787 $(
7788 '.everest-forms-field-option:visible .evf-privacy-policy-custom-link-url',
7789 ).val('');
7790 }
7791 },
7792 );
7793 },
7794 /**
7795 * Process syntaxes in a text.
7796 *
7797 * @since 1.7.0
7798 *
7799 * @param {string} text Text to be processed.
7800 * @param {bool} escape_html Whether to escape all the htmls before processing or not.
7801 *
7802 * @return {string} Processed text.
7803 */
7804 processSyntaxes: function (text) {
7805 text = text.replace(/^\s+/g, '');
7806 text = EVFPanelBuilder.processHyperlinkSyntax(text);
7807 text = EVFPanelBuilder.process_italic_syntax(text);
7808 text = EVFPanelBuilder.process_bold_syntax(text);
7809 text = EVFPanelBuilder.process_underline_syntax(text);
7810 text = EVFPanelBuilder.process_new_lines(text);
7811 return text;
7812 },
7813
7814 /**
7815 * Process hyperlink syntaxes in a text.
7816 * The syntax used for hyperlink is: [Link Label](Link URL)
7817 * Example: [Google Search Page](https://google.com)
7818 *
7819 * @since 1.7.0
7820 *
7821 * @param {string} text Text to process.
7822 *
7823 * @return {string} Processed text.
7824 */
7825 processHyperlinkSyntax: function (text) {
7826 var regex = new RegExp(/(\[[^\[\]]*\])(\([^\(\)]*\))/g);
7827
7828 // Process all the hyperlink syntax.
7829 while ((matches = regex.exec(text))) {
7830 var matched_string = matches[0];
7831 var label = matches[1];
7832 var link = matches[2];
7833
7834 // Trim brackets.
7835 label = label.substring(1, label.length - 1);
7836 link = link.substring(1, link.length - 1);
7837
7838 // Proceed only if label or link is not empty.
7839 if ('' !== label || '' !== link) {
7840 // Use hash(#) if the link is empty.
7841 if ('' === link) {
7842 link = '#';
7843 }
7844
7845 // Use link as label if it's empty.
7846 if ('' === label) {
7847 label = link;
7848 }
7849
7850 // Insert hyperlink html.
7851 var html = '<a href="' + link + '">' + label + '</a>';
7852 text = text.replace(matched_string, html);
7853 } else {
7854 // If both label and link are empty then replace it with empty string.
7855 text = text.replace(matched_string, '');
7856 }
7857 }
7858 return text;
7859 },
7860
7861 /**
7862 * Process italic syntaxes in a text.
7863 * The syntax used for italic text is: `text`
7864 * Just wrap the text with back tick characters. To escape a backtick insert a backslash(\) before the character like "\`".
7865 *
7866 * @since 1.7.0
7867 *
7868 * @param {string} text Text to process.
7869 *
7870 * @return {string} Processed text.
7871 */
7872 process_italic_syntax: function (text) {
7873 var regex = new RegExp(/`[^`]+`/g);
7874 text = text.split('\\`').join('<&&&&&>'); // To preserve an escaped special character '`'.
7875
7876 while ((matches = regex.exec(text))) {
7877 var matched_string = matches[0];
7878 var label = matched_string
7879 .trim()
7880 .substring(1, matched_string.length - 1);
7881 var html = '<i>' + label + '</i>';
7882 text = text.replace(matched_string, html);
7883 }
7884 return text.split('<&&&&&>').join('`');
7885 },
7886
7887 /**
7888 * Process bold syntaxes in a text.
7889 * The syntax used for bold text is: *text*
7890 * Just wrap the text with asterisk characters. To escape an asterisk insert a backslash(\) before the character like "\*".
7891 *
7892 * @since 1.7.0
7893 *
7894 * @param {string} text Text to process.
7895 *
7896 * @return {string} Processed text.
7897 */
7898 process_bold_syntax: function (text) {
7899 var regex = new RegExp(/\*[^*]+\*/g);
7900 text = text.split('\\*').join('<&&&&&>'); // To preserve an escaped special character '*'.
7901
7902 while ((matches = regex.exec(text))) {
7903 var matched_string = matches[0];
7904 var label = matched_string
7905 .trim()
7906 .substring(1, matched_string.length - 1);
7907 var html = '<b>' + label + '</b>';
7908 text = text.replace(matched_string, html);
7909 }
7910 return text.split('<&&&&&>').join('*');
7911 },
7912
7913 /**
7914 * Process underline syntaxes in a text.
7915 * The syntax used for bold text is: __text__
7916 * Wrap the text with double underscore characters. To escape an underscore insert a backslash(\) before the character like "\_".
7917 *
7918 * @since 1.7.0
7919 *
7920 * @param {string} text Text to process.
7921 *
7922 * @return {string} Processed text.
7923 */
7924 process_underline_syntax: function (text) {
7925 var regex = new RegExp(/__[^_]+__/g);
7926 text = text.split('\\_').join('<&&&&&>'); // To preserve an escaped special character '_'.
7927
7928 while ((matches = regex.exec(text))) {
7929 var matched_string = matches[0];
7930 var label = matched_string
7931 .trim()
7932 .substring(2, matched_string.length - 2);
7933 var html = '<u>' + label + '</u>';
7934 text = text.replace(matched_string, html);
7935 }
7936 return text.split('<&&&&&>').join('_');
7937 },
7938
7939 /**
7940 * It replaces `\n` characters with `<br/>` tag because new line `\n` character is not supported in html.
7941 *
7942 * @since 1.7.0
7943 *
7944 * @param {string} text
7945 *
7946 * @return {string} Processed text.
7947 */
7948 process_new_lines: function (text) {
7949 //Ref: https://stackoverflow.com/questions/1144783/how-to-replace-all-occurrences-of-a-string
7950 return text.split('\n').join('<br/>');
7951 },
7952 livePreviewNumberOfRating: function (el) {
7953 var $this = $(el),
7954 value = $this.val();
7955 if (value.length == 0 || value <= 0) {
7956 value = 1;
7957 }
7958 var id = $this.parent().data('field-id'),
7959 icons = $('#everest-forms-field-' + id + ' .rating-icon').first();
7960 if (value <= 100) {
7961 $('#everest-forms-field-' + id + ' .rating-icon').remove();
7962 for (var $i = 1; $i <= value; $i++) {
7963 $('#everest-forms-field-' + id + '').append(icons.clone());
7964 }
7965 }
7966 },
7967 bindFormTags: function () {},
7968 };
7969
7970 /**
7971 * Re-render the builder's fields canvas + options panel in place (no full page
7972 * reload). Used by the in-builder AI chat after it edits the form via the AI
7973 * gateway. Because all field interactions are delegated on $builder (which is
7974 * NOT replaced), only sortables need re-initialising via bindFields().
7975 *
7976 * @param {number} formId Form ID to re-render.
7977 * @param {string} nonce evf_ai_nonce.
7978 * @param {function} done Callback(success:boolean).
7979 */
7980 window.evfReloadBuilderFields = function (formId, nonce, done) {
7981 $.post(
7982 window.ajaxurl,
7983 { action: 'evf_ai_render_fields', nonce: nonce, form_id: formId },
7984 function (res) {
7985 var ok = !!(res && res.success && res.data);
7986 if (ok) {
7987 $builder.find('.everest-forms-field-wrap').html(res.data.preview);
7988 $builder.find('.everest-forms-field-options').html(res.data.options);
7989 if (res.data.title) {
7990 $('#evf-edit-form-name').val(res.data.title);
7991 $('#everest-forms-panel-field-settings-form_title').val(res.data.title);
7992 }
7993 try {
7994 EVFPanelBuilder.bindFields();
7995 $(document.body).trigger('evf-enhanced-select-init');
7996
7997 // Select the first field by default so the field options
7998 // tab isn't left empty after the builder refreshes.
7999 var $firstField = $builder
8000 .find('.evf-admin-field-wrapper .everest-forms-field')
8001 .first();
8002 if ($firstField.length) {
8003 EVFPanelBuilder.switchToFieldOptionPanel(
8004 $firstField.attr('data-field-id'),
8005 );
8006 }
8007 } catch (e) {
8008 // Re-init is best-effort; the swapped DOM is still usable.
8009 }
8010 }
8011 if (typeof done === 'function') {
8012 done(ok);
8013 }
8014 }
8015 ).fail(function () {
8016 if (typeof done === 'function') {
8017 done(false);
8018 }
8019 });
8020 };
8021
8022 EVFPanelBuilder.init();
8023 })(jQuery, window.evf_data);
8024
8025 jQuery(function ($) {
8026 if (
8027 $(
8028 '#everest-forms-panel-field-settingsemail-evf_send_confirmation_email',
8029 ).attr('checked') != 'checked'
8030 ) {
8031 $(
8032 '#everest-forms-panel-field-settingsemail-evf_send_confirmation_email-wrap',
8033 )
8034 .nextAll()
8035 .hide();
8036 }
8037
8038 $('#everest-forms-panel-field-settingsemail-evf_send_confirmation_email').on(
8039 'change',
8040 function () {
8041 if ($(this).attr('checked') != 'checked') {
8042 $(
8043 '#everest-forms-panel-field-settingsemail-evf_send_confirmation_email-wrap',
8044 )
8045 .nextAll()
8046 .hide();
8047 } else {
8048 $(
8049 '#everest-forms-panel-field-settingsemail-evf_send_confirmation_email-wrap',
8050 )
8051 .nextAll()
8052 .show();
8053 }
8054 },
8055 );
8056
8057 window.pageType = function (el, redirectTo) {
8058 var outerWrapper = $(el).closest('.evf-confirmation-wrap');
8059
8060 // If the element isn't checked, return early.
8061 if (!el.is(':checked')) {
8062 return;
8063 }
8064
8065 // Show the appropriate settings based on redirect type.
8066 switch (redirectTo) {
8067 case 'same':
8068 $(outerWrapper).find('.same-page-setting').show();
8069 outerWrapper
8070 .find('.external-page-setting, .custom-page-setting')
8071 .hide();
8072 outerWrapper.find('.custom-and-external-page-setting').hide();
8073
8074 // Handle form state type changes.
8075 var el = outerWrapper.find('.form-state-type:checked');
8076 var initialValue = el.val();
8077
8078 toggleMessageLocations(el, initialValue);
8079 previewType(el, outerWrapper);
8080
8081 outerWrapper
8082 .off('change', '.form-state-type')
8083 .on('change', '.form-state-type', function () {
8084 toggleMessageLocations($(this), $(this).val());
8085 });
8086
8087 outerWrapper.on('change', '.everest-preview-confirmation', function () {
8088 var html = '';
8089 if ($(this).is(':checked')) {
8090 var options = [
8091 { value: 'top', label: 'Above Form Summary' },
8092 { value: 'bottom', label: 'Below Form Summary' },
8093 { value: 'popup', label: 'As Popup' },
8094 ];
8095 } else {
8096 var options = [
8097 { value: 'hide', label: 'Shown Message in Place of Form' },
8098 { value: 'popup', label: 'As Popup' },
8099 ];
8100 }
8101
8102 var select = outerWrapper.find('.form-state-hide select');
8103
8104 select.empty();
8105
8106 $.each(options, function (index, option) {
8107 html += `<option value="${option.value}">${option.label}</option>`;
8108 });
8109
8110 select.html(html);
8111 setTimeout(function () {
8112 select.trigger('change');
8113 }, 50);
8114 });
8115 break;
8116 case 'custom_page':
8117 outerWrapper.find('.custom-page-setting').show();
8118 outerWrapper.find('.custom-and-external-page-setting').show();
8119 outerWrapper.find('.same-page-setting, .external-page-setting').hide();
8120
8121 toggleAppendQueryString(outerWrapper);
8122 break;
8123 case 'external_url':
8124 outerWrapper.find('.external-page-setting').show();
8125 outerWrapper.find('.custom-and-external-page-setting').show();
8126 outerWrapper.find('.same-page-setting, .custom-page-setting').hide();
8127
8128 toggleAppendQueryString(outerWrapper);
8129 break;
8130 default:
8131 console.warn('Unknown redirect type:', redirectTo);
8132 break;
8133 }
8134 };
8135
8136 // Initialize on page load
8137 $(function ($) {
8138 // Get initial value and apply
8139 $('.confirmation-redirect-to').each(function () {
8140 var initialValue = $(this).val();
8141 window.pageType($(this), initialValue);
8142 });
8143
8144 // Handle changes
8145 $(document).on('change', '.confirmation-redirect-to', function () {
8146 window.pageType($(this), $(this).val());
8147 });
8148 });
8149
8150 // Function to toggle message locations based on form state
8151 function toggleMessageLocations(el, state) {
8152 var wrapper = $(el).closest('.everest-forms-border-container');
8153 wrapper.find('.form-state-hide, .form-state-reset').hide();
8154
8155 if (state === 'hide') {
8156 wrapper.find('.form-state-hide').show();
8157 wrapper.find('.preview-confirmation-toggle-wrapper').show();
8158 if (wrapper.find('.everest-preview-confirmation').is(':checked')) {
8159 wrapper.find('.preview-confirm-select-wrapper').show();
8160 } else {
8161 wrapper.find('.preview-confirm-select-wrapper').hide();
8162 }
8163 } else if (state === 'reset') {
8164 wrapper.find('.preview-confirmation-toggle-wrapper').hide();
8165 wrapper.find('.preview-confirm-select-wrapper').hide();
8166 wrapper.find('.form-state-reset').show();
8167 }
8168 }
8169
8170 // Handle query string toggle
8171 function toggleAppendQueryString(outerWrapper) {
8172 var queryStringWrap = outerWrapper.find('.query-string-wrap');
8173 var appendInput = outerWrapper.find('.append-query-string-input');
8174 queryStringWrap.toggle(appendInput.is(':checked'));
8175
8176 outerWrapper.on('change', '.append-query-string-input', function () {
8177 queryStringWrap.toggle($(this).is(':checked'));
8178 });
8179 }
8180
8181 function previewType(el, outerWrapper) {
8182 var queryStringWrap = outerWrapper.find('.preview-confirm-select-wrapper');
8183
8184 if (el.val() == 'reset') {
8185 queryStringWrap.toggle(false);
8186 return;
8187 }
8188
8189 var appendInput = outerWrapper.find('.everest-preview-confirmation');
8190 queryStringWrap.toggle(appendInput.is(':checked'));
8191
8192 outerWrapper.on('change', '.everest-preview-confirmation', function () {
8193 queryStringWrap.toggle($(this).is(':checked'));
8194 });
8195 }
8196
8197 $('.evf-panel-field-options-button.evf-disabled-tab').hide();
8198 });
8199
8200 jQuery(function ($) {
8201 // Add Fields - Open/close.
8202 $(document.body)
8203 .on('init_add_fields_toogle', function () {
8204 $('.everest-forms-add-fields').on(
8205 'click',
8206 '.everest-forms-add-fields-group > a',
8207 function (event) {
8208 event.preventDefault();
8209 $(this)
8210 .parent('.everest-forms-add-fields-group')
8211 .toggleClass('closed')
8212 .toggleClass('open');
8213 },
8214 );
8215 $('.everest-forms-add-fields').on(
8216 'click',
8217 '.everest-forms-add-fields-group a',
8218 function () {
8219 $(this).next('.evf-registered-buttons').stop().slideToggle();
8220 },
8221 );
8222 $('.everest-forms-add-fields-group.closed').each(function () {
8223 $(this).find('.evf-registered-buttons').hide();
8224 });
8225 })
8226 .trigger('init_add_fields_toogle');
8227
8228 // Fields Options - Open/close.
8229 $(document.body).on(
8230 'click',
8231 '.everest-forms-field-option .everest-forms-field-option-group > a',
8232 function (event) {
8233 event.preventDefault();
8234 var $fielOption = $(this)
8235 .closest('.everest-forms-field-option-group')
8236 .closest('.everest-forms-field-option');
8237 var currentElement = $(this),
8238 currentElementId = currentElement
8239 .parent('.everest-forms-field-option-group')
8240 .attr('id');
8241
8242 $fielOption.find('.everest-forms-field-option-group').each(function () {
8243 var selectedID = $(this).attr('id');
8244 if (currentElementId !== selectedID) {
8245 $(this).removeClass('open').addClass('closed');
8246 }
8247 });
8248
8249 var $currentGroup = $(this).parent('.everest-forms-field-option-group');
8250 if ($currentGroup.hasClass('closed')) {
8251 $currentGroup.removeClass('closed').addClass('open');
8252 } else {
8253 $currentGroup.removeClass('open').addClass('closed');
8254 }
8255 $('.everest-forms-field-option-group.closed').not($currentGroup).each(function () {
8256 $(this).find('.everest-forms-field-option-group-inner').hide();
8257 });
8258 },
8259 );
8260 $(document.body).on(
8261 'click',
8262 '.everest-forms-field-option .everest-forms-field-option-group a',
8263 function (event) {
8264 // If the user clicks on some form input inside, the box should not be toggled.
8265 if ($(event.target).filter(':input, option, .sort').length) {
8266 return;
8267 }
8268 $(this)
8269 .next('.everest-forms-field-option-group-inner')
8270 .stop()
8271 .slideToggle();
8272
8273 /**
8274 * If the field option group is not basic, then auto scroll to top.
8275 *
8276 * @since 3.3.0
8277 */
8278 var $el = $(this).closest('.everest-forms-field-option-group');
8279
8280 if (
8281 $el.length &&
8282 !$el.hasClass('everest-forms-field-option-group-basic')
8283 ) {
8284 var targetId = 'field-options';
8285 var dynamicLink = $('<a>', {
8286 id: 'evf-temp-link',
8287 href: '#' + targetId,
8288 });
8289
8290 dynamicLink.insertBefore($el);
8291
8292 dynamicLink[0].click();
8293
8294 setTimeout(function () {
8295 dynamicLink.remove();
8296 }, 100);
8297 }
8298 },
8299 );
8300 $(document.body)
8301 .on('init_field_options_toggle', function () {
8302 $('.everest-forms-field-option-group.closed').each(function () {
8303 $(this).find('.everest-forms-field-option-group-inner').hide();
8304 });
8305 })
8306 .trigger('init_field_options_toggle');
8307
8308 $(document).on('click', function () {
8309 $('.evf-smart-tag-lists').hide();
8310 });
8311
8312 $('.evf-smart-tag-lists').hide();
8313
8314 // Toggle Smart Tags.
8315 $(document.body).on('click', '.evf-toggle-smart-tag-display', function (e) {
8316 e.stopPropagation();
8317 $('.evf-smart-tag-lists').hide();
8318 $('.evf-smart-tag-lists ul').empty();
8319 $(this).parent().find('.evf-smart-tag-lists').toggle('show');
8320
8321 var type = $(this).data('type');
8322
8323 var allowed_field = $(this).data('fields');
8324 get_all_available_field(allowed_field, type, $(this));
8325 });
8326
8327 $(document.body).on('click', '.smart-tag-field', function (e) {
8328 var field_id = $(this).data('field_id'),
8329 field_label = $(this).text(),
8330 type = $(this).data('type'),
8331 $parent = $(this).parent().parent().parent(),
8332 $input = $parent.find('input[type=text]'),
8333 $textarea = $parent.find('textarea'),
8334 $calculationCodeMirror = $parent.find('.CodeMirror');
8335
8336 //Return when calculation smart tag is clicked because we use codeMirror
8337 if (0 != $calculationCodeMirror.length) {
8338 return;
8339 }
8340
8341 if (
8342 field_id !== 'fullname' &&
8343 field_id !== 'email' &&
8344 field_id !== 'subject' &&
8345 field_id !== 'message' &&
8346 'other' !== type
8347 ) {
8348 field_label = field_label.split(/[\s-_]/);
8349 for (var i = 0; i < field_label.length; i++) {
8350 if (i === 0) {
8351 field_label[i] =
8352 field_label[i].charAt(0).toLowerCase() + field_label[i].substr(1);
8353 } else {
8354 field_label[i] =
8355 field_label[i].charAt(0).toUpperCase() + field_label[i].substr(1);
8356 }
8357 }
8358 field_label = field_label.join('');
8359 field_id = field_label + '_' + field_id;
8360 } else {
8361 field_id = field_id;
8362 }
8363 if ('field' === type) {
8364 $input.val($input.val() + '{field_id="' + field_id + '"}');
8365 $textarea.val($textarea.val() + '{field_id="' + field_id + '"}');
8366 $textarea.trigger('change');
8367 } else if ('other' === type) {
8368 $input.val($input.val() + '{' + field_id + '}');
8369 $textarea.val($textarea.val() + '{' + field_id + '}');
8370 } else if ('regex' === type) {
8371 $input.val($input.val() + field_id.replace(field_label + '_', ''));
8372 $textarea.val($textarea.val() + field_id.replace(field_label + '_', ''));
8373 }
8374 });
8375
8376 // Toggle form status.
8377 $(document).on(
8378 'change',
8379 '.wp-list-table .everest-forms-toggle-form input',
8380 function (e) {
8381 e.stopPropagation();
8382 /**
8383 * Disable row when form is disabled.
8384 *
8385 * @since 3.2.0
8386 */
8387 if (!$(this).prop('checked')) {
8388 $(this)
8389 .closest('tr')
8390 .find('td')
8391 .not('.has-row-actions, .column-enabled')
8392 .addClass('evf-disable-row');
8393 var str = $(document)
8394 .find('.everest-forms-list-filters-row')
8395 .find('.inactive')
8396 .find('span.count')
8397 .text();
8398 var newStr = str.replace(/\((\d+)\)/, function (match, p1) {
8399 var number = parseInt(p1, 10);
8400 number += 1;
8401 return '(' + number + ')';
8402 });
8403 $(document)
8404 .find('.everest-forms-list-filters-row')
8405 .find('.inactive')
8406 .find('span.count')
8407 .text(newStr);
8408 } else {
8409 $(this)
8410 .closest('tr')
8411 .find('td')
8412 .not('.has-row-actions, .column-enabled')
8413 .removeClass('evf-disable-row');
8414 var str = $(document)
8415 .find('.everest-forms-list-filters-row')
8416 .find('.inactive')
8417 .find('span.count')
8418 .text();
8419 var newStr = str.replace(/\((\d+)\)/, function (match, p1) {
8420 var number = parseInt(p1, 10);
8421 number -= 1;
8422 return '(' + number + ')';
8423 });
8424 $(document)
8425 .find('.everest-forms-list-filters-row')
8426 .find('.inactive')
8427 .find('span.count')
8428 .text(newStr);
8429 }
8430
8431 $.post(evf_data.ajax_url, {
8432 action: 'everest_forms_enabled_form',
8433 security: evf_data.evf_enabled_form,
8434 form_id: $(this).data('form_id'),
8435 enabled: $(this).prop('checked') ? 1 : 0,
8436 });
8437 },
8438 );
8439
8440 $('.wp-list-table .everest-forms-toggle-form input').each(function () {
8441 if (!$(this).prop('checked')) {
8442 $(this)
8443 .closest('tr')
8444 .find('td')
8445 .not('.has-row-actions, .column-enabled')
8446 .addClass('evf-disable-row');
8447 } else {
8448 $(this)
8449 .closest('tr')
8450 .find('td')
8451 .not('.has-row-actions, .column-enabled')
8452 .removeClass('evf-disable-row');
8453 }
8454 });
8455
8456 // Toggle email notification.
8457 $(document).on(
8458 'change',
8459 '.evf-content-email-settings .evf-toggle-switch input',
8460 function (e) {
8461 var $this = $(this),
8462 value = $this.prop('checked'),
8463 connection_id = $this.data('connection-id');
8464 if (false === value) {
8465 $this.val('');
8466 $this
8467 .closest('.evf-content-email-settings')
8468 .find('.email-disable-message')
8469 .remove();
8470 $this
8471 .closest('.evf-content-section-title')
8472 .find('.evf-enable-email-toggle')
8473 .removeClass('everest-forms-hidden');
8474 $this
8475 .closest('.evf-content-section-title')
8476 .siblings('.evf-content-email-settings-inner')
8477 .addClass('everest-forms-hidden');
8478 $(
8479 '<p class="email-disable-message everest-forms-notice everest-forms-notice-info">' +
8480 evf_data.i18n_email_disable_message +
8481 '</p>',
8482 ).insertAfter($this.closest('.evf-content-section-title'));
8483 $('input[data-connection-id="' + connection_id + '"]').prop(
8484 'checked',
8485 false,
8486 );
8487 } else if (true === value) {
8488 $this.val('1');
8489 $this
8490 .closest('.evf-content-section-title')
8491 .siblings('.evf-content-email-settings-inner')
8492 .removeClass('everest-forms-hidden');
8493 $this
8494 .closest('.evf-content-email-settings')
8495 .find('.email-disable-message')
8496 .remove();
8497 $this
8498 .closest('.evf-content-section-title')
8499 .find('.evf-enable-email-toggle')
8500 .addClass('everest-forms-hidden');
8501 $('input[data-connection-id="' + connection_id + '"]').prop(
8502 'checked',
8503 true,
8504 );
8505 }
8506 },
8507 );
8508
8509 $(document).on('change', '.evf-email-toggle', function (e) {
8510 var $this = $(this),
8511 connection_id = $this.data('connection-id');
8512 if ($this.prop('checked')) {
8513 $this.val('1');
8514 $('.evf-content-email-settings')
8515 .find(
8516 'input[type="checkbox"][data-connection-id="' + connection_id + '"]',
8517 )
8518 .prop('checked', true)
8519 .trigger('change');
8520 } else {
8521 $this.val('');
8522 $('.evf-content-email-settings')
8523 .find(
8524 'input[type="checkbox"][data-connection-id="' + connection_id + '"]',
8525 )
8526 .prop('checked', false)
8527 .trigger('change');
8528 }
8529 });
8530
8531 $(document).on(
8532 'click',
8533 '.everest-forms-min-max-date-format input',
8534 function () {
8535 var minDate = $(this)
8536 .closest('.everest-forms-date')
8537 .find('.everest-forms-min-date')
8538 .val();
8539 var maxDate = $(this)
8540 .closest('.everest-forms-date')
8541 .find('.everest-forms-min-date')
8542 .val();
8543
8544 if ($(this).is(':checked')) {
8545 var setDateRange = $(this)
8546 .parent()
8547 .parent()
8548 .parent()
8549 .next('.everest-forms-min-max-date-range-format');
8550 if (setDateRange.find('input[type="checkbox"]').is(':checked')) {
8551 setDateRange
8552 .next('.everest-forms-min-max-date-option')
8553 .addClass('everest-forms-hidden');
8554 setDateRange
8555 .next()
8556 .next('.everest-forms-min-max-date-range-option')
8557 .removeClass('everest-forms-hidden');
8558 } else {
8559 setDateRange
8560 .next('.everest-forms-min-max-date-option')
8561 .removeClass('everest-forms-hidden');
8562 setDateRange
8563 .next()
8564 .next('.everest-forms-min-max-date-range-option')
8565 .addClass('everest-forms-hidden');
8566 }
8567
8568 $(this)
8569 .parent()
8570 .parent()
8571 .parent()
8572 .next('.everest-forms-min-max-date-range-format')
8573 .removeClass('everest-forms-hidden');
8574
8575 if ('' === minDate) {
8576 $('.everest-forms-min-date')
8577 .addClass('flatpickr-field')
8578 .flatpickr({
8579 disableMobile: true,
8580 onChange: function (selectedDates, dateStr, instance) {
8581 $('.everest-forms-min-date').val(dateStr);
8582 },
8583 onOpen: function (selectedDates, dateStr, instance) {
8584 instance.set('maxDate', $('.everest-forms-max-date').val());
8585 },
8586 });
8587 }
8588 if ('' === maxDate) {
8589 $('.everest-forms-max-date')
8590 .addClass('flatpickr-field')
8591 .flatpickr({
8592 disableMobile: true,
8593 onChange: function (selectedDates, dateStr, instance) {
8594 $('.everest-forms-max-date').val(dateStr);
8595 },
8596 onOpen: function (selectedDates, dateStr, instance) {
8597 instance.set('minDate', $('.everest-forms-min-date').val());
8598 },
8599 });
8600 }
8601 } else {
8602 $(this)
8603 .parent()
8604 .parent()
8605 .parent()
8606 .next()
8607 .next('.everest-forms-min-max-date-option')
8608 .addClass('everest-forms-hidden');
8609 $(this)
8610 .parent()
8611 .parent()
8612 .parent()
8613 .next()
8614 .next()
8615 .next('.everest-forms-min-max-date-range-option')
8616 .addClass('everest-forms-hidden');
8617 $(this)
8618 .parent()
8619 .parent()
8620 .parent()
8621 .next('.everest-forms-min-max-date-range-format')
8622 .addClass('everest-forms-hidden');
8623 }
8624 },
8625 );
8626
8627 $(document).on(
8628 'click',
8629 '.everest-forms-min-max-date-range-format input[type="checkbox"]',
8630 function () {
8631 if ($(this).is(':checked')) {
8632 $(this)
8633 .parent()
8634 .parent()
8635 .parent()
8636 .next('.everest-forms-min-max-date-option')
8637 .addClass('everest-forms-hidden');
8638 $(this)
8639 .parent()
8640 .parent()
8641 .parent()
8642 .next()
8643 .next('.everest-forms-min-max-date-range-option')
8644 .removeClass('everest-forms-hidden');
8645 } else {
8646 $(this)
8647 .parent()
8648 .parent()
8649 .parent()
8650 .next('.everest-forms-min-max-date-option')
8651 .removeClass('everest-forms-hidden');
8652 $(this)
8653 .parent()
8654 .parent()
8655 .parent()
8656 .next()
8657 .next('.everest-forms-min-max-date-range-option')
8658 .addClass('everest-forms-hidden');
8659 }
8660 },
8661 );
8662 /**
8663 * Real-time updates for Google Calendar.
8664 *
8665 * @since 2.0.6
8666 */
8667 $(document).on(
8668 'change',
8669 '.appt-sched-google-calendar-advanced',
8670 function (e) {
8671 var $this = $(this);
8672 if (!$this.is(':checked')) {
8673 $('.everest-form-appt-sched-google-event-section').addClass(
8674 'everest-forms-hidden',
8675 );
8676 } else {
8677 $('.everest-form-appt-sched-google-event-section').removeClass(
8678 'everest-forms-hidden',
8679 );
8680 }
8681 },
8682 );
8683 /**
8684 * Real-time updates the field for google calendar when we drag the new field on builder.
8685 *
8686 * @since 2.0.6
8687 */
8688 $(document).on(
8689 'focus',
8690 '.appt-sched-google-calendar-event-title-field',
8691 function (e) {
8692 var selectedItems = $('.evf-admin-field-wrapper').find(
8693 '.everest-forms-field',
8694 );
8695 appt_sched_event_title_field_list($(this), selectedItems);
8696 },
8697 );
8698 $(document).on(
8699 'focus',
8700 '.appt-sched-google-calendar-event-desc-field',
8701 function (e) {
8702 var selectedItems = $('.evf-admin-field-wrapper').find(
8703 '.everest-forms-field',
8704 );
8705 appt_sched_event_title_field_list($(this), selectedItems);
8706 },
8707 );
8708 /**
8709 * Function to updates google event title when we drag the new field on builder.
8710 *
8711 * @since 2.0.6
8712 */
8713 function appt_sched_event_title_field_list($this, selectedItems) {
8714 var html = '<option value=""> -- Select Field -- </option>';
8715 const allowedField = ['first-name', 'last-name', 'text', 'textarea'];
8716 $.each(selectedItems, function (index, element) {
8717 var fieldType = $(element).data('field-type');
8718 if (allowedField.includes(fieldType)) {
8719 var content = $(element).find('.label-title');
8720 var label = $(content).find('.text').text();
8721 var fieldName = $(element).data('field-id');
8722
8723 html += '<option value=' + fieldName + '>' + label + '</option>';
8724 }
8725 });
8726 $($this).html(html);
8727 }
8728
8729 function get_all_available_field(allowed_field, type, el) {
8730 var all_fields_without_email = [];
8731 var all_fields = [];
8732 var email_field = [];
8733 var phone_field = [];
8734 $('.evf-admin-row .evf-admin-grid .everest-forms-field').each(function () {
8735 var field_type = $(this).data('field-type');
8736 var field_id = $(this).data('field-id');
8737 if ('email' === field_type) {
8738 var e_field_label = $(this).find('.label-title span').first().text();
8739 var e_field_id = field_id;
8740 email_field[e_field_id] = e_field_label;
8741 } else if ('phone' === field_type) {
8742 var e_field_label = $(this).find('.label-title span').first().text();
8743 var e_field_id = field_id;
8744 phone_field[e_field_id] = e_field_label;
8745 } else {
8746 var field_label = $(this).find('.label-title span').first().text();
8747 all_fields_without_email[field_id] = field_label;
8748 }
8749 all_fields[field_id] = $(this).find('.label-title span').first().text();
8750 });
8751
8752 if ('other' === type || 'all' === type) {
8753 var other_smart_tags = evf_data.smart_tags_other;
8754 for (var key in other_smart_tags) {
8755 $(el)
8756 .parent()
8757 .find('.evf-smart-tag-lists .evf-others')
8758 .append(
8759 '<li class = "smart-tag-field" data-type="other" data-field_id="' +
8760 key +
8761 '">' +
8762 other_smart_tags[key] +
8763 '</li>',
8764 );
8765 }
8766 }
8767
8768 if ('regex' == type) {
8769 var regex_lists = evf_data.regex_expression_lists;
8770 regex_lists.forEach(function (key, value) {
8771 $(el)
8772 .parent()
8773 .find('.evf-smart-tag-lists .evf-regex')
8774 .append(
8775 '<li class = "smart-tag-field" data-type="regex" data-field_id="' +
8776 key.value +
8777 '">' +
8778 key.text +
8779 '</li>',
8780 );
8781 });
8782 }
8783
8784 if ('fields' === type || 'all' === type) {
8785 if (allowed_field === 'email') {
8786 if (Object.keys(email_field).length < 1) {
8787 $(el)
8788 .parent()
8789 .find(
8790 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8791 )
8792 .addClass('everest-forms-hidden');
8793 } else {
8794 $(el)
8795 .parent()
8796 .find(
8797 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8798 )
8799 .removeClass('everest-forms-hidden');
8800 }
8801 $(el).parent().find('.evf-smart-tag-lists .other-tag-title').remove();
8802 $(el).parent().find('.evf-smart-tag-lists .evf-others').remove();
8803 $(el)
8804 .parent()
8805 .find('.evf-smart-tag-lists')
8806 .append(
8807 '<div class="smart-tag-title other-tag-title">Others</div><ul class="evf-others"></ul>',
8808 );
8809 $(el)
8810 .parent()
8811 .find('.evf-smart-tag-lists .evf-others')
8812 .append(
8813 '<li class="smart-tag-field" data-type="other" data-field_id="admin_email">Site Admin Email</li><li class="smart-tag-field" data-type="other" data-field_id="user_email">User Email</li>',
8814 );
8815 for (var key in email_field) {
8816 $(el)
8817 .parent()
8818 .find('.evf-smart-tag-lists .evf-fields')
8819 .append(
8820 '<li class = "smart-tag-field" data-type="field" data-field_id="' +
8821 key +
8822 '">' +
8823 email_field[key] +
8824 '</li>',
8825 );
8826 }
8827 } else if (allowed_field === 'phone') {
8828 if (Object.keys(phone_field).length < 1) {
8829 $(el)
8830 .parent()
8831 .find(
8832 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8833 )
8834 .addClass('everest-forms-hidden');
8835 } else {
8836 $(el)
8837 .parent()
8838 .find(
8839 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8840 )
8841 .removeClass('everest-forms-hidden');
8842 }
8843 $(el).parent().find('.evf-smart-tag-lists .other-tag-title').remove();
8844 $(el).parent().find('.evf-smart-tag-lists .evf-others').remove();
8845 for (var key in phone_field) {
8846 $(el)
8847 .parent()
8848 .find('.evf-smart-tag-lists .evf-fields')
8849 .append(
8850 '<li class = "smart-tag-field" data-type="field" data-field_id="' +
8851 key +
8852 '">' +
8853 phone_field[key] +
8854 '</li>',
8855 );
8856 }
8857 } else {
8858 if (Object.keys(all_fields).length < 1) {
8859 $(el)
8860 .parent()
8861 .find(
8862 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8863 )
8864 .addClass('everest-forms-hidden');
8865 } else {
8866 $(el)
8867 .parent()
8868 .find(
8869 '.evf-smart-tag-lists .smart-tag-title:not(".other-tag-title")',
8870 )
8871 .removeClass('everest-forms-hidden');
8872 }
8873 for (var meta in all_fields) {
8874 $(el)
8875 .parent()
8876 .find('.evf-smart-tag-lists .evf-fields')
8877 .append(
8878 '<li class = "smart-tag-field" data-type="field" data-field_id="' +
8879 meta +
8880 '">' +
8881 all_fields[meta] +
8882 '</li>',
8883 );
8884 }
8885 }
8886 }
8887
8888 if ('calculations' === type) {
8889 var calculations = [
8890 'number',
8891 'payment-single',
8892 'range-slider',
8893 'payment-checkbox',
8894 'payment-multiple',
8895 'select',
8896 'payment-total',
8897 'radio',
8898 'first-name',
8899 'text',
8900 'last-name',
8901 'email',
8902 'url',
8903 ];
8904 $(document)
8905 .find('.everest-forms-field')
8906 .each(function () {
8907 $fieldId = $(this).attr('data-field-id').split('-');
8908 if (
8909 calculations.includes($(this).attr('data-field-type')) &&
8910 $(el)
8911 .parents('.everest-forms-field-option-row-calculation_field')
8912 .attr('data-field-id') !== $(this).attr('data-field-id')
8913 ) {
8914 $(el)
8915 .parent()
8916 .find('.evf-smart-tag-lists .calculations')
8917 .append(
8918 '<li class = "smart-tag-field" data-type="field" data-field_id="' +
8919 $fieldId[1] +
8920 '">' +
8921 $(this).find('.label-title .text').text() +
8922 '</li>',
8923 );
8924 }
8925 });
8926 }
8927
8928 if ('ai-fields' === type) {
8929 var aiFields = ['text', 'select', 'radio'];
8930 $(document)
8931 .find('.everest-forms-field')
8932 .each(function () {
8933 if (
8934 aiFields.includes($(this).attr('data-field-type')) &&
8935 $(el)
8936 .parents('.everest-forms-field-option-row-ai_chatbot_input')
8937 .attr('data-field-id') !== $(this).attr('data-field-id')
8938 ) {
8939 $(el)
8940 .parent()
8941 .find('.evf-smart-tag-lists .evf-fields-ai')
8942 .append(
8943 '<li class = "smart-tag-field" data-type="field" data-field_id="' +
8944 $(this).attr('data-field-id') +
8945 '">' +
8946 $(this).find('.label-title .text').text() +
8947 '</li>',
8948 );
8949 }
8950 });
8951 }
8952 }
8953 });
8954
8955 jQuery(function ($) {
8956 $(document).ready(function () {
8957
8958 // Add "Add Field Below" button to repeater field.
8959 var observer = new MutationObserver(function (mutations) {
8960 mutations.forEach(function (mutation) {
8961 $(mutation.addedNodes).each(function () {
8962 if ($(this).hasClass('everest-forms-field')) {
8963 if (!$(this).find('.evf-add-field-below').length) {
8964 $(this).append(
8965 '<div class="evf-add-field-below">' +
8966 '<span class="dashicons dashicons-plus" title="Add Field Below"></span>' +
8967 '</div>'
8968 );
8969 }
8970 }
8971 });
8972 });
8973 });
8974
8975 observer.observe(document.body, {
8976 childList: true,
8977 subtree: true
8978 });
8979
8980 // Custom CSS
8981 const customCssElement = $(
8982 '#everest-forms-panel-field-settings-evf-custom-css',
8983 );
8984 if (customCssElement.length && typeof wp.CodeMirror !== 'undefined') {
8985 var cssEditor = wp.CodeMirror.fromTextArea(customCssElement[0], {
8986 indentUnit: 2,
8987 indentWithTabs: true,
8988 inputStyle: 'contenteditable',
8989 lineNumbers: true,
8990 lineWrapping: true,
8991 styleActiveLine: true,
8992 continueComments: true,
8993 extraKeys: {
8994 'Ctrl-Space': 'autocomplete',
8995 'Ctrl-/': 'toggleComment',
8996 'Cmd-/': 'toggleComment',
8997 'Alt-F': 'findPersistent',
8998 'Ctrl-F': 'findPersistent',
8999 'Cmd-F': 'findPersistent',
9000 },
9001 direction: 'ltr',
9002 gutters: [],
9003 mode: 'text/css',
9004 lint: false,
9005 autoCloseBrackets: true,
9006 autoCloseTags: true,
9007 autoRefresh: true,
9008 matchTags: {
9009 bothTags: true,
9010 },
9011 tabSize: 2,
9012 theme: 'default',
9013 });
9014
9015 cssEditor.on('change', function () {
9016 customCssElement.html(
9017 cssEditor
9018 .getValue()
9019 .replace(/<\s*script/gi, '')
9020 .replace(/\s+on\w+\s*=/gi, ' '),
9021 );
9022 });
9023 }
9024
9025 // Custom JS
9026 const customJsElement = $(
9027 '#everest-forms-panel-field-settings-evf-custom-js',
9028 );
9029 if (customJsElement.length && typeof wp.CodeMirror !== 'undefined') {
9030 var jsEditor = wp.CodeMirror.fromTextArea(customJsElement[0], {
9031 indentUnit: 2,
9032 indentWithTabs: true,
9033 inputStyle: 'contenteditable',
9034 lineNumbers: true,
9035 lineWrapping: true,
9036 styleActiveLine: true,
9037 continueComments: true,
9038 extraKeys: {
9039 'Ctrl-Space': 'autocomplete',
9040 'Ctrl-/': 'toggleComment',
9041 'Cmd-/': 'toggleComment',
9042 'Alt-F': 'findPersistent',
9043 'Ctrl-F': 'findPersistent',
9044 'Cmd-F': 'findPersistent',
9045 },
9046 direction: 'ltr',
9047 gutters: [],
9048 mode: 'javascript',
9049 lint: false,
9050 autoCloseBrackets: true,
9051 autoCloseTags: true,
9052 autoRefresh: true,
9053 matchTags: {
9054 bothTags: true,
9055 },
9056 tabSize: 2,
9057 });
9058
9059 jsEditor.on('change', function () {
9060 customJsElement.html(
9061 jsEditor
9062 .getValue()
9063 .replace(/<\s*script/gi, '')
9064 .replace(/\s+on\w+\s*=/gi, ' '),
9065 );
9066 });
9067 }
9068
9069 $(
9070 '#everest-forms-panel-field-settings-evf-enable-custom-css, #everest-forms-panel-field-settings-evf-enable-custom-js',
9071 ).on('change', (e) => {
9072 showHideEditors();
9073 });
9074
9075 showHideEditors();
9076
9077 // Show/Hide the custom CSS and JS input boxes based on the enabled/disabled state.
9078 function showHideEditors() {
9079 if (
9080 $('#everest-forms-panel-field-settings-evf-enable-custom-css').is(
9081 ':checked',
9082 )
9083 ) {
9084 $('#everest-forms-panel-field-settings-evf-custom-css-wrap').show(500);
9085 } else {
9086 $('#everest-forms-panel-field-settings-evf-custom-css-wrap').hide(500);
9087 }
9088
9089 if (
9090 $('#everest-forms-panel-field-settings-evf-enable-custom-js').is(
9091 ':checked',
9092 )
9093 ) {
9094 $('#everest-forms-panel-field-settings-evf-custom-js-wrap').show(500);
9095 } else {
9096 $('#everest-forms-panel-field-settings-evf-custom-js-wrap').hide(500);
9097 }
9098 }
9099 });
9100 });
9101