#26 - Loading animation + success message fix
This commit was merged in pull request #31.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Reservair\Forms\RsvFormBuilder;
|
||||
use Reservair\Forms\RsvCodeEditor;
|
||||
use Reservair\Layout\RsvColumnLayout;
|
||||
|
||||
class RsvFormsPage extends RsvAdminPage {
|
||||
@@ -127,7 +128,20 @@ class RsvFormsPage extends RsvAdminPage {
|
||||
echo RsvFormBuilder::create('edit_form_definition', get_rest_url(null, 'reservations/v1/form-definition/' . $id), 'PUT', 'Form definition updated.')
|
||||
->text('name', 'Name', '', true, $form_def['name'])
|
||||
->select('definition.email_key', 'Email Key', $email_key_options, "Form field that holds the submitter's email address.", true, $definition['email_key'] ?? '')
|
||||
->code('definition.success_message', 'Success message', 'Shown to the visitor after a successful submission. HTML is allowed. Use <reservation-summary></reservation-summary> to display the selected reservations. Leave blank for the default message.', $definition['success_message'] ?? '')
|
||||
->custom('Success message', function () use ($definition) {
|
||||
$editor = RsvCodeEditor::render('definition.success_message', [
|
||||
'value' => $definition['success_message'] ?? '',
|
||||
'mode' => 'text/html',
|
||||
'rows' => 8,
|
||||
]);
|
||||
$hint = esc_html('Shown to the visitor after a successful submission. HTML is allowed. Use <reservation-summary></reservation-summary> to display the selected reservations. Leave blank for the default message.');
|
||||
return '<div style="display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap;">'
|
||||
. '<div style="flex:1 1 320px;min-width:0;">' . $editor . '<p class="description">' . $hint . '</p></div>'
|
||||
. '<div style="flex:1 1 320px;min-width:0;">'
|
||||
. '<span style="display:block;font-weight:600;margin-bottom:8px;">Live preview</span>'
|
||||
. '<div id="rsv_success_preview" class="rsv-form-preview rsv-success-msg"></div>'
|
||||
. '</div></div>';
|
||||
})
|
||||
->render();
|
||||
?>
|
||||
|
||||
@@ -169,11 +183,11 @@ class RsvFormsPage extends RsvAdminPage {
|
||||
->output();
|
||||
?>
|
||||
|
||||
<?php $this->elements_table_script($elements_with_ids, $next_id, 'edit_form_definition', $element_types, $timetables, $programs, $bindings); ?>
|
||||
<?php $this->elements_table_script($elements_with_ids, $next_id, 'edit_form_definition', $element_types, $timetables, $programs, $bindings, $id); ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
private function elements_table_script(array $elements_with_ids, int $next_id, string $form_id, array $element_types, array $timetables = [], array $programs = [], array $bindings = []): void {
|
||||
private function elements_table_script(array $elements_with_ids, int $next_id, string $form_id, array $element_types, array $timetables = [], array $programs = [], array $bindings = [], int $definition_id = 0): void {
|
||||
$elements_json = json_encode($elements_with_ids);
|
||||
$types_json = json_encode(array_values($element_types));
|
||||
$timetables_json = json_encode(array_values($timetables));
|
||||
@@ -365,6 +379,54 @@ class RsvFormsPage extends RsvAdminPage {
|
||||
// The preview form is inert: block submission (capture so it works after re-render).
|
||||
rsv_preview_el?.addEventListener('submit', (e) => e.preventDefault(), true);
|
||||
|
||||
// --- Success message live preview ----------------------------------
|
||||
// Rendered with the same template engine the front-end uses after a real
|
||||
// submission. The data comes from this form's most recent submission, so
|
||||
// {{ tokens }} and <reservation-summary> mirror a genuine confirmation;
|
||||
// the message text itself updates live as it is edited.
|
||||
const rsv_success_preview_el = document.getElementById('rsv_success_preview');
|
||||
let rsv_success_preview_timer = null;
|
||||
let rsv_success_preview_data = {};
|
||||
|
||||
function rsv_schedule_success_preview() {
|
||||
if (!rsv_success_preview_el) return;
|
||||
clearTimeout(rsv_success_preview_timer);
|
||||
rsv_success_preview_timer = setTimeout(rsv_render_success_preview, 300);
|
||||
}
|
||||
|
||||
function rsv_render_success_preview() {
|
||||
if (!rsv_success_preview_el) return;
|
||||
const form = document.getElementById('<?= $form_id ?>');
|
||||
const tpl = (form?.querySelector('[name="definition.success_message"]')?.value ?? '').trim();
|
||||
if (tpl === '') {
|
||||
rsv_success_preview_el.innerHTML = '<p class="rsv-preview-empty">Leave blank to show the default confirmation message.</p>';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
rsv_success_preview_el.innerHTML = RsvFormSender.render_template(tpl, rsv_success_preview_data);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
rsv_success_preview_el.innerHTML = '<p class="rsv-preview-empty">Preview unavailable.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons rendered into the preview (e.g. <reset-form-button>) live inside
|
||||
// the edit form — keep them from submitting it.
|
||||
rsv_success_preview_el?.addEventListener('click', (e) => {
|
||||
if (e.target.closest('button, input[type="submit"], input[type="image"]')) e.preventDefault();
|
||||
}, true);
|
||||
|
||||
if (rsv_success_preview_el) {
|
||||
rsv_render_success_preview();
|
||||
fetch('<?= get_rest_url(null, 'reservations/v1/form-definition/' . $definition_id . '/submission/latest') ?>', {
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Accept': 'application/json', 'X-WP-Nonce': ReservairServiceAPI.nonce },
|
||||
})
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(res => { rsv_success_preview_data = res?.data ?? {}; rsv_render_success_preview(); })
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function rsv_render_element_inline_form(dt, row, data) {
|
||||
const builder = RsvInlineFormBuilder.create(rsv_elements_source)
|
||||
.fieldset('Element', '50%')
|
||||
@@ -620,11 +682,15 @@ class RsvFormsPage extends RsvAdminPage {
|
||||
}
|
||||
|
||||
const rsv_meta_form = document.getElementById('<?= $form_id ?>');
|
||||
['name', 'definition.email_key', 'definition.success_message', 'definition.membership_combine'].forEach((n) => {
|
||||
['name', 'definition.email_key', 'definition.membership_combine'].forEach((n) => {
|
||||
const el = rsv_meta_form?.querySelector(`[name="${n}"]`);
|
||||
el?.addEventListener('input', rsv_schedule_preview);
|
||||
el?.addEventListener('change', rsv_schedule_preview);
|
||||
});
|
||||
// The success message drives its own preview only.
|
||||
const rsv_success_input = rsv_meta_form?.querySelector('[name="definition.success_message"]');
|
||||
rsv_success_input?.addEventListener('input', rsv_schedule_success_preview);
|
||||
rsv_success_input?.addEventListener('change', rsv_schedule_success_preview);
|
||||
|
||||
RsvAdminForm.bind(document.getElementById('<?= $form_id ?>'), {
|
||||
transform: () => rsv_collect_definition(),
|
||||
|
||||
Reference in New Issue
Block a user