PluginProbe
Booking Calendar / 11.7
Booking Calendar v11.7
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / includes / page-form-builder / field-packs / wizard-nav / _src / wizard-nav.js

wizard-nav.js in Booking Calendar 11.7, at includes/page-form-builder/field-packs/wizard-nav/_src/wizard-nav.js

269 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // File: /includes/page-form-builder/field-packs/wizard-nav/_out/wizard-nav.js
2 (function ( w ) {
3 'use strict';
4
5 var Core = w.WPBC_BFB_Core || {};
6 var registry = Core.WPBC_BFB_Field_Renderer_Registry;
7 var Base = Core.WPBC_BFB_Field_Base;
8
9 if ( ! registry || typeof registry.register !== 'function' || ! Base ) {
10 _wpbc?.dev?.error?.( 'WPBC_BFB_Field_Wizard_Nav', 'Core registry/base missing' );
11 return;
12 }
13
14 /**
15 * WPBC BFB: Field Renderer for "wizard_nav" (Schema-driven)
16 * - Inspector is rendered by Factory (from PHP schema).
17 * - No wp.template usage for preview.
18 * - Must output:
19 * <a class="wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_{N} [cssclass_extra]">Label</a>
20 */
21 class WPBC_BFB_Field_Wizard_Nav extends Base {
22
23 /**
24 * Return default props for "wizard_nav" field.
25 * Must stay in sync with PHP schema defaults.
26 *
27 * @returns {Object}
28 */
29 static get_defaults() {
30 return {
31 type : 'wizard_nav',
32 direction : 'next', // 'next' | 'back'
33 label : 'Next',
34 target_step : 2, // >= 1
35 cssclass_extra : '',
36 name : '',
37 html_id : '',
38 help : '',
39 usage_key : 'wizard_nav'
40 };
41 }
42
43 /**
44 * Render the preview markup into the field element.
45 *
46 * @param {HTMLElement} el Field root element inside the canvas.
47 * @param {Object} data Field props (already normalized by schema).
48 * @param {Object} ctx Context: { builder, sanit, ... }
49 * @returns {void}
50 */
51 static render( el, data, ctx ) {
52
53 if ( ! el ) {
54 return;
55 }
56
57 // Normalize against defaults first.
58 const d = this.normalize_data( data );
59
60 // ----- Core sanitize helpers (static) -----
61 const eh = ( v ) => Core.WPBC_BFB_Sanitize.escape_html( v );
62 const sid = ( v ) => Core.WPBC_BFB_Sanitize.sanitize_html_id( v );
63 const sname = ( v ) => Core.WPBC_BFB_Sanitize.sanitize_html_name( v );
64 const sclass = ( v ) => Core.WPBC_BFB_Sanitize.sanitize_css_classlist( v );
65 const to_int = ( v, def ) => {
66 const n = parseInt( v, 10 );
67 return ( isNaN( n ) || n < 1 ) ? def : n;
68 };
69
70 // Direction & label coherence.
71 const dir = ( d.direction === 'back' ) ? 'back' : 'next';
72 const step_def = ( dir === 'next' ) ? 2 : 1;
73 const step_num = to_int( d.target_step, step_def );
74 const label_txt = ( typeof d.label === 'string' && d.label.length ) ? d.label : ( dir === 'next' ? 'Next' : 'Back' );
75
76 // Public attributes.
77 const html_id = d.html_id ? sid( String( d.html_id ) ) : '';
78 const name_val = d.name ? sname( String( d.name ) ) : '';
79 const cls_extra = sclass( String( d.cssclass_extra || '' ) );
80
81 // Persist useful props on dataset (do not mutate wrapper classes directly).
82 if ( 'cssclass_extra' in d && el.dataset.cssclass_extra !== cls_extra ) {
83 el.dataset.cssclass_extra = cls_extra;
84 }
85 if ( 'html_id' in d && el.dataset.html_id !== html_id ) {
86 el.dataset.html_id = html_id;
87 }
88 if ( 'name' in d && el.dataset.name !== name_val ) {
89 el.dataset.name = name_val;
90 }
91 if ( 'target_step' in d && String( el.dataset.target_step ) !== String( step_num ) ) {
92 el.dataset.target_step = String( step_num );
93 }
94 if ( 'direction' in d && el.dataset.direction !== dir ) {
95 el.dataset.direction = dir;
96 }
97
98 // Attribute fragments.
99 const id_attr = html_id ? ` id="${eh( html_id )}"` : '';
100 const name_attr = name_val ? ` name="${eh( name_val )}"` : '';
101 const req_cls = `wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_${String( step_num )}`;
102 const cls_attr = ` class="${req_cls}${cls_extra ? ' ' + eh( cls_extra ) : ''}"`;
103 const href_attr = ` href="javascript:void(0);"`;
104
105 // Optional help text below the button.
106 const help_html = d.help ? `<div class="wpbc_bfb__help">${eh( d.help )}</div>` : '';
107
108 // Render preview HTML.
109 el.innerHTML = `
110 <span class="wpbc_bfb__noaction wpbc_bfb__no-drag-zone" inert="">
111 <div class="wpbc_bfb__field-preview">
112 <a${href_attr}${cls_attr}${id_attr}${name_attr}>${eh( label_txt )}</a>
113 </div>
114 ${help_html}
115 </span>
116 `;
117
118 // Overlay (handles/toolbars).
119 Core.UI?.WPBC_BFB_Overlay?.ensure?.( ctx?.builder, el );
120 }
121
122 /**
123 * Optional hook executed after field is dropped from the palette.
124 *
125 * @param {Object} data
126 * @param {HTMLElement} el
127 * @param {Object} ctx
128 * @returns {void}
129 */
130 static on_field_drop( data, el, ctx ) {
131 // Keep base behavior (auto-name from label, etc.).
132 super.on_field_drop?.( data, el, ctx );
133 }
134 }
135
136 try {
137 registry.register( 'wizard_nav', WPBC_BFB_Field_Wizard_Nav );
138 } catch ( e ) { _wpbc?.dev?.error?.( 'WPBC_BFB_Field_Wizard_Nav.register', e ); }
139
140
141 // -----------------------------------------------------------------------------------------------------------------
142 // Export for "Booking Form" (Advanced Form shortcode)
143 // -----------------------------------------------------------------------------------------------------------------
144 /**
145 * Booking Form exporter callback for "wizard_nav".
146 *
147 * Produces anchors equivalent to the legacy exporter:
148 * <a class="wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_2 extra">Next</a>
149 *
150 * Notes:
151 * - No shortcode; this is pure HTML (navigation control, not a data field).
152 * - Help text is appended centrally by WPBC_BFB_Exporter.render_field_node().
153 */
154 function register_wizard_nav_booking_form_exporter() {
155
156 var Exp = w.WPBC_BFB_Exporter;
157 if ( ! Exp || typeof Exp.register !== 'function' ) { return; }
158 if ( typeof Exp.has_exporter === 'function' && Exp.has_exporter( 'wizard_nav' ) ) { return; }
159
160 var S = Core.WPBC_BFB_Sanitize || {};
161 var esc_html = S.escape_html || function( v ){ return String( v ); };
162 var sid = S.sanitize_html_id || function( v ){ return String( v ).trim(); };
163 var scls = S.sanitize_css_classlist || function( v ){ return String( v ).trim(); };
164
165 /**
166 * @type {WPBC_BFB_ExporterCallback}
167 */
168 Exp.register( 'wizard_nav', function( field, emit, extras ) {
169 extras = extras || {};
170
171 var ctx = extras.ctx || {};
172 var usedIds = ( ctx.usedIds instanceof Set ) ? ctx.usedIds : null;
173
174 // Merge with defaults to keep behavior stable even if some props are missing.
175 var defs = ( typeof WPBC_BFB_Field_Wizard_Nav.get_defaults === 'function' )
176 ? WPBC_BFB_Field_Wizard_Nav.get_defaults()
177 : {};
178 var d = Object.assign( {}, defs, field || {} );
179
180 // Direction & label logic (same as preview).
181 var dir = ( d.direction === 'back' ) ? 'back' : 'next';
182 var step_raw = parseInt( d.target_step, 10 );
183 var step_num = ( Number.isFinite( step_raw ) && step_raw > 0 )
184 ? step_raw
185 : ( dir === 'back' ? 1 : 2 );
186
187 var label_txt = ( typeof d.label === 'string' && d.label.trim().length )
188 ? d.label.trim()
189 : ( dir === 'back' ? 'Back' : 'Next' );
190
191 // HTML ID: sanitize + ensure uniqueness across the export.
192 var html_id = d.html_id ? sid( String( d.html_id ) ) : '';
193 if ( html_id && usedIds ) {
194 var base = html_id;
195 var candidate = base;
196 var i = 2;
197 while ( usedIds.has( candidate ) ) {
198 candidate = base + '_' + ( i++ );
199 }
200 usedIds.add( candidate );
201 html_id = candidate;
202 }
203
204 // Extra classes (in addition to required base wizard nav classes).
205 var extra_raw = String( d.cssclass_extra || d.cssclass || d.class || '' );
206 var extra_cls = scls( extra_raw );
207
208 var req_cls = 'wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_' + String( step_num );
209 var full_cls = req_cls + ( extra_cls ? ( ' ' + esc_html( extra_cls ) ) : '' );
210
211 var id_attr = html_id ? ( ' id="' + esc_html( html_id ) + '"' ) : '';
212
213 // Final anchor — no href (click is handled externally).
214 emit(
215 '<a class="' + full_cls + '"' + id_attr + '>' +
216 esc_html( label_txt ) +
217 '</a>'
218 );
219
220 // NOTE:
221 // - Help text (field.help) is output by WPBC_BFB_Exporter.render_field_node()
222 // beneath this block, same as for other packs.
223 } );
224 }
225
226 if ( w.WPBC_BFB_Exporter && typeof w.WPBC_BFB_Exporter.register === 'function' ) {
227 register_wizard_nav_booking_form_exporter();
228 } else if ( typeof document !== 'undefined' ) {
229 document.addEventListener(
230 'wpbc:bfb:exporter-ready',
231 register_wizard_nav_booking_form_exporter,
232 { once: true }
233 );
234 }
235
236
237 // -----------------------------------------------------------------------------------------------------------------
238 // Export for "Booking Data" (Content of booking fields data)
239 // -----------------------------------------------------------------------------------------------------------------
240 /**
241 * Booking Data exporter callback for "wizard_nav".
242 *
243 * Wizard navigation buttons do not carry user-entered values,
244 * so they are intentionally omitted from the "Content of booking fields data".
245 */
246 function register_wizard_nav_booking_data_exporter() {
247
248 var C = w.WPBC_BFB_ContentExporter;
249 if ( ! C || typeof C.register !== 'function' ) { return; }
250 if ( typeof C.has_exporter === 'function' && C.has_exporter( 'wizard_nav' ) ) { return; }
251
252 C.register( 'wizard_nav', function( field, emit, extras ) {
253 // Intentionally no output: nav buttons are not part of data template.
254 return;
255 } );
256 }
257
258 if ( w.WPBC_BFB_ContentExporter && typeof w.WPBC_BFB_ContentExporter.register === 'function' ) {
259 register_wizard_nav_booking_data_exporter();
260 } else if ( typeof document !== 'undefined' ) {
261 document.addEventListener(
262 'wpbc:bfb:content-exporter-ready',
263 register_wizard_nav_booking_data_exporter,
264 { once: true }
265 );
266 }
267
268 })( window );
269