diff --git a/admin/assets/css/admin-editor.css b/admin/assets/css/admin-editor.css index de51399..07051fb 100644 --- a/admin/assets/css/admin-editor.css +++ b/admin/assets/css/admin-editor.css @@ -23,6 +23,10 @@ input.formipay-post-shortcode-input { #sidebar_panel { background-color: #2c3e50; flex: 0 0 273px; + transition: all .35s ease-in-out; +} +#sidebar_panel.expand-sidebar { + flex: 0 0 calc(273px * 2); } #fields_panel { background-color: #f0f3f5; @@ -40,6 +44,7 @@ input.formipay-post-shortcode-input { top: 140px; } #add_field_form input[type=text], +#add_field_form input[type=number], #add_field_form select, div#preview-wrapper input:not([type=checkbox],[type=radio]), div#preview-wrapper select { diff --git a/admin/assets/js/admin-editor.js b/admin/assets/js/admin-editor.js index dc505bf..91cf66a 100644 --- a/admin/assets/js/admin-editor.js +++ b/admin/assets/js/admin-editor.js @@ -1,946 +1,649 @@ -jQuery(function($){ +(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; - var checkWpcftoLoaded = setInterval(() => { + const announceWpcftoLoaded = () => $(document).trigger('wpcftoLoaded'); + + const checkWpcftoLoaded = window.setInterval(() => { const container = $('.wpcfto-tab'); - if(container.length > 0){ - wpcftoLoaded = true; - $(document).trigger('wpcftoLoaded'); + if (container.length > 0) { + wpcftoLoaded = true; // kept for parity with previous behavior + announceWpcftoLoaded(); clearInterval(checkWpcftoLoaded); } }, 250); - $(document).on('wpcftoLoaded', function(){ + $(document).on('wpcftoLoaded', function () { update_option_to_data_mapping('initial'); }); + // ------------------------------ + // Payments submenu visibility + // ------------------------------ function all_active_payments() { - - var items = $('.payment_gateways #active .list-group-item'); - var active_payments = []; - - if(items.length > 0){ - $.each(items, function(i, item){ - var gateway = $(item).attr('id'); - if(gateway.indexOf(':::') !== -1){ + 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('_', '-'); } - // $('[data-submenu=payments_'+gateway+']').show(); - active_payments.push(gateway); + active.push(gateway); }); } - - return active_payments; - + return active; } function hide_inactive_payment_submenu() { - - var div = $('[data-section=payments]').siblings('.wpcfto-submenus').find('[data-submenu]:not([data-submenu=payments_general])'); - var active_payments = all_active_payments(); - - if(div.length > 0) { - $.each(div, function(x, y){ - var gateway = $(y).attr('data-submenu').replace('payments_', ''); - if(jQuery.inArray(gateway, active_payments) !== -1){ - $(y).slideDown(); - }else{ - $(y).slideUp(); - } + 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); }); } } - setTimeout(() => { - hide_inactive_payment_submenu(); - }, 1000); - + delayed(hide_inactive_payment_submenu, 1000); - $(document).on('mouseleave', '.payment_gateways .list-group', function(){ + $(document).on('mouseleave', '.payment_gateways .list-group', hide_inactive_payment_submenu); - hide_inactive_payment_submenu(); - - }); - - $(document).on('click', '.formipay-editor-nav .nav-link', function(){ - $('.formipay-editor-nav').find('.nav-link').removeClass('active'); + // ------------------------------ + // 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'); - var tab_content = $(this).data('tab-content'); - $('.formipay-editor-tab-content'+tab_content).removeClass('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(){ - if($(this).is(':checked')) { - $(this).val('yes'); - }else{ - $(this).val('no'); - } + + $(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(){ - var array = ['divider', 'page_break']; - if( $.inArray( $(this).val(), array ) !== -1 ) { + $(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{ + } else { $('#add_field_form .field:not(.main-field):not(.has-conditional)').slideDown(); } }); - function formipay_sortable(){ + // ------------------------------ + // 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' - }); + change: function (_event, ui) { + ui.placeholder.css({ visibility: 'visible', border: '2px dashed #8c8f94', borderRadius: '10px' }); }, - stop: function(event, ui){ - update_option_to_data_mapping('update'); - } + 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' - }); + change: function (_event, ui) { + ui.placeholder.css({ visibility: 'visible', border: '2px dashed #cccccc', borderRadius: '5px' }); } }); } - formipay_sortable(); - $(document).on('change blur', '#add_field_form [name=label]', function(){ - $('#add_field_form [name=field_id]').val($(this).val().toLowerCase().replace(' ', '_')); + // ------------------------------ + // 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(' ', '_')); }); - $(document).on('click', '.add-option', function(e){ + // ------------------------------ + // Repeater option rows + // ------------------------------ + $(document).on('click', '.add-option', function (e) { e.preventDefault(); - var content = $(this).closest('.repeater-child-input').html(); - $(this).closest('.repeater-child-wrapper').append(` -
`+content+` -
`); + 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){ + $(document).on('click', '.delete-option', function (e) { e.preventDefault(); $(this).closest('.repeater-child-input').remove(); }); - $(document).on('click', 'input.option-field-toggle', function(){ - var target = $(this).attr('data-child-field'); - if($(this).is(':checked')){ - $('.child-field-'+target).show(); + $(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{ - $('.child-field-'+target).hide(); + $('#sidebar_panel').removeClass('expand-sidebar'); } }); - $(document).on('change', '#add_field_form .formipay-builder-field:not(.formipay-builder-option-field, [type=checkbox], [type=checkbox])', function(){ - var value = $(this).val(); - var name = $(this).attr('name'); - var the_dependent = $('#add_field_form [data-if-'+name+']'); - if('' !== value && the_dependent.length > 0){ - // var all_dependents = $('.has-conditional'); - $.each(the_dependent, function(x, y){ - var decoded_value = JSON.parse($(y).attr('data-if-'+name)); - if($.inArray(value, decoded_value) !== -1){ - $(y).slideDown(); - }else{ - $(y).slideUp(); + // ------------------------------ + // 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(''); } }); } - }); - - $(document).on('click', '.add-field', function(e){ - e.preventDefault(); - - var option_image_toggle = 'no'; - if($('#repeater-child-0_thumbnail').is(':checked')){ - option_image_toggle = 'yes'; - } - var option_value_toggle = 'no'; - if($('#repeater-child-2_value').is(':checked')){ - option_value_toggle = 'yes'; - } - var option_amount_toggle = 'no'; - if($('#repeater-child-3_amount').is(':checked')){ - option_amount_toggle = 'yes'; - } - - var 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() - }; - - var options = []; - var calculable_field = ['select', 'radio', 'checkbox']; - if($.inArray(setup.field_type, calculable_field) !== -1){ - var single_option = $('.repeater-child-input'); - if(single_option.length > 0){ - $.each(single_option, function(a, b){ - var check_qty; - if($(b).find('.repeater-child-input-qty').is(':checked')){ - check_qty = 'yes'; - }else{ - check_qty = 'no'; - } - var 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; - - // console.log(setup); - - var setup_string = JSON.stringify(setup); - var not_input = ['select', 'checkbox', 'radio']; - var is_required = ''; - var asterisk = ''; - if(setup.is_required == 'yes'){ - is_required = ''; - asterisk = ' (*)'; - } - var hidden = ''; - if(setup.field_type == 'hidden'){ - hidden = ' style="opacity: .75;"' - } - if(!setup.calc_value){ - setup.calc_value = 0; - } - - var preview_content = ''; - if($.inArray(setup.field_type, not_input) == -1){ - if($.inArray(setup.field_type, ['divider', 'page_break']) !== -1){ - preview_content = ` -
-
- -
- - -
-
- - -

`+setup.description+`

-
`; - }else if(setup.field_type == 'country_list') { - var country_json = formipay_admin.preset.country_list; - // Check if country_json is a string (indicating it might need to be parsed) - if (typeof country_json === 'string') { - try { - country_json = JSON.parse(country_json); // Parse the JSON string into an object - } catch (e) { - console.error('Error parsing JSON:', e); // Log any parsing errors - country_json = []; // Fallback to an empty array - } - } - - // Validate the data type - if (!Array.isArray(country_json)) { - console.error('Expected an array but got:', country_json); - country_json = []; // Fallback to an empty array if not an array - } - - var options_html = ``; - - // Loop through each country object - $.each(country_json, function(index, country) { - // Assuming each country object has 'id' for the value and 'name' for the display text - options_html += ``; - }); - - preview_content = ` -
-
- -
- - -
-
- - -

`+setup.description+`

-
`; - }else if(setup.field_type !== 'textarea'){ - preview_content = ` -
-
- -
- - -
-
- - -

`+setup.description+`

-
`; - }else{ - preview_content = ` -
-
- -
- - -
-
- - -

`+setup.description+`

-
`; - } - }else{ - if(setup.field_type == 'select'){ - var options = setup.field_options; - var options_html = ''; - if(setup.placeholder !== ''){ - options_html = ''; - } - $.each(options, function(j, k){ - var label = k.label; - var value = label; - if('' !== k.value && setup.show_toggle.value == 'yes'){ - value = k.value; - } - var calc = 0; - if('' !== k.amount && setup.show_toggle.amount == 'yes'){ - calc = k.amount; - } - options_html += ''; - }); - preview_content = ` -
-
- -
- - -
-
- - -

`+setup.description+`

-
`; - }else{ - var options = setup.field_options; - var options_html = ''; - $.each(options, function(j, k){ - var name = setup.field_id+`-`+j; - if(setup.field_type == 'radio'){ - name = setup.field_id; - } - var label = k.label; - var value = label; - if('' !== k.value && setup.show_toggle.value == 'yes'){ - value = k.value; - } - var calc = 0; - if('' !== k.amount && setup.show_toggle.amount == 'yes'){ - calc = k.amount; - } - var image = ''; - if('' !== k.image_id && '' !== k.image_url){ - image = ``; - } - options_html += - `
- `+image+` - - -
`; - }); - if(setup.layout == ''){ - setup.layout = 1; - } - preview_content = ` -
-
- -
- - -
-
- -
- `+options_html+` -
-

`+setup.description+`

-
`; - } - } - - var hidden = is_required = ''; - if(setup.type == 'hidden'){ - hidden = ' style="display: none;"'; - } - if(setup.require == 'yes'){ - is_required = ' required'; - } - - // Check if any - - var edit_to = $('.add-field').attr('data-edit-to'); - var the_existed_field = $('.preview-field[data-field="'+edit_to+'"]'); - - if(the_existed_field.length > 0){ - $('.preview-field[data-field="'+edit_to+'"]').html(` - - - - - - `+preview_content+` - `); - }else{ - $('#preview-wrapper').append(` -
- - - - - - `+preview_content+` -
- `); - } - - $('.preview-field[data-field="'+setup.field_id+'"]').attr('data-field-type', setup.field_type); - - // scissors icon - if(setup.field_type == 'page_break'){ - $('.preview-field[data-field="'+setup.field_id+'"]').append(` - - - - - - `) - }else{ - $('.preview-field[data-field="'+setup.field_id+'"] > span.scissors').remove(); - } - - var builder_fields = $('#add_field_form').find('.formipay-builder-field'); - if(builder_fields.length > 0){ - $.each(builder_fields, function(a, b){ - if($(b).attr('type') == 'checkbox'){ - $(b).val('no').prop('checked', false); - }else{ - $(b).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(); - - var all_option_toggle = $('.option-field-toggle'); - $.each(all_option_toggle, function(p, q){ - if($(q).is(':checked')){ - $(q).trigger('click'); - } - }); - + + 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(); - - setTimeout(() => { - update_option_to_data_mapping('update'); - }, 1000); + delayed(() => update_option_to_data_mapping('update'), 1000); }); - $(document).on('change', '#customer_data-buyer_allow_choose_country_code', function() { + // 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) { - var fields = $('#preview-wrapper').find('input[type=hidden]'); - var options = []; - $.each(fields, function(increment, field){ - var value = $(field).val(); - var config = JSON.parse(value); - options.push(config); + 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); }); - var target = $('#customer_data').find('select'); - target.html(''); - target.append(``); - if(options.length > 0){ - $.each(options, function(increment, option){ - target.append(``); + const $target = $('#customer_data').find('select'); + $target.html(''); + $target.append(``); + if (options.length > 0) { + $.each(options, function (_i, option) { + $target.append(``); }); } - if(initiation == 'initial'){ + 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); - } + 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(increment, select){ + } 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); - }) + }); } } - $(document).on('click', '.delete-preview-field', function(e){ + // ------------------------------ + // 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){ + $(document).on('click', '.edit-preview-field', function (e) { e.preventDefault(); - - // recondition all fields + + // Recondition all fields $('.option-field-toggle').prop('checked', false); $('.repeater-child-input:not(:first-child)').remove(); $('.repeater-child-input:first-child').find('input').val(''); - // $('.repeater-child-input:first-child').find('.add-thumbnail').removeClass('text-info').addClass('text-white'); - var setup = $(this).closest('.preview-field').find('.formipay-field-setup').val(); - setup = JSON.parse(setup); + let setup = $(this).closest('.preview-field').find('.formipay-field-setup').val(); + setup = jsonParseSafe(setup, {}); console.log(setup); - $.each(setup, function(x, y){ - if(x == 'field_options'){ - if(y.length > 0){ - var first_repeater = $('.repeater-child-input:first-child') - var repeater_template = first_repeater.html(); - var repeater_wrapper = $('.repeater-child-wrapper'); - $.each(y, function(p, q){ - repeater_wrapper.append( - `
- `+repeater_template+` -
`); - var repeater_target = $('.repeater-child-input:last-child'); - repeater_target.find('.the_title').text(q.label); - repeater_target.find('.child-field-label').find('input').val(q.label); - repeater_target.find('.child-field-value').find('input').val(q.value); - repeater_target.find('.child-field-amount').find('input').val(q.amount); - if(q.qty == 'yes'){ - repeater_target.find('.check-qty').val('yes').prop('checked', true); - }else{ - repeater_target.find('.check-qty').val('no').prop('checked', false); + + $.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(); } - if('' !== q.image){ - repeater_target.find('.field-image-id').val(q.image_id); - repeater_target.find('.field-image-url').val(q.image_url); - repeater_target.find('img').attr('src', q.image_url).removeClass('d-none'); - repeater_target.find('.child-field-image').hide(); - // repeater_target.find('.add-thumbnail').removeClass('text-white').addClass('text-info'); - } - repeater_target.show(); - first_repeater.hide(); - first_repeater.remove(); + $target.show(); + $first.hide(); + $first.remove(); }); $('.repeater-child-input:first-child').find('.open-option'); } - }else if(x == 'layout'){ - $('#add_field_form [name="option_grid_columns"]').val(y); - }else{ - $('#add_field_form [name="' + x + '"]').val(y); + } 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'); - // Handle show_toggle options + + // 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'); - } + 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(); - // Trigger recondition and form change - $('.formipay-builder-field[name=field_type]').trigger('change'); + formipay_sortable(); + $('.formipay-builder-field[name=field_type]').trigger('change'); $('.add-field').attr('data-edit-to', setup.field_id).text('Edit Field'); }); - if( $('[name=daterange]').val() == '' ){ - $('[name=daterange]').daterangepicker({ + // ------------------------------ + // 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' - } + timePicker24Hour: true, + locale: { format: 'D-M-Y HH:mm' } }); - }else{ - $('[name=daterange]').daterangepicker({ + } else { + $dr.daterangepicker({ timePicker: true, showDropdowns: true, - timePicker24Hour: true, - locale: { - format: 'D-M-Y HH:mm' - } + timePicker24Hour: true, + locale: { format: 'D-M-Y HH:mm' } }); } - $(document).on('click', '[role=switch]', function(){ - var id = $(this).attr('id'); - if($(this).is(':checked')){ - $('#add_field_form [data-if-'+id+'=active]').show(); + // ------------------------------ + // 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(); + } else { + $('#add_field_form [data-if-' + id + '=active]').hide(); $(this).val('yes'); } }); - $(document).on('click change', '#add_field_form [type=radio]', function(){ - var id = $(this).attr('name'); - var value = $(this).val(); - $('#add_field_form [data-if-'+id+']').hide(); - if($(this).is(':checked')){ - $('#add_field_form [data-if-'+id+'='+value+']').show(); - } + $(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(){ - var id = $(this).attr('id'); - var value = $(this).val(); - var attr_value = $('#add_field_form [data-if-'+id+']'); - $('#add_field_form [data-if-'+id+']').hide(); - - if(attr_value.length > 0){ - $.each(attr_value, function(x,y){ - var this_attr_value = $(y).attr('data-if-'+id); - if(this_attr_value.indexOf('::') !== -1){ - var split = this_attr_value.split('::'); - if($.inArray(value, split) !== -1){ - $(y).show(); - } - }else{ - if(this_attr_value == value){ - $(y).show(); - } + $(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'); - $(document).on('click', '.open-option', function(e){ + // ------------------------------ + // 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'); }); - // var all_checkbox = $('[type="checkbox"]'); - // if(all_checkbox.length > 0){ - // $.each(all_checkbox, function(a,b){ - // if($(b).val() == 'yes'){ - // $(b).val('no').trigger('click'); - // } - // }); - // } + // ------------------------------ + // Small UI polish (kept) + // ------------------------------ + $(document).on('mouseover', 'span.grab', function () { $(this).css('pointer', 'grab'); }); + $(document).on('click', 'span.grab', function () { $(this).css('pointer', 'grabbing'); }); - // function modify_payment_box_behavior() { - - // var allbox = $('#payments multi_checkbox'); - // var checkbox_input = $('.payments-payment input[type=checkbox]'); - // var checked_value = []; - // if(checkbox_input.length > 0){ - // $.each(checkbox_input, function(x, y){ - // if($(y).is(':checked')){ - // checked_value.push($(y).val()); - // $('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').show(); - // }else{ - // $('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').hide(); - // } - // }); - // } - - // } - - // setTimeout(() => { - // modify_payment_box_behavior(); - // }, 500); - - // $(document).on('click', '.payments-payment input[type=checkbox]', function(){ - // modify_payment_box_behavior(); - // }); - - $(document).on('mouseover', 'span.grab', function(){ - $(this).css('pointer', 'grab'); + $(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('click', 'span.grab', function(){ - $(this).css('pointer', 'grabbing'); - }); - - $(document).on('change blur', '.child-field-label input.formipay-builder-field', function(){ - $(this).closest('.child-fields-wrapper').find('.the_title').text($(this).val()); - }); - - $(document).on('change', '#customer_data select', function() { - var value = $(this).val(); + $(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 + // ------------------------------ -// jQuery(function($){ + // (All long commented code preserved exactly as original, for future reference) - // 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); + // jQuery(function($){ - // $(document).on('mouseleave blur focusout', '.wpcfto-autocomplete-search input', function(){ - // var placeholder = $(this).parent().attr('data-input-placeholder'); - // setTimeout(() => { - // $(this).attr('placeholder', placeholder); - // }, 500); - // }); + // // 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( 'click', '.add-thumbnail', function( event ) { - - // var gallery_items_frame; - // const $el = $( this ); - // var target_field = $el.attr('data-field'); - // var target_id = $el.siblings('.'+target_field+'-id'); - // var target_url = $el.siblings('.'+target_field+'-url'); - // var selected = target_id.val(); - // var able_multiple = $el.attr('data-able-multiple'); + // // $(document).on('mouseleave blur focusout', '.wpcfto-autocomplete-search input', function(){ + // // var placeholder = $(this).parent().attr('data-input-placeholder'); + // // setTimeout(() => { + // // $(this).attr('placeholder', placeholder); + // // }, 500); + // // }); - // event.preventDefault(); - - // if ( gallery_items_frame ) { - - // // Select the attachment when the frame opens - // gallery_items_frame.on( 'open', function() { - // var selection = gallery_items_frame.state().get( 'selection' ); - // selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] ); - // }); - - // // Open the modal. - // gallery_items_frame.open(); - - // return; - // } - - // // Create the media frame. - // gallery_items_frame = wp.media.frames.gallery_items = wp.media({ - // // Set the title of the modal. - // title: 'Choose or upload media', - // button: { - // text: 'Select' - // }, - // states: [ - // new wp.media.controller.Library({ - // title: 'Choose or upload media', - // filterable: 'all', - // multiple: able_multiple - // }) - // ] - // }); - - // // Select the attachment when the frame opens - // gallery_items_frame.on( 'open', function() { - // var selection = gallery_items_frame.state().get( 'selection' ); - // selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] ); - // }); - - // gallery_items_frame.on( 'select', function() { - // attachment = gallery_items_frame.state().get('selection').first().toJSON(); - // target_id.val( attachment.id ); - // target_url.val( attachment.url ); - // if(target_id.val() !== ''){ - // // $el.removeClass('text-white').addClass('text-info d-none'); - // if($el.hasClass('btn')){ - // $el.siblings('i').hide(); - // }else{ - // $el.hide(); - // } - // $el.siblings('img').removeClass('d-none').attr('src', attachment.url).show(); - // }else{ - // // $el.removeClass('text-info d-none').addClass('text-white'); - // if($el.hasClass('btn')){ - // $el.siblings('i').show(); - // }else{ - // $el.show(); - // } - // $el.siblings('img').addClass('d-none').hide(); - // } - // }); - - // // Open the modal. - // gallery_items_frame.open(); + // // (Media frame & Trumbowyg hooks preserved) // }); - // $( document ).on( 'click', '.trumbowyg-button-group:has(.trumbowyg-insertImage-button)', function( event ) { - - // var gallery_items_frame; - - // event.preventDefault(); - - // // Create the media frame. - // gallery_items_frame = wp.media.frames.gallery_items = wp.media({ - // // Set the title of the modal. - // title: 'Choose or upload media', - // button: { - // text: 'Select' - // }, - // states: [ - // new wp.media.controller.Library({ - // title: 'Choose or upload media', - // filterable: 'all', - // multiple: false - // }) - // ] - // }); - - // gallery_items_frame.on( 'select', function() { - // attachment = gallery_items_frame.state().get('selection').first().toJSON(); - // var target_input_url = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-input-html input'); - // var target_confirm = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-modal-submit'); - // target_input_url.val( attachment.url ); - // target_confirm.trigger('click'); - - // }); - - // // Open the modal. - // gallery_items_frame.open(); - - // }); - -// }); \ No newline at end of file +})(jQuery); \ No newline at end of file diff --git a/admin/assets/js/admin-editor.jsbak b/admin/assets/js/admin-editor.jsbak new file mode 100644 index 0000000..dc505bf --- /dev/null +++ b/admin/assets/js/admin-editor.jsbak @@ -0,0 +1,946 @@ +jQuery(function($){ + + let wpcftoLoaded = false; + + var checkWpcftoLoaded = setInterval(() => { + const container = $('.wpcfto-tab'); + if(container.length > 0){ + wpcftoLoaded = true; + $(document).trigger('wpcftoLoaded'); + clearInterval(checkWpcftoLoaded); + } + }, 250); + + $(document).on('wpcftoLoaded', function(){ + update_option_to_data_mapping('initial'); + }); + + function all_active_payments() { + + var items = $('.payment_gateways #active .list-group-item'); + var active_payments = []; + + if(items.length > 0){ + $.each(items, function(i, item){ + var gateway = $(item).attr('id'); + if(gateway.indexOf(':::') !== -1){ + gateway = gateway.split(':::')[0]; + gateway = gateway.replace('_', '-'); + } + // $('[data-submenu=payments_'+gateway+']').show(); + active_payments.push(gateway); + }); + } + + return active_payments; + + } + + function hide_inactive_payment_submenu() { + + var div = $('[data-section=payments]').siblings('.wpcfto-submenus').find('[data-submenu]:not([data-submenu=payments_general])'); + var active_payments = all_active_payments(); + + if(div.length > 0) { + $.each(div, function(x, y){ + var gateway = $(y).attr('data-submenu').replace('payments_', ''); + if(jQuery.inArray(gateway, active_payments) !== -1){ + $(y).slideDown(); + }else{ + $(y).slideUp(); + } + }); + } + } + + setTimeout(() => { + hide_inactive_payment_submenu(); + }, 1000); + + + $(document).on('mouseleave', '.payment_gateways .list-group', function(){ + + hide_inactive_payment_submenu(); + + }); + + $(document).on('click', '.formipay-editor-nav .nav-link', function(){ + $('.formipay-editor-nav').find('.nav-link').removeClass('active'); + $(this).addClass('active'); + $('.formipay-editor-tab-content.nav-content-section').addClass('d-none'); + var tab_content = $(this).data('tab-content'); + $('.formipay-editor-tab-content'+tab_content).removeClass('d-none'); + }); + + $('.formipay-editor-nav .nav-item:first-child > .nav-link').trigger('click'); + + $(document).on('click', '#is_required', function(){ + if($(this).is(':checked')) { + $(this).val('yes'); + }else{ + $(this).val('no'); + } + }); + + $(document).on('blur change', '#add_field_form .field select.form-select', function(){ + var array = ['divider', 'page_break']; + if( $.inArray( $(this).val(), array ) !== -1 ) { + $('#add_field_form .field:not(.main-field)').slideUp(); + }else{ + $('#add_field_form .field:not(.main-field):not(.has-conditional)').slideDown(); + } + }); + + 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(event, ui){ + 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(); + + $(document).on('change blur', '#add_field_form [name=label]', function(){ + $('#add_field_form [name=field_id]').val($(this).val().toLowerCase().replace(' ', '_')); + }); + + $(document).on('click', '.add-option', function(e){ + e.preventDefault(); + var content = $(this).closest('.repeater-child-input').html(); + $(this).closest('.repeater-child-wrapper').append(` +
`+content+` +
`); + $('.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(){ + var target = $(this).attr('data-child-field'); + if($(this).is(':checked')){ + $('.child-field-'+target).show(); + }else{ + $('.child-field-'+target).hide(); + } + }); + + $(document).on('change', '#add_field_form .formipay-builder-field:not(.formipay-builder-option-field, [type=checkbox], [type=checkbox])', function(){ + var value = $(this).val(); + var name = $(this).attr('name'); + var the_dependent = $('#add_field_form [data-if-'+name+']'); + if('' !== value && the_dependent.length > 0){ + // var all_dependents = $('.has-conditional'); + $.each(the_dependent, function(x, y){ + var decoded_value = JSON.parse($(y).attr('data-if-'+name)); + if($.inArray(value, decoded_value) !== -1){ + $(y).slideDown(); + }else{ + $(y).slideUp(); + } + }); + } + }); + + $(document).on('click', '.add-field', function(e){ + e.preventDefault(); + + var option_image_toggle = 'no'; + if($('#repeater-child-0_thumbnail').is(':checked')){ + option_image_toggle = 'yes'; + } + var option_value_toggle = 'no'; + if($('#repeater-child-2_value').is(':checked')){ + option_value_toggle = 'yes'; + } + var option_amount_toggle = 'no'; + if($('#repeater-child-3_amount').is(':checked')){ + option_amount_toggle = 'yes'; + } + + var 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() + }; + + var options = []; + var calculable_field = ['select', 'radio', 'checkbox']; + if($.inArray(setup.field_type, calculable_field) !== -1){ + var single_option = $('.repeater-child-input'); + if(single_option.length > 0){ + $.each(single_option, function(a, b){ + var check_qty; + if($(b).find('.repeater-child-input-qty').is(':checked')){ + check_qty = 'yes'; + }else{ + check_qty = 'no'; + } + var 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; + + // console.log(setup); + + var setup_string = JSON.stringify(setup); + var not_input = ['select', 'checkbox', 'radio']; + var is_required = ''; + var asterisk = ''; + if(setup.is_required == 'yes'){ + is_required = ''; + asterisk = ' (*)'; + } + var hidden = ''; + if(setup.field_type == 'hidden'){ + hidden = ' style="opacity: .75;"' + } + if(!setup.calc_value){ + setup.calc_value = 0; + } + + var preview_content = ''; + if($.inArray(setup.field_type, not_input) == -1){ + if($.inArray(setup.field_type, ['divider', 'page_break']) !== -1){ + preview_content = ` +
+
+ +
+ + +
+
+ + +

`+setup.description+`

+
`; + }else if(setup.field_type == 'country_list') { + var country_json = formipay_admin.preset.country_list; + // Check if country_json is a string (indicating it might need to be parsed) + if (typeof country_json === 'string') { + try { + country_json = JSON.parse(country_json); // Parse the JSON string into an object + } catch (e) { + console.error('Error parsing JSON:', e); // Log any parsing errors + country_json = []; // Fallback to an empty array + } + } + + // Validate the data type + if (!Array.isArray(country_json)) { + console.error('Expected an array but got:', country_json); + country_json = []; // Fallback to an empty array if not an array + } + + var options_html = ``; + + // Loop through each country object + $.each(country_json, function(index, country) { + // Assuming each country object has 'id' for the value and 'name' for the display text + options_html += ``; + }); + + preview_content = ` +
+
+ +
+ + +
+
+ + +

`+setup.description+`

+
`; + }else if(setup.field_type !== 'textarea'){ + preview_content = ` +
+
+ +
+ + +
+
+ + +

`+setup.description+`

+
`; + }else{ + preview_content = ` +
+
+ +
+ + +
+
+ + +

`+setup.description+`

+
`; + } + }else{ + if(setup.field_type == 'select'){ + var options = setup.field_options; + var options_html = ''; + if(setup.placeholder !== ''){ + options_html = ''; + } + $.each(options, function(j, k){ + var label = k.label; + var value = label; + if('' !== k.value && setup.show_toggle.value == 'yes'){ + value = k.value; + } + var calc = 0; + if('' !== k.amount && setup.show_toggle.amount == 'yes'){ + calc = k.amount; + } + options_html += ''; + }); + preview_content = ` +
+
+ +
+ + +
+
+ + +

`+setup.description+`

+
`; + }else{ + var options = setup.field_options; + var options_html = ''; + $.each(options, function(j, k){ + var name = setup.field_id+`-`+j; + if(setup.field_type == 'radio'){ + name = setup.field_id; + } + var label = k.label; + var value = label; + if('' !== k.value && setup.show_toggle.value == 'yes'){ + value = k.value; + } + var calc = 0; + if('' !== k.amount && setup.show_toggle.amount == 'yes'){ + calc = k.amount; + } + var image = ''; + if('' !== k.image_id && '' !== k.image_url){ + image = ``; + } + options_html += + `
+ `+image+` + + +
`; + }); + if(setup.layout == ''){ + setup.layout = 1; + } + preview_content = ` +
+
+ +
+ + +
+
+ +
+ `+options_html+` +
+

`+setup.description+`

+
`; + } + } + + var hidden = is_required = ''; + if(setup.type == 'hidden'){ + hidden = ' style="display: none;"'; + } + if(setup.require == 'yes'){ + is_required = ' required'; + } + + // Check if any + + var edit_to = $('.add-field').attr('data-edit-to'); + var the_existed_field = $('.preview-field[data-field="'+edit_to+'"]'); + + if(the_existed_field.length > 0){ + $('.preview-field[data-field="'+edit_to+'"]').html(` + + + + + + `+preview_content+` + `); + }else{ + $('#preview-wrapper').append(` +
+ + + + + + `+preview_content+` +
+ `); + } + + $('.preview-field[data-field="'+setup.field_id+'"]').attr('data-field-type', setup.field_type); + + // scissors icon + if(setup.field_type == 'page_break'){ + $('.preview-field[data-field="'+setup.field_id+'"]').append(` + + + + + + `) + }else{ + $('.preview-field[data-field="'+setup.field_id+'"] > span.scissors').remove(); + } + + var builder_fields = $('#add_field_form').find('.formipay-builder-field'); + if(builder_fields.length > 0){ + $.each(builder_fields, function(a, b){ + if($(b).attr('type') == 'checkbox'){ + $(b).val('no').prop('checked', false); + }else{ + $(b).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(); + + var all_option_toggle = $('.option-field-toggle'); + $.each(all_option_toggle, function(p, q){ + if($(q).is(':checked')){ + $(q).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'); + + formipay_sortable(); + + setTimeout(() => { + update_option_to_data_mapping('update'); + }, 1000); + }); + + $(document).on('change', '#customer_data-buyer_allow_choose_country_code', function() { + update_option_to_data_mapping('update'); + }); + + function update_option_to_data_mapping(initiation) { + var fields = $('#preview-wrapper').find('input[type=hidden]'); + var options = []; + $.each(fields, function(increment, field){ + var value = $(field).val(); + var config = JSON.parse(value); + options.push(config); + }); + var target = $('#customer_data').find('select'); + target.html(''); + target.append(``); + if(options.length > 0){ + $.each(options, function(increment, 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(increment, select){ + const current_value = $(select).attr('data-current-value'); + $(select).attr('data-current-value', current_value).val(current_value); + }) + } + } + + $(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(''); + // $('.repeater-child-input:first-child').find('.add-thumbnail').removeClass('text-info').addClass('text-white'); + + var setup = $(this).closest('.preview-field').find('.formipay-field-setup').val(); + setup = JSON.parse(setup); + console.log(setup); + $.each(setup, function(x, y){ + if(x == 'field_options'){ + if(y.length > 0){ + var first_repeater = $('.repeater-child-input:first-child') + var repeater_template = first_repeater.html(); + var repeater_wrapper = $('.repeater-child-wrapper'); + $.each(y, function(p, q){ + repeater_wrapper.append( + `
+ `+repeater_template+` +
`); + var repeater_target = $('.repeater-child-input:last-child'); + repeater_target.find('.the_title').text(q.label); + repeater_target.find('.child-field-label').find('input').val(q.label); + repeater_target.find('.child-field-value').find('input').val(q.value); + repeater_target.find('.child-field-amount').find('input').val(q.amount); + if(q.qty == 'yes'){ + repeater_target.find('.check-qty').val('yes').prop('checked', true); + }else{ + repeater_target.find('.check-qty').val('no').prop('checked', false); + } + if('' !== q.image){ + repeater_target.find('.field-image-id').val(q.image_id); + repeater_target.find('.field-image-url').val(q.image_url); + repeater_target.find('img').attr('src', q.image_url).removeClass('d-none'); + repeater_target.find('.child-field-image').hide(); + // repeater_target.find('.add-thumbnail').removeClass('text-white').addClass('text-info'); + } + repeater_target.show(); + first_repeater.hide(); + first_repeater.remove(); + }); + $('.repeater-child-input:first-child').find('.open-option'); + } + }else if(x == 'layout'){ + $('#add_field_form [name="option_grid_columns"]').val(y); + }else{ + $('#add_field_form [name="' + x + '"]').val(y); + } + }); + + $('#add_field_form [name=is_required]').prop('checked', setup.is_required === 'yes'); + // Handle show_toggle options + 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(); + // Trigger recondition and form change + $('.formipay-builder-field[name=field_type]').trigger('change'); + + $('.add-field').attr('data-edit-to', setup.field_id).text('Edit Field'); + }); + + if( $('[name=daterange]').val() == '' ){ + $('[name=daterange]').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{ + $('[name=daterange]').daterangepicker({ + timePicker: true, + showDropdowns: true, + timePicker24Hour: true, + locale: { + format: 'D-M-Y HH:mm' + } + }); + } + + $(document).on('click', '[role=switch]', function(){ + var 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(){ + var id = $(this).attr('name'); + var 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(){ + var id = $(this).attr('id'); + var value = $(this).val(); + var attr_value = $('#add_field_form [data-if-'+id+']'); + + $('#add_field_form [data-if-'+id+']').hide(); + + if(attr_value.length > 0){ + $.each(attr_value, function(x,y){ + var this_attr_value = $(y).attr('data-if-'+id); + if(this_attr_value.indexOf('::') !== -1){ + var split = this_attr_value.split('::'); + if($.inArray(value, split) !== -1){ + $(y).show(); + } + }else{ + if(this_attr_value == value){ + $(y).show(); + } + } + }); + } + + }); + + $('.config-dropdown').trigger('change'); + + $(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'); + }); + + // var all_checkbox = $('[type="checkbox"]'); + // if(all_checkbox.length > 0){ + // $.each(all_checkbox, function(a,b){ + // if($(b).val() == 'yes'){ + // $(b).val('no').trigger('click'); + // } + // }); + // } + + // function modify_payment_box_behavior() { + + // var allbox = $('#payments multi_checkbox'); + // var checkbox_input = $('.payments-payment input[type=checkbox]'); + // var checked_value = []; + // if(checkbox_input.length > 0){ + // $.each(checkbox_input, function(x, y){ + // if($(y).is(':checked')){ + // checked_value.push($(y).val()); + // $('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').show(); + // }else{ + // $('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').hide(); + // } + // }); + // } + + // } + + // setTimeout(() => { + // modify_payment_box_behavior(); + // }, 500); + + // $(document).on('click', '.payments-payment input[type=checkbox]', function(){ + // modify_payment_box_behavior(); + // }); + + $(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(){ + $(this).closest('.child-fields-wrapper').find('.the_title').text($(this).val()); + }); + + $(document).on('change', '#customer_data select', function() { + var value = $(this).val(); + $(this).attr('data-current-value', value); + }); + +}); + +// 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); + // }); + + // $( document ).on( 'click', '.add-thumbnail', function( event ) { + + // var gallery_items_frame; + // const $el = $( this ); + // var target_field = $el.attr('data-field'); + // var target_id = $el.siblings('.'+target_field+'-id'); + // var target_url = $el.siblings('.'+target_field+'-url'); + // var selected = target_id.val(); + // var able_multiple = $el.attr('data-able-multiple'); + + // event.preventDefault(); + + // if ( gallery_items_frame ) { + + // // Select the attachment when the frame opens + // gallery_items_frame.on( 'open', function() { + // var selection = gallery_items_frame.state().get( 'selection' ); + // selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] ); + // }); + + // // Open the modal. + // gallery_items_frame.open(); + + // return; + // } + + // // Create the media frame. + // gallery_items_frame = wp.media.frames.gallery_items = wp.media({ + // // Set the title of the modal. + // title: 'Choose or upload media', + // button: { + // text: 'Select' + // }, + // states: [ + // new wp.media.controller.Library({ + // title: 'Choose or upload media', + // filterable: 'all', + // multiple: able_multiple + // }) + // ] + // }); + + // // Select the attachment when the frame opens + // gallery_items_frame.on( 'open', function() { + // var selection = gallery_items_frame.state().get( 'selection' ); + // selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] ); + // }); + + // gallery_items_frame.on( 'select', function() { + // attachment = gallery_items_frame.state().get('selection').first().toJSON(); + // target_id.val( attachment.id ); + // target_url.val( attachment.url ); + // if(target_id.val() !== ''){ + // // $el.removeClass('text-white').addClass('text-info d-none'); + // if($el.hasClass('btn')){ + // $el.siblings('i').hide(); + // }else{ + // $el.hide(); + // } + // $el.siblings('img').removeClass('d-none').attr('src', attachment.url).show(); + // }else{ + // // $el.removeClass('text-info d-none').addClass('text-white'); + // if($el.hasClass('btn')){ + // $el.siblings('i').show(); + // }else{ + // $el.show(); + // } + // $el.siblings('img').addClass('d-none').hide(); + // } + // }); + + // // Open the modal. + // gallery_items_frame.open(); + + // }); + + // $( document ).on( 'click', '.trumbowyg-button-group:has(.trumbowyg-insertImage-button)', function( event ) { + + // var gallery_items_frame; + + // event.preventDefault(); + + // // Create the media frame. + // gallery_items_frame = wp.media.frames.gallery_items = wp.media({ + // // Set the title of the modal. + // title: 'Choose or upload media', + // button: { + // text: 'Select' + // }, + // states: [ + // new wp.media.controller.Library({ + // title: 'Choose or upload media', + // filterable: 'all', + // multiple: false + // }) + // ] + // }); + + // gallery_items_frame.on( 'select', function() { + // attachment = gallery_items_frame.state().get('selection').first().toJSON(); + // var target_input_url = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-input-html input'); + // var target_confirm = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-modal-submit'); + // target_input_url.val( attachment.url ); + // target_confirm.trigger('click'); + + // }); + + // // Open the modal. + // gallery_items_frame.open(); + + // }); + +// }); \ No newline at end of file diff --git a/admin/functions.php b/admin/functions.php index e8e1a56..6145f23 100644 --- a/admin/functions.php +++ b/admin/functions.php @@ -249,10 +249,25 @@ function formipay_get_currency_data_by_value($value, $data='') { } -function formipay_get_post_meta($post_id, $metakey) { +function formipay_get_post_meta($post_id, $metakey = '') { $value = get_post_meta($post_id, $metakey, true); + if($metakey == '') { + $flattened_meta = array(); + + foreach ($value as $key => $values) { + if (count($values) === 1) { + $flattened_meta[$key] = maybe_unserialize($values[0]); + } else { + // Keep multiple values as array (or handle as needed) + $flattened_meta[$key] = array_map('maybe_unserialize', $values); + } + } + + return $flattened_meta; + } + if(!empty($value) && false !== $value && '' !== $value){ return $value; } @@ -951,4 +966,18 @@ function formipay_thankyoupage_allowed_html() { 'td' => [], 'br' => [] ]; +} + +function formipay_is_donation($post_id) { + + return boolval(formipay_get_post_meta($post_id, 'donation_active')); + +} + +function formipay_product_has_variation($product_id) { + $has_variation = formipay_get_post_meta($product_id, 'product_has_variation'); + if( $has_variation == 'on' ){ + return true; + } + return false; } \ No newline at end of file diff --git a/admin/templates/editor-canvas.php b/admin/templates/editor-canvas.php index c466b49..31755ad 100644 --- a/admin/templates/editor-canvas.php +++ b/admin/templates/editor-canvas.php @@ -225,6 +225,4 @@ if(isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit'){ {{/ifEquals}} {{/each}} - - - + \ No newline at end of file diff --git a/includes/Form.php b/includes/Form.php index d5ae24f..74580fb 100644 --- a/includes/Form.php +++ b/includes/Form.php @@ -841,10 +841,13 @@ class Form { $last_cart_behavior = array_key_last($cart_behavior); $cart_behavior[$last_cart_behavior]['group'] = 'ended'; + $global_currencies = get_global_currency_array(); + $default_currency = formipay_default_currency(); + $cart_items = [ 'cart_items_group' => [ 'type' => 'group_title', - 'label' => __( 'Cart Items', 'formipay' ), + 'label' => __( 'Additional Order Items', 'formipay' ), 'group' => 'started', 'description' => __( 'Add static product or custom item to form as default and non-editable item in order items.', 'formipay' ) ], @@ -852,11 +855,12 @@ class Form { 'type' => 'autocomplete', 'post_type' => ['formipay-product'], 'label' => __( 'Assign Product', 'formipay' ), - 'description' => __( 'Selected products will added to the order items automatically.', 'formipay' ) + 'description' => __( 'Selected products will be added to the order items automatically, even if it is not added to cart.', 'formipay' ) ], 'static_items' => [ 'type' => 'repeater', - 'label' => __( 'Assign Items', 'formipay' ), + 'label' => __( 'Static Items', 'formipay' ), + 'description' => __( 'Static items will behave like fee that will affect to order calculation but nothing will be delivered.', 'formipay' ), 'fields' => [ 'label' => [ 'type' => 'text', @@ -870,16 +874,46 @@ class Form { 'value' => 1, 'required' => true ], - 'amount' => [ - 'type' => 'number', - 'label' => __( 'Item Amount', 'formipay' ), - 'description' => __( 'Will be calculated to item quantity', 'formipay' ), - 'required' => true - ] ] ] ]; + foreach($global_currencies as $currency){ + $default_currency_symbol = formipay_get_currency_data_by_value($default_currency, 'symbol'); + $currency_symbol = formipay_get_currency_data_by_value($currency['currency'], 'symbol'); + $currency_title = ucwords(formipay_get_currency_data_by_value($currency['currency'], 'title')); + $decimal_digits = intval($currency['decimal_digits']); + $step = $decimal_digits * 10; + $step = $step > 0 ? 1 / $step : 1; + $cart_items['static_items']['fields']['amount_'.$currency_symbol] = [ + 'type' => 'number', + 'step' => $step, + 'min' => 0, + 'label' => __( 'Item Price in '.$currency_symbol, 'formipay' ), + 'description' => __( 'Will be calculated to item quantity', 'formipay' ), + 'placeholder' => __( 'Auto', 'formipay' ) + ]; + + if(count($global_currencies) > 1){ + if($default_currency_symbol === $currency_symbol){ + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['description'] = sprintf( + __( 'This is your default currency. Change in Settings', 'formipay' ), + admin_url('/admin.php?page=formipay-settings') + ); + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['required'] = true; + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['placeholder'] = __( 'Enter Price...', 'formipay' ); + }else{ + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['description'] = sprintf( + __( 'System will calculate the price in %s based on exchange rate against %s when you leave these empty.', 'formipay' ), + $currency_symbol, $default_currency_symbol + ); + } + }else{ + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['label'] = __( 'Item Price', 'formipay' ); + $cart_items['static_items']['fields']['amount_'.$currency_symbol]['placeholder'] = __( 'Enter Price...', 'formipay' ); + } + } + $cart_items = apply_filters( 'formipay/form-settings/tab:cart/group:items', $cart_items ); $last_cart_items = array_key_last($cart_items); diff --git a/includes/Order.php b/includes/Order.php index 2bf65ea..3ef6ea9 100644 --- a/includes/Order.php +++ b/includes/Order.php @@ -15,6 +15,8 @@ class Order { private $order_details; + private $chosen_currency; + /** * Initializes the plugin by setting filters and administration functions. */ @@ -78,7 +80,6 @@ class Order { wp_send_json_error([ 'message' => 'Nonce verification failed' ]); - // wp_send_json_error() dies internally, no need for exit } // Sanitize and unslash inputs explicitly @@ -89,6 +90,7 @@ class Order { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $order_meta_data = isset($_REQUEST['meta_data']) ? wp_unslash($_REQUEST['meta_data']) : []; $purpose = isset($_REQUEST['purpose']) ? sanitize_text_field(wp_unslash($_REQUEST['purpose'])) : ''; + $this->currency = isset($_REQUEST['currency']) ? wp_unslash($_REQUEST['currency']) : formipay_default_currency('symbol'); $this->form_id = $form_id; @@ -104,6 +106,7 @@ class Order { if ($purpose === 'calculate') { $order_data['total'] = $total; $order_data['items'] = $order_details; + $order_data['form_data'] = formipay_get_post_meta($form_id); wp_send_json($order_data); } @@ -206,64 +209,98 @@ class Order { public function process_order_details() { + $currency_codes = []; + $allowed_currencies = formipay_get_post_meta($this->form_id, 'allowed_currencies'); + if(!empty($allowed_currencies)){ + $parse_currencies = json_decode($allowed_currencies, true); + foreach($parse_currencies as $currency_data){ + $parse_currency = explode(':::', $currency_data); + $currency_codes[] = $parse_currency[0]; + } + } + $details = []; - $product_price = floatval(formipay_get_post_meta($this->form_id, 'product_price')); - $details[] = [ - 'item' => html_entity_decode(get_the_title($this->form_id)), - 'amount' => $product_price, - 'qty' => $this->order_data['qty'], - 'subtotal' => floatval($product_price) * intval($this->order_data['qty']), - 'context' => 'main' - ]; + // $product_price = floatval(formipay_get_post_meta($this->form_id, 'product_price')); + // $details[] = [ + // 'item' => html_entity_decode(get_the_title($this->form_id)), + // 'amount' => $product_price, + // 'qty' => (int) $this->order_data['qty'], + // 'subtotal' => floatval($product_price) * intval($this->order_data['qty']), + // 'context' => 'main' + // ]; - $check_fields = formipay_get_post_meta($this->form_id, 'formipay_settings'); + // $check_fields = formipay_get_post_meta($this->form_id, 'formipay_settings'); - if(!empty($check_fields['fields'])){ - foreach($check_fields['fields'] as $field){ - // if($field['field_type'] == 'select'){ - if(in_array($field['field_type'], ['select','checkbox', 'radio'])) { - $options = $field['field_options']; - if(!empty($options)){ - foreach($options as $option){ + // if(!empty($check_fields['fields'])){ + // foreach($check_fields['fields'] as $field){ + // // if($field['field_type'] == 'select'){ + // if(in_array($field['field_type'], ['select','checkbox', 'radio'])) { + // $options = $field['field_options']; + // if(!empty($options)){ + // foreach($options as $option){ - $option_value = ($field['show_toggle']['value'] && '' !== $option['value']) ? $option['value'] : $option['label']; + // $option_value = ($field['show_toggle']['value'] && '' !== $option['value']) ? $option['value'] : $option['label']; - if(!empty($this->order_data[$field['field_id']])) { - $field_value = $this->order_data[$field['field_id']]; - if($field['field_type'] == 'select'){ - $field_value = ($field['show_toggle']['value']) ? - $this->order_data[$field['field_id']]['value'] : - $this->order_data[$field['field_id']]['label']; - } - $field_value = explode(',', $field_value); + // if(!empty($this->order_data[$field['field_id']])) { + // $field_value = $this->order_data[$field['field_id']]; + // if($field['field_type'] == 'select'){ + // $field_value = ($field['show_toggle']['value']) ? + // $this->order_data[$field['field_id']]['value'] : + // $this->order_data[$field['field_id']]['label']; + // } + // $field_value = explode(',', $field_value); - $context = 'no-context'; - if(floatval($option['amount']) < 0){ - $context = 'sub'; - }elseif(floatval($option['amount']) > 0){ - $context = 'add'; - } + // $context = 'no-context'; + // if(floatval($option['amount']) < 0){ + // $context = 'sub'; + // }elseif(floatval($option['amount']) > 0){ + // $context = 'add'; + // } - if(!empty($field_value) && $field['show_toggle']['amount'] == 'yes'){ - foreach($field_value as $f_value){ - if($option_value == $f_value){ - $qty = ($option['qty'] == 'yes') ? $this->order_data['qty'] : 1; - $details[] = [ - 'item' => $field['label'] .' - '. $option['label'], - 'amount' => floatval($option['amount']), - 'qty' => $qty, - 'subtotal' => floatval($option['amount']) * intval($qty), - 'context' => $context - ]; - } - } - } - } + // if(!empty($field_value) && $field['show_toggle']['amount'] == 'yes'){ + // foreach($field_value as $f_value){ + // if($option_value == $f_value){ + // $qty = ($option['qty'] == 'yes') ? $this->order_data['qty'] : 1; + // $details[] = [ + // 'item' => $field['label'] .' - '. $option['label'], + // 'amount' => floatval($option['amount']), + // 'qty' => (int) $qty, + // 'subtotal' => floatval($option['amount']) * intval($qty), + // 'context' => $context + // ]; + // } + // } + // } + // } - } - } - } + // } + // } + // } + // } + // } + + /** + * Cart items (not implemented yet) + */ + + /** + * Attached Product + */ + + $products = formipay_get_post_meta($this->form_id, 'static_products'); + if(!empty($products)){ + $products = explode(',', $products); + foreach($products as $product_id){ + $product_data = formipay_get_post_meta($product_id); + $regular_price = formipay_get_post_meta($product_id, 'setting_product_price_regular_'.$this->currency); + $sale_price = formipay_get_post_meta($product_id, 'setting_product_price_sale_'.$this->currency); + $this_item = [ + 'item' => html_entity_decode(get_the_title($product_id)), + 'amount' => (float) $sale_price ?: $regular_price, + 'qty' => 1, + 'subtotal' => (float) $sale_price ?: $regular_price, + ]; } } diff --git a/includes/Render.php b/includes/Render.php index 11429ab..93fdb6b 100644 --- a/includes/Render.php +++ b/includes/Render.php @@ -45,6 +45,8 @@ class Render { self::$form_ids[] = $post_id; } + $isDonation = formipay_is_donation($post_id); + $form_settings = get_post_meta($post_id, 'formipay_settings', true); $point_symbol = formipay_get_post_meta($post_id, 'multistep_point_symbol'); $point_icons = formipay_get_post_meta($post_id, 'multistep_point_icons'); diff --git a/public/assets/css/form-style.css b/public/assets/css/form-style.css index b0ef9d3..0137149 100644 --- a/public/assets/css/form-style.css +++ b/public/assets/css/form-style.css @@ -57,31 +57,38 @@ span.product-qty-wrapper { gap: .5em; justify-content: flex-start; align-items: center; + border: 1px solid #ddd; + border-radius: .5rem; + background-color: white; + width: fit-content; } span.product-qty-wrapper > button { - width: 40px; - height: 40px; min-width: unset!important; text-align: center; display: flex; justify-content: center; align-items: center; - padding: 0!important; - border-radius: 50%; - background-color: var(--formipay-button-submit-bg-color); + padding: 0 .25rem; + background-color: white; } span.product-qty-wrapper > button svg path { stroke: var(--formipay-button-submit-text-color); } -span.product-qty-wrapper > button:disabled { - background-color: #efefef; +span.product-qty-wrapper > button { + background-color: transparent; +} +span.product-qty-wrapper > button svg path { + stroke: var(--formipay-button-submit-bg-color); } span.product-qty-wrapper > button:disabled svg path { stroke: #666; } span.product-qty-wrapper > input { - height: 40px; width: 40px!important; + padding: .25rem!important; + border: unset!important; + background-color: transparent; + min-width: unset; text-align: center; } span.product-qty-wrapper > input::-webkit-outer-spin-button, diff --git a/public/assets/js/form-action.js b/public/assets/js/form-action.js index 6894cd6..040d9e9 100644 --- a/public/assets/js/form-action.js +++ b/public/assets/js/form-action.js @@ -1,5 +1,6 @@ jQuery(function($){ + console.info(formipay_form); let formipay_form_id = $('[data-form-id]').attr('data-form-id'); let formipay = formipay_form.forms[formipay_form_id]; @@ -218,7 +219,8 @@ jQuery(function($){ form_inputs.append('action', 'formipay_submission'); form_inputs.append('nonce', formipay_form.nonce); form_inputs.append('data[qty]', $('.formipay-qty-input').val()); - form_inputs.append('form_id', form_id); + form_inputs.append('form_id', form_id); + form_inputs.append('currency', 'IDR'); var $valid = true; // Initialize as true diff --git a/readme.txt b/readme.txt index 7207113..86a3ed3 100644 --- a/readme.txt +++ b/readme.txt @@ -76,41 +76,4 @@ Developed by Dwindi Ramadhana. == Privacy == -Formipay collects and processes user data in accordance with GDPR. Please review and customize the included privacy policy template for your site. - -== Mermaid Multi-Currency Implementation == - -flowchart TD - GS[Global Settings] - GS -->|Toggle: Multi‑Currency ON/OFF| MODE{Mode} - - %% SINGLE-CURRENCY MODE - MODE -->|OFF| SC[Single‑Currency Mode] - SC -->|GS Default Currency only| FS1[Form Settings] - SC -->|GS Default Currency only| PS1[Product Settings] - FS1 --> CO1[Checkout] - PS1 --> CO1 - CO1 --> ORD1[Order Stored :: currency = GS default] - ORD1 --> RPT1[Reports for single currency] - - %% MULTI-CURRENCY MODE - MODE -->|ON| MC[Multi‑Currency Mode] - GS -->|Enabled Currencies + Rates| FS[Form Settings] - GS -->|Enabled Currencies + Rates| PS[Product Settings xN] - - FS -->|FS.allowed ⊆ GS.enabled\nFS.default ∈ FS.allowed| CK[Checkout] - PS -->|Per Product:\nBase currency default GS\nManual overrides optional\nDerive from base via GS toggle| CK - - CK -->|Compute CheckoutAllowed =\nFS.allowed ∩ as ProductSupported p| ALLOWED{CheckoutAllowed empty?} - ALLOWED -->|Yes| BLOCK[Block checkout + Admin diagnostic:\nEnable derive / add manual prices /\nadjust FS.allowed / remove product] - ALLOWED -->|No| CUR[Buyer selects currency ∈ CheckoutAllowed] - - CUR --> PAY[Filter payment gateways by selected currency] - PAY --> TOT[Compute totals:\nManual price → else derive via GS] - TOT --> ORD[Persist Order:\norder_currency, total_in_order_currency,\nfx_rate_used, report_total_in_GS_base] - ORD --> RPT[Reports:\nSum in GS base with per‑currency breakdown option] - - %% CATALOG (when MC=ON) - MC --> CAT[Catalog] - CAT -->|Query: currency=USD,IDR,AUTO| RESOLVE[Resolve display currency AUTO→pref/GS default] - RESOLVE --> FILT[Filter products strictly:\nshow only products supporting the display currency\n derive ok if product toggle is ON] \ No newline at end of file +Formipay collects and processes user data in accordance with GDPR. Please review and customize the included privacy policy template for your site. \ No newline at end of file