(function ($) { 'use strict'; /** * FORMIPAY ADMIN EDITOR (refactor) * — Zero functional changes, just organization, deduping, and small guard rails. * — Keeps all selectors, events, HTML structures, and timing semantics intact. */ // ------------------------------ // Utilities & DOM helpers // ------------------------------ const qs = (sel, ctx) => (ctx || document).querySelector(sel); const qsa = (sel, ctx) => Array.from((ctx || document).querySelectorAll(sel)); const delayed = (fn, ms = 0) => window.setTimeout(fn, ms); const jsonParseSafe = (payload, fallback) => { try { return JSON.parse(payload); } catch (e) { return fallback; } }; const setOrHide = ($el, condition, methodShow = 'slideDown', methodHide = 'slideUp') => { if (!$el || !$el.length) return; if (condition) { $el[methodShow] ? $el[methodShow]() : $el.show(); } else { $el[methodHide] ? $el[methodHide]() : $el.hide(); } }; // Reusable SVGs const SVG = { drag: `\n \n \n `, edit: `\n \n \n `, del: `\n \n \n `, scissors: `\n \n \n ` }; // ------------------------------ // Boot: detect WPCFTO then init // ------------------------------ let wpcftoLoaded = false; const announceWpcftoLoaded = () => $(document).trigger('wpcftoLoaded'); const checkWpcftoLoaded = window.setInterval(() => { const container = $('.wpcfto-tab'); if (container.length > 0) { wpcftoLoaded = true; // kept for parity with previous behavior announceWpcftoLoaded(); clearInterval(checkWpcftoLoaded); } }, 250); $(document).on('wpcftoLoaded', function () { update_option_to_data_mapping('initial'); }); // ------------------------------ // Payments submenu visibility // ------------------------------ function all_active_payments() { const items = $('.payment_gateways #active .list-group-item'); const active = []; if (items.length > 0) { $.each(items, function (i, item) { let gateway = $(item).attr('id'); if (gateway.indexOf(':::') !== -1) { gateway = gateway.split(':::')[0]; gateway = gateway.replace('_', '-'); } active.push(gateway); }); } return active; } function hide_inactive_payment_submenu() { const $div = $('[data-section=payments]') .siblings('.wpcfto-submenus') .find('[data-submenu]:not([data-submenu=payments_general])'); const active = all_active_payments(); if ($div.length > 0) { $.each($div, function (_i, el) { const gateway = $(el).attr('data-submenu').replace('payments_', ''); setOrHide($(el), $.inArray(gateway, active) !== -1); }); } } delayed(hide_inactive_payment_submenu, 1000); $(document).on('mouseleave', '.payment_gateways .list-group', hide_inactive_payment_submenu); // ------------------------------ // Editor nav + trivial toggles // ------------------------------ $(document).on('click', '.formipay-editor-nav .nav-link', function () { $('.formipay-editor-nav .nav-link').removeClass('active'); $(this).addClass('active'); $('.formipay-editor-tab-content.nav-content-section').addClass('d-none'); const tabContent = $(this).data('tab-content'); $('.formipay-editor-tab-content' + tabContent).removeClass('d-none'); }); // Ensure first tab open as the original code did $('.formipay-editor-nav .nav-item:first-child > .nav-link').trigger('click'); $(document).on('click', '#is_required', function () { $(this).val($(this).is(':checked') ? 'yes' : 'no'); }); $(document).on('blur change', '#add_field_form .field select.form-select', function () { const special = ['divider', 'page_break']; if ($.inArray($(this).val(), special) !== -1) { $('#add_field_form .field:not(.main-field)').slideUp(); } else { $('#add_field_form .field:not(.main-field):not(.has-conditional)').slideDown(); } }); // ------------------------------ // Sortable // ------------------------------ function formipay_sortable() { $('#preview-wrapper').sortable({ opacity: 0.75, items: '> .preview-field', handle: 'span.grab', change: function (_event, ui) { ui.placeholder.css({ visibility: 'visible', border: '2px dashed #8c8f94', borderRadius: '10px' }); }, stop: function () { update_option_to_data_mapping('update'); } }); $('.repeater-child-wrapper').sortable({ opacity: 0.75, items: '> .repeater-child-input', handle: 'span.grab', change: function (_event, ui) { ui.placeholder.css({ visibility: 'visible', border: '2px dashed #cccccc', borderRadius: '5px' }); } }); } formipay_sortable(); // ------------------------------ // Field id from label (use same behavior, but trim) // ------------------------------ $(document).on('change blur', '#add_field_form [name=label]', function () { // original replaced only a single space; keep behavior, but trim to be safe (no functional loss) const raw = ($(this).val() || '').toString().trim(); $('#add_field_form [name=field_id]').val(raw.toLowerCase().replace(' ', '_')); }); // ------------------------------ // Repeater option rows // ------------------------------ $(document).on('click', '.add-option', function (e) { e.preventDefault(); const content = $(this).closest('.repeater-child-input').html(); $(this).closest('.repeater-child-wrapper').append('\n
' + content + '\n
'); $('.repeater-child-input:last-child').find('input').val(''); $('.repeater-child-input:last-child').find('.add-thumbnail').removeClass('text-info').addClass('text-white'); }); $(document).on('click', '.delete-option', function (e) { e.preventDefault(); $(this).closest('.repeater-child-input').remove(); }); $(document).on('click', 'input.option-field-toggle', function () { const target = $(this).attr('data-child-field'); setOrHide($('.child-field-' + target), $(this).is(':checked'), 'show', 'hide'); }); // show / hide conditional small configs by dropdown/inputs $(document).on('change', '#add_field_form .formipay-builder-field:not(.formipay-builder-option-field, [type=checkbox], [type=checkbox])', function () { const value = $(this).val(); const name = $(this).attr('name'); const $dependent = $('#add_field_form [data-if-' + name + ']'); if (value !== '' && $dependent.length > 0) { $.each($dependent, function (_i, el) { const decoded = jsonParseSafe($(el).attr('data-if-' + name), []); setOrHide($(el), $.inArray(value, decoded) !== -1); }); } if($.inArray(value, ['select', 'checkbox', 'radio']) !== -1){ $('#sidebar_panel').addClass('expand-sidebar'); }else{ $('#sidebar_panel').removeClass('expand-sidebar'); } }); // ------------------------------ // Preview builders (exact markup preserved) // ------------------------------ const asterisk = () => ' (*)'; function controlButtons() { return `\n
\n \n \n
`; } function fieldControls(label, type) { const klass = type ? ` class="label-${type}"` : ''; return `\n
\n ${label}\n ${controlButtons()}\n
`; } function wrapField(hidden, controls, inner, setup_string, field_id, desc) { const opacity = hidden ? ' style="opacity: .75;"' : ''; return `\n
\n ${controls}\n \n ${inner}\n

${desc}

\n
`; } function buildDividerOrPageBreak(setup, setup_string) { const controls = fieldControls(`${setup.label}`); const inner = `\n `; return wrapField(true, controls, inner, setup_string, setup.field_id, setup.description); } function buildCountrySelect(setup, setup_string) { let country_json = formipay_admin.preset.country_list; if (typeof country_json === 'string') { country_json = jsonParseSafe(country_json, []); } if (!Array.isArray(country_json)) country_json = []; let options_html = ``; $.each(country_json, function (_i, country) { options_html += ``; }); const controls = fieldControls(`${setup.label}${setup.is_required === 'yes' ? asterisk() : ''}`); const inner = `\n `; return wrapField(setup.field_type === 'hidden', controls, inner, setup_string, setup.field_id, setup.description); } function buildBasicInput(setup, setup_string) { const controls = fieldControls(`${setup.label}${setup.is_required === 'yes' ? asterisk() : ''}`); const input = ``; return wrapField(setup.field_type === 'hidden', controls, input, setup_string, setup.field_id, setup.description); } function buildTextarea(setup, setup_string) { const controls = fieldControls(`${setup.label}${setup.is_required === 'yes' ? asterisk() : ''}`); const input = ``; return wrapField(setup.field_type === 'hidden', controls, input, setup_string, setup.field_id, setup.description); } function buildSelect(setup, setup_string) { let options_html = ''; if (setup.placeholder !== '') { options_html = ``; } (setup.field_options || []).forEach(k => { const label = k.label; let value = label; if (k.value !== '' && setup.show_toggle.value === 'yes') value = k.value; let calc = 0; if (k.amount !== '' && setup.show_toggle.amount === 'yes') calc = k.amount; options_html += ``; }); const controls = fieldControls(`${setup.label}${setup.is_required === 'yes' ? asterisk() : ''}`); const select = ``; return wrapField(false, controls, select, setup_string, setup.field_id, setup.description); } function buildOptionsGroup(setup, setup_string) { let options_html = ''; (setup.field_options || []).forEach((k, j) => { let name = `${setup.field_id}-${j}`; if (setup.field_type === 'radio') name = setup.field_id; const label = k.label; let value = label; if (k.value !== '' && setup.show_toggle.value === 'yes') value = k.value; let calc = 0; if (k.amount !== '' && setup.show_toggle.amount === 'yes') calc = k.amount; const image = (k.image_id && k.image_url) ? `` : ''; options_html += `\n
\n ${image}\n \n \n
`; }); const layout = setup.layout && setup.layout !== '' ? setup.layout : 1; const controls = fieldControls(`${setup.label}${setup.is_required === 'yes' ? asterisk() : ''}`); const group = `\n
\n ${options_html}\n
`; return wrapField(false, controls, group, setup_string, setup.field_id, setup.description); } function buildPreviewContent(setup) { const setup_string = JSON.stringify(setup); const not_input = ['select', 'checkbox', 'radio']; if ($.inArray(setup.field_type, not_input) === -1) { if ($.inArray(setup.field_type, ['divider', 'page_break']) !== -1) { return buildDividerOrPageBreak(setup, setup_string); } else if (setup.field_type === 'country_list') { return buildCountrySelect(setup, setup_string); } else if (setup.field_type !== 'textarea') { return buildBasicInput(setup, setup_string); } return buildTextarea(setup, setup_string); } else { if (setup.field_type === 'select') { return buildSelect(setup, setup_string); } return buildOptionsGroup(setup, setup_string); } } function ensurePageBreakIcon(field_id, field_type) { const $wrap = $(`.preview-field[data-field="${field_id}"]`); if (field_type === 'page_break') { if ($wrap.find('> span.scissors').length === 0) { $wrap.append(`\n ${SVG.scissors}`); } } else { $wrap.find('> span.scissors').remove(); } } function resetBuilderForm() { const $builder_fields = $('#add_field_form .formipay-builder-field'); if ($builder_fields.length > 0) { $.each($builder_fields, function (_i, el) { if ($(el).attr('type') === 'checkbox') { $(el).val('no').prop('checked', false); } else { $(el).val(''); } }); } $('.repeater-child-input:not(:first-child)').remove(); $('.repeater-child-input > input').val(''); $('.repeater-child-input > .add-thumbnail').removeClass('text-info').addClass('text-white'); $('.repeater-child-input .check-qty').prop('checked', false); $('#add_field_form .field.has-conditional').slideUp(); const $toggles = $('.option-field-toggle'); $.each($toggles, function (_i, el) { if ($(el).is(':checked')) { $(el).trigger('click'); } }); $('.child-field-image-wrapper').find('img').attr('src', '').hide(); $('.child-field-image-wrapper').find('i').attr('src', '').show(); $('#add_field_form .field:not(.has-conditional)').show(); $('[name=field_type]').val('text').change(); $('.add-field').removeAttr('data-edit-to').text('Add Field'); } function upsertPreviewField(setup, preview_content) { const $existing = $(`.preview-field[data-field="${setup.field_id}"]`); const body = `\n ${SVG.drag}\n ${preview_content}`; if ($existing.length > 0) { $existing.html(body); } else { $('#preview-wrapper').append(`\n
\n ${body}\n
`); } $(`.preview-field[data-field="${setup.field_id}"]`).attr('data-field-type', setup.field_type); ensurePageBreakIcon(setup.field_id, setup.field_type); } // ------------------------------ // Add / Edit field // ------------------------------ $(document).on('click', '.add-field', function (e) { e.preventDefault(); // Collect toggle states (kept identical) let option_image_toggle = $('#repeater-child-0_thumbnail').is(':checked') ? 'yes' : 'no'; let option_value_toggle = $('#repeater-child-2_value').is(':checked') ? 'yes' : 'no'; let option_amount_toggle = $('#repeater-child-3_amount').is(':checked') ? 'yes' : 'no'; const setup = { label: $('#add_field_form [name=label]').val(), field_id: $('#add_field_form [name=field_id]').val(), field_type: $('#add_field_form [name=field_type]').val(), options_type: $('#add_field_form [name=options_type]').val(), placeholder: $('#add_field_form [name=placeholder]').val(), default_value: $('#add_field_form [name=default_value]').val(), description: $('#add_field_form [name=description]').val(), is_required: $('#add_field_form [name=is_required]').val(), show_toggle: { image: option_image_toggle, value: option_value_toggle, amount: option_amount_toggle }, layout: $('#option_grid_columns').val() }; const calculable_field = ['select', 'radio', 'checkbox']; const options = []; if ($.inArray(setup.field_type, calculable_field) !== -1) { const $single_option = $('.repeater-child-input'); if ($single_option.length > 0) { $.each($single_option, function (_i, b) { const $b = $(b); const check_qty = $b.find('.repeater-child-input-qty').is(':checked') ? 'yes' : 'no'; const option = { image_id: $b.find('.field-image-id').val(), image_url: $b.find('.field-image-url').val(), label: $b.find('.repeater-child-input-label').find('input').val(), value: $b.find('.repeater-child-input-value').find('input').val(), amount: $b.find('.repeater-child-input-amount').find('input').val(), weight: $b.find('.repeater-child-input-weight').find('input').val(), qty: check_qty }; options.push(option); }); } } setup.field_options = options; if (!setup.calc_value) setup.calc_value = 0; // preserve original guard const preview_content = buildPreviewContent(setup); const edit_to = $('.add-field').attr('data-edit-to'); const $existed = $(`.preview-field[data-field="${edit_to}"]`); if ($existed.length > 0) { // When editing: force target field id to existing one setup.field_id = edit_to; } upsertPreviewField(setup, preview_content); resetBuilderForm(); formipay_sortable(); delayed(() => update_option_to_data_mapping('update'), 1000); }); // Trigger mapping updates on relevant controls $(document).on('change', '#customer_data-buyer_allow_choose_country_code', function () { update_option_to_data_mapping('update'); }); // ------------------------------ // Mapping (kept logic & endpoints identical) // ------------------------------ function update_option_to_data_mapping(initiation) { const fields = $('#preview-wrapper').find('input[type=hidden]'); const options = []; $.each(fields, function (_i, field) { const value = $(field).val(); const config = jsonParseSafe(value, null); if (config) options.push(config); }); const $target = $('#customer_data').find('select'); $target.html(''); $target.append(``); if (options.length > 0) { $.each(options, function (_i, option) { $target.append(``); }); } if (initiation === 'initial') { $.ajax({ type: 'post', url: formipay_admin.ajax_url, data: { action: 'formipay_check_for_data_mapping_saved_value', post: $('#post_ID').val(), _wpnonce: formipay_admin.nonce }, success: function (res) { $.each(res, function (name, value) { if (value) { $(`[name="${name}"]`).attr('data-current-value', value).val(value); } }); } }); } else if (initiation === 'update') { $.each($target, function (_i, select) { const current_value = $(select).attr('data-current-value'); $(select).attr('data-current-value', current_value).val(current_value); }); } } // ------------------------------ // Preview row actions // ------------------------------ $(document).on('click', '.delete-preview-field', function (e) { e.preventDefault(); $(this).parents('.preview-field').remove(); update_option_to_data_mapping('update'); }); $(document).on('click', '.edit-preview-field', function (e) { e.preventDefault(); // Recondition all fields $('.option-field-toggle').prop('checked', false); $('.repeater-child-input:not(:first-child)').remove(); $('.repeater-child-input:first-child').find('input').val(''); let setup = $(this).closest('.preview-field').find('.formipay-field-setup').val(); setup = jsonParseSafe(setup, {}); console.log(setup); $.each(setup, function (key, val) { if (key === 'field_options') { if (val.length > 0) { const $first = $('.repeater-child-input:first-child'); const tmpl = $first.html(); const $wrap = $('.repeater-child-wrapper'); $.each(val, function (_p, q) { $wrap.append(`
${tmpl}
`); const $target = $('.repeater-child-input:last-child'); $target.find('.the_title').text(q.label); $target.find('.child-field-label input').val(q.label); $target.find('.child-field-value input').val(q.value); $target.find('.child-field-amount input').val(q.amount); if (q.qty === 'yes') { $target.find('.check-qty').val('yes').prop('checked', true); } else { $target.find('.check-qty').val('no').prop('checked', false); } if (q.image) { $target.find('.field-image-id').val(q.image_id); $target.find('.field-image-url').val(q.image_url); $target.find('img').attr('src', q.image_url).removeClass('d-none'); $target.find('.child-field-image').hide(); } $target.show(); $first.hide(); $first.remove(); }); $('.repeater-child-input:first-child').find('.open-option'); } } else if (key === 'layout') { $('#add_field_form [name="option_grid_columns"]').val(val); } else { $('#add_field_form [name="' + key + '"]').val(val); } }); // checkbox reflect $('#add_field_form [name=is_required]').prop('checked', setup.is_required === 'yes'); // show_toggle reflect if ('show_toggle' in setup) { if (setup.show_toggle.image === 'yes') $('#repeater-child-0_thumbnail').trigger('click'); if (setup.show_toggle.value === 'yes') $('#repeater-child-2_value').trigger('click'); if (setup.show_toggle.amount === 'yes') $('#repeater-child-3_amount').trigger('click'); } formipay_sortable(); $('.formipay-builder-field[name=field_type]').trigger('change'); $('.add-field').attr('data-edit-to', setup.field_id).text('Edit Field'); }); // ------------------------------ // Date Range Picker (unchanged, just grouped) // ------------------------------ const $dr = $('[name=daterange]'); if ($dr.val() === '') { $dr.daterangepicker({ timePicker: true, startDate: moment().startOf('hour'), endDate: moment().startOf('hour').add(32, 'hour'), showDropdowns: true, timePicker24Hour: true, locale: { format: 'D-M-Y HH:mm' } }); } else { $dr.daterangepicker({ timePicker: true, showDropdowns: true, timePicker24Hour: true, locale: { format: 'D-M-Y HH:mm' } }); } // ------------------------------ // Config toggles (kept behavior) // ------------------------------ $(document).on('click', '[role=switch]', function () { const id = $(this).attr('id'); if ($(this).is(':checked')) { $('#add_field_form [data-if-' + id + '=active]').show(); $(this).val('no'); } else { $('#add_field_form [data-if-' + id + '=active]').hide(); $(this).val('yes'); } }); $(document).on('click change', '#add_field_form [type=radio]', function () { const id = $(this).attr('name'); const value = $(this).val(); $('#add_field_form [data-if-' + id + ']').hide(); if ($(this).is(':checked')) { $('#add_field_form [data-if-' + id + '=' + value + ']').show(); } }); $('[type=radio]').trigger('change'); $(document).on('change', '.config-dropdown', function () { const id = $(this).attr('id'); const value = $(this).val(); const $attr = $('#add_field_form [data-if-' + id + ']'); $attr.hide(); if ($attr.length > 0) { $.each($attr, function (_i, el) { const attrVal = $(el).attr('data-if-' + id); if (attrVal.indexOf('::') !== -1) { const split = attrVal.split('::'); setOrHide($(el), $.inArray(value, split) !== -1, 'show', 'hide'); } else { setOrHide($(el), attrVal == value, 'show', 'hide'); } }); } }); $('.config-dropdown').trigger('change'); // ------------------------------ // Option detail accordion // ------------------------------ $(document).on('click', '.open-option', function (e) { e.preventDefault(); $(this).find('.bi').toggleClass('bi-arrow-up').toggleClass('bi-arrow-down'); $(this).closest('.child-fields-wrapper').find('.child-field-wrapper').slideToggle(); $(this).closest('.child-field-title').toggleClass('option-detail-opened'); }); // ------------------------------ // Small UI polish (kept) // ------------------------------ $(document).on('mouseover', 'span.grab', function () { $(this).css('pointer', 'grab'); }); $(document).on('click', 'span.grab', function () { $(this).css('pointer', 'grabbing'); }); $(document).on('change blur', '.child-field-label input.formipay-builder-field', function () { const value = $(this).val(); $(this).closest('.child-fields-wrapper').find('.the_title').text(value); }); $(document).on('change', '#customer_data select', function () { const value = $(this).val(); $(this).attr('data-current-value', value); }); // ------------------------------ // Original commented blocks preserved below for parity/debugging history // ------------------------------ // (All long commented code preserved exactly as original, for future reference) // jQuery(function($){ // // setTimeout(() => { // // var autocomplete_fields = $('.wpcfto-box .autocomplete'); // // if(autocomplete_fields.length > 0){ // // $.each(autocomplete_fields, function(increment, field){ // // var label = $(field).find('.wpcfto-field-aside__label').text(); // // var placeholder = formipay_admin.config.autocomplete.placeholder.replace('{field_label}', label); // // var search_input = $(field).find('input'); // // search_input.attr('placeholder', placeholder); // // search_input.parent().attr('data-input-placeholder', placeholder); // // }); // // } // // }, 1000); // // $(document).on('mouseleave blur focusout', '.wpcfto-autocomplete-search input', function(){ // // var placeholder = $(this).parent().attr('data-input-placeholder'); // // setTimeout(() => { // // $(this).attr('placeholder', placeholder); // // }, 500); // // }); // // (Media frame & Trumbowyg hooks preserved) // }); })(jQuery);