228 lines
16 KiB
PHP
228 lines
16 KiB
PHP
<?php
|
|
$saved_config = [];
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
if(isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit'){
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
$formipay_post_meta = get_post_meta(intval(wp_unslash($_GET['post'])), 'formipay_settings', true);
|
|
$saved_config = $formipay_post_meta['fields'];
|
|
}
|
|
?>
|
|
|
|
<div class="d-flex mx-0 w-100">
|
|
<div class="p-3" id="sidebar_panel">
|
|
<input type="hidden" name="formipay_builder_canvas" value="<?php echo esc_attr( wp_create_nonce('formipay-form-builder-canvas') ) ?>">
|
|
<div id="add_field_form"></div>
|
|
</div>
|
|
<div class="position-relative p-2" id="fields_panel">
|
|
<div class="position-absolute fw-bold"><?php echo esc_html__('Preview', 'formipay'); ?></div>
|
|
<div id="preview-wrapper" class="h-100 d-flex flex-column gap-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Config template -->
|
|
<script id="add-field-form-template" type="text/x-handlebars-template">
|
|
{{#each fields}}
|
|
<div class="field mb-2{{custom_class custom_class}}{{conditional_class conditional}}"{{{display conditional}}}>
|
|
<label for="{{id}}" class="form-label mb-0 small text-white {{#ifIn type "checkbox radio"}}d-none{{/ifIn}}">{{label}}</label>
|
|
|
|
{{#ifIn type "text number"}}
|
|
<input type="{{type}}" name="{{id}}" id="{{id}}" class="form-control formipay-builder-field" value="{{default}}" />
|
|
{{/ifIn}}
|
|
|
|
{{#ifEquals type "select"}}
|
|
<select name="{{id}}" class="form-select w-100 formipay-builder-field">
|
|
<option value="">-- Choose Type</option>
|
|
{{#each options}}
|
|
<option value="{{@key}}" {{selectedTheFirstOption @index}}>{{this}}</option>
|
|
{{/each}}
|
|
</select>
|
|
{{/ifEquals}}
|
|
|
|
{{#ifIn type "checkbox radio"}}
|
|
<input type="checkbox" name="{{id}}" id="{{id}}" class="form-control formipay-builder-field" value="no" />
|
|
<label for="{{id}}" class="form-label mb-0 small text-white">{{label}}</label>
|
|
{{/ifIn}}
|
|
|
|
{{#ifEquals type "textarea"}}
|
|
<textarea name="{{id}}" id="{{id}}" class="form-control formipay-builder-field">{{default}}</textarea>
|
|
<p class="mb-0 option-description small text-light">{{description}}</p>
|
|
{{/ifEquals}}
|
|
|
|
{{#ifEquals type "repeater"}}
|
|
<label class="form-label mb-0 small text-white">{{label}}</label>
|
|
<div class="d-flex flex-wrap gap-2 justify-content-start align-items-center">
|
|
{{#each fields}}
|
|
{{#ifEquals toggle "yes"}}
|
|
<div class="label-field">
|
|
<input type="checkbox" class="form-control option-field-toggle" data-child-field="{{id}}" id="repeater-child-{{@index}}_{{id}}">
|
|
<label for="repeater-child-{{@index}}_{{id}}" class="form-label text-sm mb-0 text-white">Show {{label}}</label>
|
|
</div>
|
|
{{/ifEquals}}
|
|
{{/each}}
|
|
</div>
|
|
<div class="repeater-child-wrapper">
|
|
<div class="repeater-child-input d-flex justify-content-start align-items-start gap-2 my-2">
|
|
<span class="grab mt-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
|
<path fill="#fff" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
|
</svg>
|
|
</span>
|
|
<div class="child-fields-wrapper w-100">
|
|
<div class="child-field-title text-bg-dark py-2 px-3 d-flex justify-content-between align-items-center">
|
|
<div class="the_title">Option</div>
|
|
<div class="the_buttons">
|
|
<button class="btn btn-sm text-bg-light mb-0 add-option">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="18" viewBox="0 0 24 24">
|
|
<path fill="#000" d="M9 18q-.825 0-1.412-.587T7 16V4q0-.825.588-1.412T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.587 1.413T18 18zm0-2h9V4H9zm-4 6q-.825 0-1.412-.587T3 20V6h2v14h11v2zm4-6V4z" />
|
|
</svg>
|
|
</button>
|
|
<button class="btn btn-sm text-bg-light mb-0 delete-option">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
|
<path fill="#000" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" />
|
|
</svg>
|
|
</i></button>
|
|
<button class="btn btn-sm text-bg-light mb-0 open-collapse open-option">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
|
<path fill="#000" d="m12 15l-5-5h10z" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="child-field-wrapper p-2 bg-light text-dark" style="display:none;">
|
|
<div class="child-field-row row">
|
|
<div class="child-field-image col-6 child-field-col-1 child-field-thumbnail repeater-child-input-thumbnail" style="display: none;">
|
|
<div class="child-field-image-wrapper formipay-builder-field">
|
|
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder to display an image preview and will be managed by JS ?>
|
|
<img src="" class="d-none" style="width: 100%;" alt="Image Preview"/>
|
|
<i data-field="field-image" class="bi bi-file-earmark-image-fill pointer fs-3 text-secondary add-thumbnail child-field-image"{{{toggleDisplay toggle}}}></i>
|
|
<input type="hidden" class="field-image-id d-none">
|
|
<input type="hidden" class="field-image-url d-none">
|
|
<button data-field="field-image" class="btn btn-sm add-thumbnail bg-secondary text-white">Choose Image</button>
|
|
</div>
|
|
</div>
|
|
<div class="col child-field-col-2">
|
|
<table class="table child-field-input-table">
|
|
<tbody>
|
|
{{#each fields}}
|
|
{{#ifNotIn type "image toggle"}}
|
|
<tr class="child-field-{{id}} repeater-child-input-{{id}}"{{{toggleDisplay toggle}}}>
|
|
<th>{{label}}</th>
|
|
<td>
|
|
<input type="{{type}}" class="form-control formipay-builder-field formipay-builder-option-field" value="{{default}}" placeholder="{{label}}" />
|
|
</td>
|
|
</tr>
|
|
{{/ifNotIn}}
|
|
{{#ifEquals type "toggle"}}
|
|
<tr class="child-field-{{id}}"{{{toggleDisplay toggle}}}>
|
|
<th>{{label}}</th>
|
|
<td>
|
|
<div class="form-check form-switch align-items-baseline mt-2 mb-0 formipay-builder-field formipay-builder-option-field">
|
|
<input class="form-check-input check-qty repeater-child-input-qty" type="checkbox" role="switch">
|
|
<label class="form-check-label text-white text-nowrap"><span class="small">✕</span> Quantity</label>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{{/ifEquals}}
|
|
{{/each}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{/ifEquals}}
|
|
</div>
|
|
{{/each}}
|
|
<button type="button" class="btn btn-light add-field w-100">Add Field</button>
|
|
</script>
|
|
|
|
<!-- Preview template -->
|
|
<script id="preview-template" type="text/x-handlebars-template">
|
|
{{#each fields}}
|
|
{{!-- Hidden field --}}
|
|
<div class="preview-field d-flex gap-2 align-items-center" data-field="{{field_id}}" data-field-type="{{field_type}}" {{#ifEquals field_type "hidden"}}style="opacity: .5;"{{/ifEquals}}>
|
|
<span class="grab pb-4">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
|
<path fill="#000" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
|
</svg>
|
|
</span>
|
|
<div class="formipay-field w-100">
|
|
<div class="d-flex justify-content-between field-controls">
|
|
<label for="{{field_id}}" class="{{labelClass field_type}}">{{label}}{{#ifEquals is_required "yes"}} <span style="color: red;">(*)</span>{{/ifEquals}}</label>
|
|
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
|
<button class="btn btn-sm edit-preview-field">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
|
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
|
</svg>
|
|
</button>
|
|
<button class="btn btn-sm delete-preview-field">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
|
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="{{@key}}" class="formipay-field-setup" value='{{json this}}' />
|
|
|
|
{{!-- Input fields --}}
|
|
{{#ifNotEquals field_type "textarea"}}
|
|
{{#ifIn field_type "divider page_break select checkbox radio country_list"}}
|
|
{{#ifEquals field_type "divider"}}
|
|
<span class="divider-line"></span>
|
|
{{/ifEquals}}
|
|
{{#ifEquals field_type "page_break"}}
|
|
<span class="divider-line"></span>
|
|
{{/ifEquals}}
|
|
{{#ifEquals field_type "select"}}
|
|
<select id="{{field_id}}" class="formipay-input formipay-form-field w-100">
|
|
{{#if placeholder}}
|
|
<option>{{placeholder}}</option>
|
|
{{/if}}
|
|
{{#each field_options}}
|
|
<option value="{{this.value}}" data-calc-value="{{this.amount}}">{{this.label}}</option>
|
|
{{/each}}
|
|
</select>
|
|
{{/ifEquals}}
|
|
{{#ifEquals field_type "country_list"}}
|
|
<select id="{{field_id}}" class="formipay-input formipay-form-field w-100">
|
|
<option>-- {{placeholder}}</option>
|
|
{{{countryListOptions}}}
|
|
</select>
|
|
{{/ifEquals}}
|
|
{{#ifIn field_type "checkbox radio"}}
|
|
<div class="formipay-checkbox-wrapper" style="grid-template-columns: repeat({{layoutColumn layout}}, 1fr);">
|
|
{{#each field_options}}
|
|
<div class="formipay-checkbox-group">
|
|
{{#if image_url}}
|
|
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder to display an image preview and will be managed by JS ?>
|
|
<img src="{{this.image_url}}" alt="{{this.label}}" style="width: 100%; height: 150px; object-fit: contain;" />
|
|
{{/if}}
|
|
<input type="{{../field_type}}" id="{{../config_id}}-{{@index}}" name="{{name ../field_type ../field_id @index}}" class="formipay-input formipay-form-field" value="{{this.value}}" data-calc-value="{{this.amount}}"/>
|
|
<label for="{{../config_id}}-{{@index}}">{{this.label}}</label>
|
|
</div>
|
|
{{/each}}
|
|
</div>
|
|
{{/ifIn}}
|
|
{{else}}
|
|
<input type="{{field_type}}" id="{{field_id}}" class="formipay-input formipay-form-field w-100" placeholder="{{placeholder}}" value="{{default_value}}" {{#ifEquals field_type "number"}}data-calc-value="{{calc_value}}"{{/ifEquals}} />
|
|
{{/ifIn}}
|
|
{{else}}
|
|
{{!-- Textarea field --}}
|
|
<textarea id="{{field_id}}" rows="4" class="formipay-input formipay-form-field w-100" placeholder="{{placeholder}}">{{default_value}}</textarea>
|
|
{{/ifNotEquals}}
|
|
|
|
<p class="formipay-inline-desc">{{description}}</p>
|
|
</div>
|
|
{{#ifEquals field_type "page_break"}}
|
|
<span class="scissors">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
|
<path fill="#000" d="m12 14l-2.35 2.35q.2.375.275.8T10 18q0 1.65-1.175 2.825T6 22t-2.825-1.175T2 18t1.175-2.825T6 14q.425 0 .85.075t.8.275L10 12L7.65 9.65q-.375.2-.8.275T6 10q-1.65 0-2.825-1.175T2 6t1.175-2.825T6 2t2.825 1.175T10 6q0 .425-.075.85t-.275.8L20.6 18.6q.675.675.3 1.538T19.575 21q-.275 0-.537-.112t-.463-.313zm3-3l-2-2l5.575-5.575q.2-.2.463-.312T19.574 3q.95 0 1.313.875t-.313 1.55zM6 8q.825 0 1.413-.587T8 6t-.587-1.412T6 4t-1.412.588T4 6t.588 1.413T6 8m6 4.5q.2 0 .35-.15t.15-.35t-.15-.35t-.35-.15t-.35.15t-.15.35t.15.35t.35.15M6 20q.825 0 1.413-.587T8 18t-.587-1.412T6 16t-1.412.588T4 18t.588 1.413T6 20" />
|
|
</svg>
|
|
</span>
|
|
{{/ifEquals}}
|
|
</div>
|
|
{{/each}}
|
|
</script>
|