PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / V3.0.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder vV3.0.2
V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 2.10.2 All 137 releases
bit-form / views / conversational-form.php

conversational-form.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder V3.0.2, at views/conversational-form.php

245 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // This file is included via Render::view() using extract(); all variables below are in the calling method's local scope, not global namespace.
4
5 use BitCode\BitForm\Core\Util\EscapingHelper;
6
7 if (!defined('ABSPATH')) {
8 exit;
9 }
10 if (!defined('BITFORMS_ASSET_URI')) {
11 exit;
12 }
13
14 $formUpdateVersion = get_option('bitform_form_update_version');
15 $formIdSafe = sanitize_key((string) $formID);
16
17 $baseCSSPath = "/form-styles/bitform-{$formID}.css";
18 $baseConversationalCSSPath = "/form-styles/bitform-conversational-{$formID}.css";
19 $customCSSPath = "/form-styles/bitform-custom-{$formID}.css";
20 $standaloneCSSPath = "/form-styles/bitform-standalone-{$formID}.css";
21
22 wp_register_style('bitform-conversational-base-' . $formIdSafe, BITFORMS_UPLOAD_BASE_URL . $baseCSSPath, [], $formUpdateVersion);
23 wp_register_style('bitform-conversational-' . $formIdSafe, BITFORMS_UPLOAD_BASE_URL . $baseConversationalCSSPath, [], $formUpdateVersion);
24 wp_enqueue_style('bitform-conversational-base-' . $formIdSafe);
25 wp_enqueue_style('bitform-conversational-' . $formIdSafe);
26
27 if (file_exists(BITFORMS_CONTENT_DIR . $customCSSPath)) {
28 wp_register_style('bitform-conversational-custom-' . $formIdSafe, BITFORMS_UPLOAD_BASE_URL . $customCSSPath, [], $formUpdateVersion);
29 wp_enqueue_style('bitform-conversational-custom-' . $formIdSafe);
30 }
31
32 if (file_exists(BITFORMS_CONTENT_DIR . $standaloneCSSPath)) {
33 wp_register_style('bitform-conversational-standalone-' . $formIdSafe, BITFORMS_UPLOAD_BASE_URL . $standaloneCSSPath, [], $formUpdateVersion);
34 wp_enqueue_style('bitform-conversational-standalone-' . $formIdSafe);
35 }
36
37 if (isset($font) && '' !== $font) {
38 wp_register_style('bitform-conversational-font-' . $formIdSafe, $font, [], $formUpdateVersion);
39 wp_enqueue_style('bitform-conversational-font-' . $formIdSafe);
40 }
41
42 $conversationalJsPath = BITFORMS_UPLOAD_BASE_URL . '/form-scripts/bitform-conversational-' . $formID . '.js';
43 wp_register_script('bitform-conversational-' . $formIdSafe, $conversationalJsPath, [], $formUpdateVersion, true);
44 wp_enqueue_script('bitform-conversational-' . $formIdSafe);
45 if (isset($bfGlobals) && '' !== $bfGlobals) {
46 wp_add_inline_script('bitform-conversational-' . $formIdSafe, (string) $bfGlobals, 'before');
47 }
48 ?>
49
50 <!DOCTYPE html>
51 <html lang="en">
52
53 <head>
54 <meta charset="UTF-8">
55 <meta name="viewport" content="width=device-width, initial-scale=1.0">
56 <title><?php echo isset($title) ? esc_html($title) : 'Conversational Form'; ?></title>
57 <style>
58 * {
59 padding: 0;
60 margin: 0;
61 box-sizing: border-box;
62 }
63
64 body.bit-conversational-form {
65 height: 100vh;
66 overflow: hidden;
67 }
68
69 @media (max-width: 575.98px) {
70 .standalone-form-wrapper {
71 width: 100%;
72 }
73 }
74 </style>
75 <?php if (isset($font) && '' !== $font) : ?>
76 <link rel="preconnect" href="https://fonts.googleapis.com">
77 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
78 <?php endif; ?>
79 <?php
80 wp_enqueue_emoji_styles();
81 wp_print_styles();
82 ?>
83 </head>
84
85 <body class="bit-conversational-form">
86 <?php echo wp_kses($formHTML, EscapingHelper::getFormAllowedHtml(isset($formContent) ? $formContent : null)); ?>
87 <?php if (!empty($isPreview)) : ?>
88 <style>.bc-live-hidden { display: none !important; }</style>
89 <script>window.bf_preview_mode = true;</script>
90 <?php endif; ?>
91 <?php wp_print_scripts(); ?>
92 <?php if (!empty($isPreview)) : ?>
93 <script>
94 (function() {
95 var FID = <?php echo (int) $formID; ?>;
96 var pfx = 'bc' + FID + '-';
97
98 function q(sel) { return document.querySelector('.' + pfx + sel); }
99 function qa(sel) { return document.querySelectorAll('.' + pfx + sel); }
100 function toggle(el, show) { if (el) el.classList.toggle('bc-live-hidden', !show); }
101 function setTxt(el, val) { if (el && val !== undefined && val !== null) el.textContent = val; }
102
103 var LAYOUT_CLASSES = ['normal-layout', 'compact-left-layout', 'compact-right-layout', 'padding-left-layout', 'padding-right-layout', 'centered-card-layout'];
104
105 function applyLiveSettings(settings) {
106 var nav = settings.navigationSettings || {};
107 var stl = settings.stepListObject || {};
108 var all = stl.allSteps || {};
109
110 // Visibility toggles
111 toggle(q('nav-wrpr'), nav.show !== false);
112 toggle(q('progress-lbl-wrpr'), !!nav.showProgressLabel);
113 toggle(q('progress-bar-wrpr'), !!nav.showProgressBar);
114 toggle(q('branding-wrpr'), nav.showBranding !== false);
115 toggle(q('nav-btn-wrpr'), !!nav.showNavigateBtn);
116
117 // Welcome page text content
118 var wp = stl.welcomePage || {};
119 var titleEl = document.querySelector('.' + pfx + 'welcome-title h2');
120 setTxt(titleEl, wp.title);
121 // Welcome page rich content (everything between title and button wrapper)
122 var welcomeContentEl = q('welcome-content');
123 if (welcomeContentEl && wp.content !== undefined) {
124 // Find the text node area — insert content after title, before button wrapper
125 var btnWrpr = welcomeContentEl.querySelector('.' + pfx + 'step-btn-wrpr');
126 var titleWrpr = welcomeContentEl.querySelector('.' + pfx + 'welcome-title');
127 // Remove existing text nodes / content nodes between title and button
128 var children = Array.from(welcomeContentEl.childNodes);
129 children.forEach(function(node) {
130 if (node !== titleWrpr && node !== btnWrpr) {
131 welcomeContentEl.removeChild(node);
132 }
133 });
134 var tempDiv = document.createElement('div');
135 tempDiv.innerHTML = wp.content || '';
136 var frag = document.createDocumentFragment();
137 while (tempDiv.firstChild) frag.appendChild(tempDiv.firstChild);
138 welcomeContentEl.insertBefore(frag, btnWrpr);
139 }
140
141 // Per-step: button text, hints, layout, image, background
142 var wrappers = qa('step-wrapper');
143 var fieldKeys = Object.keys(stl).filter(function(k) { return k !== 'allSteps' && k !== 'welcomePage'; });
144 var welcomeOffset = (wp.enable) ? 1 : 0;
145
146 Array.prototype.forEach.call(wrappers, function(wrapper, idx) {
147 var isWelcome = wrapper.classList.contains(pfx + 'welcome');
148 var cfg = isWelcome ? wp : (stl[fieldKeys[idx - welcomeOffset]] || {});
149
150 // Button text (start button on welcome, ok button on steps)
151 if (isWelcome) {
152 var startBtn = wrapper.querySelector('.' + pfx + 'start-btn');
153 if (startBtn) {
154 // preserve icon elements, update only text node
155 var textNode = Array.from(startBtn.childNodes).find(function(n) { return n.nodeType === 3 && n.textContent.trim(); });
156 if (textNode) textNode.textContent = '\n ' + (cfg.btnTxt || all.btnTxt || 'Start') + '\n ';
157 }
158 } else {
159 var btnEl = wrapper.querySelector('.' + pfx + 'btn-ok');
160 if (btnEl) {
161 var textNode = Array.from(btnEl.childNodes).find(function(n) { return n.nodeType === 3 && n.textContent.trim(); });
162 if (textNode) textNode.textContent = '\n ' + (cfg.btnTxt || all.btnTxt || 'OK') + '\n ';
163 }
164 }
165
166 // Step hints — rendered as HTML (same as PHP frontend output).
167 var hintsEl = wrapper.querySelector('.' + pfx + 'step-hints');
168 var hintsVal = cfg.stepHints !== undefined ? cfg.stepHints : all.stepHints;
169 if (hintsEl && hintsVal !== undefined && hintsVal !== null) hintsEl.innerHTML = hintsVal;
170
171 // Layout class
172 var layout = cfg.layout || all.layout || 'normal-layout';
173 LAYOUT_CLASSES.forEach(function(c) { wrapper.classList.remove(c); });
174 wrapper.classList.add(layout);
175
176 // Layout image
177 var imgEl = wrapper.querySelector('.' + pfx + 'step-img');
178 if (imgEl) imgEl.src = cfg.layoutImage || all.layoutImage || '';
179
180 // Show/hide image container based on layout
181 var imgCntnr = wrapper.querySelector('.' + pfx + 'step-img-cntnr');
182 if (imgCntnr) imgCntnr.style.display = (layout === 'normal-layout' || layout === 'centered-card-layout') ? 'none' : '';
183
184 // Step background — Floating Card redirects to card element; others apply to wrapper.
185 var bg = cfg.background || all.background || '';
186 var bgColor = typeof bg === 'object' ? (bg['background-color'] || '') : bg;
187 var cardEl = wrapper.querySelector('.' + pfx + 'step-content');
188 var isRealColor = bgColor && bgColor !== 'transparent';
189 if (layout === 'centered-card-layout') {
190 wrapper.style.removeProperty('background');
191 wrapper.style.removeProperty('background-color');
192 if (cardEl) {
193 // Only override CSS white fallback when user has a real color set.
194 if (isRealColor) cardEl.style.setProperty('background-color', bgColor, 'important');
195 else cardEl.style.removeProperty('background-color');
196 }
197 } else {
198 if (cardEl) cardEl.style.removeProperty('background-color');
199 if (isRealColor) wrapper.style.setProperty('background-color', bgColor, 'important');
200 else wrapper.style.removeProperty('background-color');
201 }
202 });
203 }
204
205 var BF_ALLOWED_ORIGIN = <?php
206 $bfParsed = wp_parse_url(get_site_url());
207 $bfOrigin = $bfParsed['scheme'] . '://' . $bfParsed['host'];
208 if (!empty($bfParsed['port'])) $bfOrigin .= ':' . $bfParsed['port'];
209 echo wp_json_encode($bfOrigin);
210 ?>;
211 window.addEventListener('message', function(e) {
212 if (!e.origin || e.origin !== BF_ALLOWED_ORIGIN) return;
213 var d = e.data;
214 if (!d || !d.__bf) return;
215
216 if (d.type === 'bf:css') {
217 var el = document.getElementById('bf-live-preview-css');
218 if (!el) {
219 el = document.createElement('style');
220 el.id = 'bf-live-preview-css';
221 document.head.appendChild(el);
222 }
223 el.textContent = d.css;
224 }
225
226 if (d.type === 'bf:settings') {
227 applyLiveSettings(d.settings);
228 }
229
230 if (d.type === 'bf:navigate') {
231 var contentIds = Object.keys(window.bf_globals || {});
232 for (var i = 0; i < contentIds.length; i++) {
233 var g = window.bf_globals[contentIds[i]];
234 var inst = g && g.inits && g.inits.conversational_form;
235 if (inst && typeof inst.goToStep === 'function') { inst.goToStep(d.stepIndex); break; }
236 }
237 }
238 });
239 })();
240 </script>
241 <?php endif; ?>
242 </body>
243
244 </html>
245