PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 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 All 205 releases
booking / includes / page-form-builder / field-packs / time-range / field-rangetime-wptpl.php

field-rangetime-wptpl.php in Booking Calendar 11.9, at includes/page-form-builder/field-packs/time-range/field-rangetime-wptpl.php

642 lines 33.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WPBC BFB Pack: Range Time (time-slots).
4 *
5 * - Adds a "rangetime" field that renders dropdown options like: [selectbox rangetime "Label@@HH:MM - HH:MM" ...]
6 * - Labels can be AM/PM or 24h; values are always strict 24h ranges.
7 * - Inspector:
8 * - AM/PM </> 24H switch (radio)
9 * - Generator: Start/End + Duration: AM/PM uses native <input type="time">, 24H uses iMask.js
10 * - Options editor with rows that mirror the chosen format
11 * - Requires iMask.js (already loaded on the Builder page).
12 *
13 * @package Booking Calendar
14 * @author wpdevelop
15 * @since 11.0.0
16 * @modified 31.10.2025 13:54
17 * @version 1.7.1
18 */
19
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit;
22 }
23
24 /**
25 * Register the "rangetime" field pack.
26 *
27 * @param array $packs Packs map.
28 *
29 * @return array
30 */
31 /**
32 * Register the "rangetime" field pack.
33 *
34 * @param array $packs Packs map.
35 * @return array
36 */
37 function wpbc_bfb_register_field_packs__field_rangetime_wptpl( $packs ) {
38 $packs['rangetime'] = array(
39 'kind' => 'field',
40 'type' => 'rangetime',
41 'label' => __( 'Time slots', 'booking' ),
42 'icon' => 'wpbc-bi-clock',
43 'usage_key' => 'rangetime',
44
45 // Schema defines defaults and coercion.
46 'schema' => array(
47 'props' => array(
48 'label' => array( 'type' => 'string', 'default' => __( 'Time', 'booking' ) ),
49 'name' => array( 'type' => 'string', 'default' => 'rangetime' ),
50 'html_id' => array( 'type' => 'string', 'default' => '' ),
51 'required' => array( 'type' => 'boolean', 'default' => true ),
52 'multiple' => array( 'type' => 'boolean', 'default' => false ),
53 'size' => array( 'type' => 'number', 'default' => null, 'min' => 2, 'max' => 20 ),
54 'cssclass' => array( 'type' => 'string', 'default' => '' ),
55 'help' => array( 'type' => 'string', 'default' => '' ),
56 'default_value' => array( 'type' => 'string', 'default' => '' ),
57 'placeholder' => array( 'type' => 'string', 'default' => '--- ' . __( 'Select time', 'booking' ) . ' ---' ),
58 'value_differs' => array( 'type' => 'boolean', 'default' => true ),
59
60 // Options: label (string), value (string "HH:MM - HH:MM"), selected (bool).
61 'options' => array(
62 'type' => 'array',
63 'default' => array(
64 array( 'label' => '10:00 AM - 12:00 PM', 'value' => '10:00 - 12:00', 'selected' => false ),
65 array( 'label' => '12:00 PM - 02:00 PM', 'value' => '12:00 - 14:00', 'selected' => false ),
66 array( 'label' => '02:00 PM - 04:00 PM', 'value' => '14:00 - 16:00', 'selected' => false ),
67 array( 'label' => '04:00 PM - 06:00 PM', 'value' => '16:00 - 18:00', 'selected' => false ),
68 array( 'label' => '06:00 PM - 08:00 PM', 'value' => '18:00 - 20:00', 'selected' => false ),
69 ),
70 ),
71
72 // Generator controls:.
73 'gen_label_fmt' => array( 'type' => 'string', 'default' => 'ampm' ), // 'ampm' | '24h'
74 'gen_start_24h' => array( 'type' => 'string', 'default' => '09:00' ),
75 'gen_end_24h' => array( 'type' => 'string', 'default' => '18:00' ),
76 'gen_start_ampm_t' => array( 'type' => 'string', 'default' => '09:00' ),
77 // <input type=time> expects "HH:MM"
78 'gen_end_ampm_t' => array( 'type' => 'string', 'default' => '18:00' ),
79 'gen_step_h' => array( 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 12 ),
80 'gen_step_m' => array( 'type' => 'number', 'default' => 30, 'min' => 0, 'max' => 59 ),
81
82 'min_width' => array( 'type' => 'string', 'default' => '240px' ),
83 ),
84 ),
85
86 'templates_printer' => 'wpbc_bfb_field_rangetime_wptpl_print_templates',
87 );
88
89 return $packs;
90 }
91 add_filter( 'wpbc_bfb_register_field_packs', 'wpbc_bfb_register_field_packs__field_rangetime_wptpl' );
92
93
94 /**
95 * Enqueue the Range Time pack JS.
96 *
97 * @param string $page Current admin page slug.
98 * @return void
99 */
100 function wpbc_bfb_enqueue__field_rangetime_wptpl_js( $page ) {
101
102 // iMask.js is already enqueued on this page.
103 wp_enqueue_script( 'wpbc-bfb_field_rangetime_wptpl', wpbc_plugin_url( '/includes/page-form-builder/field-packs/time-range/_out/field-rangetime-wptpl.js' ), array( 'wp-util', 'wpbc-bfb', 'wpbc-bfb-time-utils' ), WP_BK_VERSION_NUM, true );
104 }
105 add_action( 'wpbc_enqueue_js_field_pack', 'wpbc_bfb_enqueue__field_rangetime_wptpl_js', 10, 1 );
106
107
108 /**
109 * Palette item (optional).
110 *
111 * @param string $group Group key.
112 * @param string $position Position.
113 * @return void
114 */
115 function wpbc_bfb_palette_register_items__rangetime_wptpl( $group, $position ) {
116 if ( 'times' !== $group || 'bottom' !== $position ) {
117 return;
118 }
119 $default_options = array(
120 array( 'label' => '10:00 AM - 12:00 PM', 'value' => '10:00 - 12:00', 'selected' => false ),
121 array( 'label' => '12:00 PM - 02:00 PM', 'value' => '12:00 - 14:00', 'selected' => false ),
122 array( 'label' => '02:00 PM - 04:00 PM', 'value' => '14:00 - 16:00', 'selected' => false ),
123 array( 'label' => '04:00 PM - 06:00 PM', 'value' => '16:00 - 18:00', 'selected' => false ),
124 array( 'label' => '06:00 PM - 08:00 PM', 'value' => '18:00 - 20:00', 'selected' => false ),
125 );
126 ?>
127 <li class="wpbc_bfb__field"
128 data-id="rangetime"
129 data-type="rangetime"
130 data-usage_key="rangetime"
131 data-usagenumber="1"
132 data-min_width="240px"
133 data-label="<?php echo esc_attr( __( 'Time slots', 'booking' ) ); ?>"
134 data-name="rangetime"
135 data-required="true"
136 data-autoname="0"
137 data-fresh="0"
138 data-name_user_touched="1"
139 data-options="<?php echo esc_attr( wp_json_encode( $default_options ) ); ?>">
140 <i class="menu_icon icon-1x wpbc_icn_access_time"></i>
141 <span class="wpbc_bfb__field-label"><?php echo esc_html( __( 'Time slots', 'booking' ) ); ?></span>
142 <span class="wpbc_bfb__field-type">rangetime</span>
143 </li>
144 <?php
145 }
146 add_action( 'wpbc_bfb_palette_register_items', 'wpbc_bfb_palette_register_items__rangetime_wptpl', 10, 2 );
147
148
149
150 /**
151 * Print wp.template() blocks (Preview + Inspector).
152 *
153 * @param string $page Builder page slug.
154 * @return void
155 */
156 function wpbc_bfb_field_rangetime_wptpl_print_templates( $page ) {
157
158 if ( WPBC_BFB_BUILDER_PAGE_SLUG !== $page ) {
159 return;
160 }
161
162 ?>
163 <script type="text/html" id="tmpl-wpbc-bfb-field-rangetime">
164 <span class="wpbc_bfb__noaction wpbc_bfb__no-drag-zone" inert="" style="min-width: {{ data.min_width || '240px' }}">
165 <# var is_req = ( true === data.required || 'true' === data.required || 1 === data.required || '1' === data.required ); #>
166 <# var is_mul = ( true === data.multiple || 'true' === data.multiple || 1 === data.multiple || '1' === data.multiple ); #>
167
168 <# if ( data.label && data.label !== '' ) { #>
169 <label class="wpbc_bfb__field-label" <# if ( data.html_id ) { #> for="{{ data.html_id }}" <# } #>>
170 {{ data.label }} <# if ( is_req ) { #><span aria-hidden="true">*</span><# } #>
171 </label>
172 <# } #>
173
174 <span class="wpbc_wrap_text wpdev-form-control-wrap">
175 <select
176 class="wpbc_bfb__preview-input wpbc_bfb__preview-select wpbc_bfb__preview-rangetime wpbc_bfb__preview-timepicker {{ data.cssclass || '' }}"
177 name="{{ (data.name || data.id || 'rangetime') + ( is_mul ? '[]' : '' ) }}"
178 tabindex="-1" aria-disabled="true"
179 <# if ( data.html_id ) { #> id="{{ data.html_id }}" <# } #>
180 <# if ( is_req ) { #> required aria-required="true" <# } #>
181 <# if ( is_mul ) { #> multiple <# } #>
182 <# if ( is_mul && data.size && isFinite( Number( data.size ) ) ) { #> size="{{ Number( data.size ) }}" <# } #>
183 >
184 <#
185 var has_marked = Array.isArray( data.options ) && data.options.some( function(o){
186 return !! o && ( true === o.selected || 'true' === o.selected || 1 === o.selected || '1' === o.selected );
187 } );
188 var has_text_default = ( ! is_mul ) && ( (data.default_value != null) && String( data.default_value ).trim() !== '' );
189 var has_any_default = has_marked || has_text_default;
190
191 var selected_set = {};
192 if ( has_marked ) {
193 ( data.options || [] ).forEach( function(o){
194 if ( o && ( true === o.selected || 'true' === o.selected || 1 === o.selected || '1' === o.selected ) ) {
195 selected_set[ String( o.value || '' ) ] = true;
196 }
197 } );
198 } else if ( is_mul ) {
199 String( data.default_value || '' ).split( /\s*,\s*/ ).filter( function(s){ return s.length; } )
200 .forEach( function(v){ selected_set[ v ] = true; } );
201 } else if ( has_text_default ) {
202 selected_set[ String( data.default_value ) ] = true;
203 }
204 #>
205
206 <# if ( ! is_mul && data.placeholder && ! has_any_default ) { #>
207 <option value="" selected="selected" disabled="disabled">{{ data.placeholder }}</option>
208 <# } #>
209
210 <#
211 var _opts = Array.isArray( data.options ) ? data.options
212 : ( function(o){ var a=[],k; for ( k in (o||{}) ){ if ( Object.prototype.hasOwnProperty.call(o,k) ){ a.push( o[k] ); } } return a; } )( data.options );
213 _opts.forEach( function( opt ){
214 if ( ! opt ) { return; }
215 var _val = String( opt.value || '' );
216 var _lbl = String( opt.label || '' );
217 var _sel = !! selected_set[ _val ];
218 #>
219 <option value="{{ _val }}" <# if ( _sel ) { #> selected <# } #> >{{ _lbl }}</option>
220 <# }); #>
221 </select>
222 </span>
223
224 <# if ( data.help ) { #>
225 <div class="wpbc_bfb__help">{{ data.help }}</div>
226 <# } #>
227 </span>
228 </script>
229
230 <script type="text/html" id="tmpl-wpbc-bfb-inspector-rangetime">
231 <style type="text/css">
232 .wpbc_admin .wpbc_ui_el__vert_right_bar__wrapper:has(.wpbc_bfb__inspector_timepicker) {
233 --wpbc_ui_left_vert_nav__width_max: Min(580px, 100%);
234 }
235 </style>
236 <div class="wpbc_bfb__inspector_rangetime wpbc_bfb__inspector_timepicker" data-type="rangetime"
237 data-i18n-add="<?php echo esc_attr__( 'Add New', 'booking' ); ?>"
238 data-i18n-duplicate="<?php echo esc_attr__( 'Duplicate', 'booking' ); ?>"
239 data-i18n-remove="<?php echo esc_attr__( 'Remove', 'booking' ); ?>"
240 data-i18n-default="<?php echo esc_attr__( 'Default', 'booking' ); ?>"
241 data-i18n-reorder="<?php echo esc_attr__( 'Drag to reorder', 'booking' ); ?>"
242 data-i18n-rowlabel="<?php echo esc_attr__( 'Label (e.g. 10:00 AM - 10:30 AM)', 'booking' ); ?>"
243 >
244 <div class="wpbc_bfb__inspector__head">
245 <div class="header_container">
246 <div class="header_title_content">
247 <h3 class="title"><?php echo esc_html__( 'Time slots', 'booking' ); ?></h3>
248 <div class="desc"><?php echo esc_html__( 'Use the "Generate time slots" form to quickly create a list of time slots.', 'booking' ); ?></div>
249 </div>
250 <div class="actions wpbc_ajx_toolbar wpbc_no_borders">
251 <div class="ui_container ui_container_small">
252 <div class="ui_group">
253 <div class="ui_element">
254 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button" data-action="deselect" aria-label="<?php echo esc_attr__( 'Deselect', 'booking' ); ?>">
255 <i class="menu_icon icon-1x wpbc_icn_rotate_270 wpbc_icn_near_me_disabled"></i>
256 </button>
257 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button" data-action="scrollto" aria-label="<?php echo esc_attr__( 'Scroll to field', 'booking' ); ?>">
258 <i class="menu_icon icon-1x wpbc_icn_ads_click filter_center_focus"></i>
259 </button>
260 </div>
261 <div class="ui_element">
262 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button" data-action="move-up" aria-label="<?php echo esc_attr__( 'Move up', 'booking' ); ?>">
263 <i class="menu_icon icon-1x wpbc_icn_arrow_upward"></i>
264 </button>
265 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button" data-action="move-down" aria-label="<?php echo esc_attr__( 'Move down', 'booking' ); ?>">
266 <i class="menu_icon icon-1x wpbc_icn_arrow_downward"></i>
267 </button>
268 </div>
269 <div class="ui_element">
270 <?php /* ?>
271 <button data-action="duplicate" aria-label="<?php echo esc_attr__( 'Duplicate', 'booking' ); ?>" type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button">
272 <i class="menu_icon icon-1x wpbc_icn_content_copy"></i>
273 </button>
274 <?php */ ?>
275 <button data-action="delete" aria-label="<?php echo esc_attr__( 'Delete', 'booking' ); ?>" type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button wpbc_ui_button_danger button-link-delete">
276 <span class="in-button-text"><?php echo esc_html__( 'Delete', 'booking' ); ?></span>&nbsp;&nbsp;<i class="menu_icon icon-1x wpbc_icn_delete_outline"></i>
277 </button>
278 </div>
279 </div><!-- .ui_group -->
280 </div><!-- .ui_container -->
281 </div><!-- .actions -->
282
283 </div><!-- .header_container -->
284 </div><!-- .wpbc_bfb__inspector__head -->
285
286 <div class="wpbc_bfb__inspector__body">
287 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="basic">
288 <button type="button" class="group__header">
289 <h3><?php echo esc_html__( 'Basic', 'booking' ); ?></h3>
290 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
291 </button>
292 <div class="group__fields">
293 <div class="inspector__row">
294 <label class="inspector__label"><?php echo esc_html__( 'Label', 'booking' ); ?></label>
295 <div class="inspector__control">
296 <input type="text" class="inspector__input" data-inspector-key="label" value="{{ data.label || '<?php echo esc_js( __( 'Time', 'booking' ) ); ?>' }}">
297 </div>
298 </div>
299
300 <div class="inspector__row">
301 <label class="inspector__label"><?php echo esc_html__( 'Name', 'booking' ); ?></label>
302 <div class="inspector__control">
303 <?php
304 // Visible (disabled) field so users see it's fixed.
305 ?>
306 <input type="text"
307 class="inspector__input"
308 value="{{ (data.name && data.name !== '' ? data.name : 'rangetime') }}"
309 disabled="disabled"
310 aria-disabled="true">
311
312 <?php
313 // Hidden proxy that the Builder actually saves.
314 // Keep data-inspector-key on a non-disabled control.
315 ?>
316 <input type="hidden"
317 class="inspector__input js-locked-name"
318 data-inspector-key="name"
319 data-locked="1"
320 value="{{ (data.name && data.name !== '' ? data.name : 'rangetime') }}">
321
322 <p class="wpbc_bfb__help" style="margin-top:6px;">
323 <?php echo esc_html__( 'This field name is fixed for compatibility.', 'booking' ); ?>
324 </p>
325 </div>
326 </div>
327
328 <?php /* ?>
329 <div class="inspector__row">
330 <label class="inspector__label"><?php echo esc_html__( 'Required', 'booking' ); ?></label>
331 <div class="inspector__control">
332 <input type="checkbox" class="inspector__checkbox" data-inspector-key="required" <# if ( true === data.required || 'true' === data.required || 1 === data.required || '1' === data.required ) { #> checked <# } #> >
333 </div>
334 </div>
335 <?php */ ?>
336
337 <div class="inspector__row">
338 <div class="inspector__control ">
339 <span class="wpbc_ui__toggle">
340 <!-- Visible indicator: checked + disabled (tell normalizer to skip) -->
341 <# var input_id = window.WPBC_BFB_Core.UI.WPBC_BFB_Toggle_Normalizer.generate_unique_id( 'wpbc_ins_auto_' + 'toggle_required' + '_' ); #>
342 <input type="checkbox" id="{{input_id}}" class="inspector__checkbox js-required-visible" checked disabled aria-disabled="true" data-wpbc-ui-no-toggle="1">
343 <label class="wpbc_ui__toggle_icon" for="{{input_id}}"></label>
344 <label class="wpbc_ui__toggle_label" for="{{input_id}}"><?php echo esc_html__( 'Required', 'booking' ); ?></label>
345 </span>
346 <!-- PROXY for data binding (already skipped via flags) -->
347 <input type="checkbox" class="inspector__checkbox js-required-proxy" data-inspector-key="required" data-locked="1" checked data-wpbc-ui-no-toggle="1"
348 style="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;">
349 <p class="wpbc_bfb__help" style="margin-inline-start:1em;display: inline-block;"><?php echo esc_html__( 'This field is always required.', 'booking' ); ?></p>
350 </div>
351 </div>
352
353 <div class="inspector__row">
354 <label class="inspector__label"><?php echo esc_html__( 'Help text', 'booking' ); ?></label>
355 <div class="inspector__control">
356 <textarea class="inspector__textarea" rows="3" data-inspector-key="help">{{ data.help || '' }}</textarea>
357 </div>
358 </div>
359 </div>
360 </section>
361
362 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group is-open" data-group="options">
363 <button type="button" class="group__header">
364 <h3><?php echo esc_html__( 'Time slots', 'booking' ); ?></h3>
365 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
366 </button>
367
368 <div class="group__fields inspector__group__fields__times">
369
370 <?php /* ===== Generator ===== */ ?>
371 <div class="inspector__row">
372 <div class="inspector__control inspector__control__generator_timeslots">
373
374 <# var __fmt_name = 'rt_label_fmt_' + ( data.html_id ? data.html_id : ( 'id_' + String( Math.random() ).slice(2) ) ); #>
375 <h2><?php echo esc_html__( 'Generate time slots', 'booking' ); ?></h2>
376 <div class="wpbc_bfb__rt_gen_format wpbc_inline_inputs" role="radiogroup" aria-label="<?php echo esc_attr__( 'Time format', 'booking' ); ?>">
377 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'Time format', 'booking' ); ?>:</label>
378 <div class="wpbc_inline_inputs inspector__w_70">
379 <?php /*
380 * PROXY input (single source-of-truth) so the core inspector serializer sees exactly one element
381 * with this key. Radios below are UI only and update this hidden value.
382 */ ?>
383 <input type="hidden"
384 class="inspector__input js-rt-label-fmt-value"
385 data-inspector-key="gen_label_fmt"
386 value="{{ data.gen_label_fmt || 'ampm' }}">
387
388 <# var __fmt_name = 'rt_label_fmt_' + ( data.html_id ? data.html_id : ( 'id_' + String( Math.random() ).slice(2) ) ); #>
389
390 <label>
391 <input type="radio"
392 name="{{ __fmt_name }}"
393 class="js-rt-label-fmt"
394 value="ampm"
395 <# if ( (data.gen_label_fmt||'ampm') === 'ampm' ) { #> checked <# } #> >
396 <?php echo esc_html__( 'AM/PM', 'booking' ); ?>
397 </label>
398 &nbsp;&nbsp;
399 <label>
400 <input type="radio"
401 name="{{ __fmt_name }}"
402 class="js-rt-label-fmt"
403 value="24h"
404 <# if ( data.gen_label_fmt === '24h' ) { #> checked <# } #> >
405 <?php echo esc_html__( '24H', 'booking' ); ?>
406 </label>
407 </div>
408 </div>
409
410
411 <div class="wpbc_bfb__rt_gen_times" style="margin-top:8px;">
412
413 <!-- 24H group (masked text inputs) -->
414 <div class="js-rt-24h wpbc_inline_inputs" <# if ( (data.gen_label_fmt||'ampm') === 'ampm' ) { #> style="display:none" hidden aria-hidden="true" <# } #>>
415 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'From / To', 'booking' ); ?>:</label>
416 <div class="wpbc_inline_inputs inspector__w_70">
417 <div class="inspector__control inspector__w_45">
418 <input type="text" class="inspector__input inspector__w_25 js-rt-mask js-gen-start-24h" data-mask-kind="24h" placeholder="HH:MM" data-inspector-key="gen_start_24h" value="{{ data.gen_start_24h || '09:00' }}">
419 </div>
420 <div class="inspector__control inspector__w_10" style="text-align: center;font-size: 18px;line-height: 2;font-weight: 700;">&ndash;</div>
421 <div class="inspector__control inspector__w_45">
422 <input type="text" class="inspector__input inspector__w_25 js-rt-mask js-gen-end-24h" data-mask-kind="24h" placeholder="HH:MM" data-inspector-key="gen_end_24h" value="{{ data.gen_end_24h || '18:00' }}">
423 </div>
424 </div>
425 </div>
426
427 <!-- AM/PM group (native time inputs) -->
428 <div class="js-rt-ampm wpbc_inline_inputs" <# if ( (data.gen_label_fmt||'ampm') !== 'ampm' ) { #> style="display:none" hidden aria-hidden="true" <# } #>>
429 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'From / To', 'booking' ); ?>:</label>
430 <div class="wpbc_inline_inputs inspector__w_70">
431 <div class="inspector__control inspector__w_45">
432 <input type="time" class="inspector__input inspector__w_25 js-gen-start-ampm-time" step="300" data-inspector-key="gen_start_ampm_t" value="{{ data.gen_start_ampm_t || '09:00' }}">
433 </div>
434 <div class="inspector__control inspector__w_10" style="text-align: center;font-size: 18px;line-height: 2;font-weight: 700;">&ndash;</div>
435 <div class="inspector__control inspector__w_45">
436 <input type="time" class="inspector__input inspector__w_25 js-gen-end-ampm-time" step="300" data-inspector-key="gen_end_ampm_t" value="{{ data.gen_end_ampm_t || '18:00' }}">
437 </div>
438 </div>
439 </div>
440 </div>
441
442 <div class="wpbc_bfb__rt_gen_step wpbc_inline_inputs">
443 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'Duration', 'booking' ); ?></label>
444 <div class="wpbc_len_group wpbc_inline_inputs inspector__w_70" data-len-group="rt-step-hours">
445 <div class="inspector__control inspector__w_10"><?php echo esc_html__( 'hours', 'booking' ); ?>:</div>
446 <input data-len-range type="range" class="inspector__input js-gen-step-h-range" min="0" max="12" step="1" value="{{ data.gen_step_h || 0 }}">
447 <input data-len-value type="number" class="inspector__input inspector__w_30 js-gen-step-h" data-inspector-key="gen_step_h" min="0" max="12" step="1" value="{{ data.gen_step_h || 0 }}">
448 </div>
449 </div>
450
451 <div class="wpbc_bfb__rt_gen_step wpbc_inline_inputs">
452 <label class="inspector__label inspector__w_30"></label>
453 <div class="wpbc_len_group wpbc_inline_inputs inspector__w_70" data-len-group="rt-step-minutes">
454 <div class="inspector__control inspector__w_10"><?php echo esc_html__( 'minutes', 'booking' ); ?>:</div>
455 <input data-len-range type="range" class="inspector__input js-gen-step-m-range" min="0" max="59" step="5" value="{{ data.gen_step_m || 30 }}">
456 <input data-len-value type="number" class="inspector__input inspector__w_30 js-gen-step-m" data-inspector-key="gen_step_m" min="0" max="59" step="5" value="{{ data.gen_step_m || 30 }}">
457 </div>
458 </div>
459
460 <div class="wpbc_bfb__options_toolbar wpbc_inline_inputs">
461 <div class="inspector__control inspector__w_100" style="text-align: center;">
462 <button type="button" class="button button-primary js-rt-generate"><?php echo esc_html__( 'Generate time slots', 'booking' ); ?> <i class="menu_icon icon-1x wpbc_icn_arrow_downward" aria-hidden="true"></i></button>
463 </div>
464 </div>
465
466 </div>
467 </div>
468
469 <?php /* ===== Options editor ===== */ ?>
470 <div class="inspector__row wpbc_bfb__options_editor">
471 <div class="wpbc_bfb__options_list__header">
472 <div class="wpbc_bfb__header_col__drag-handle"></div>
473 <div class="wpbc_bfb__header_col__label"><?php echo esc_html__( 'Label', 'booking' ) . ' (' . esc_html__( 'any text', 'booking' ) . ')'; ?></div>
474 <div class="wpbc_bfb__header_col__value" style="flex: 150px;"><?php echo esc_html__( 'Time slot', 'booking' ); ?></div>
475 <div class="wpbc_bfb__header_col__action"></div>
476 </div>
477 <div class="wpbc_bfb__options_list">
478 <#
479 var _opts2 = Array.isArray( data.options ) ? data.options
480 : ( function(o){ var a=[],k; for ( k in (o || {}) ) { if ( Object.prototype.hasOwnProperty.call( o, k ) ) { a.push( o[ k ] ); } } return a; } )( data.options );
481 #>
482
483 <# _opts2.forEach( function( opt, idx ){
484 var _val = String( opt && opt.value || '' );
485 var _parts = _val.split( /\s*-\s*/ );
486 var __start = _parts[0] || '';
487 var __end = _parts[1] || '';
488 var __uid = 'wpbc_ins_rt_' + Math.random().toString(36).slice(2,10);
489 var __sel = !!( opt && ( true === opt.selected || 'true' === opt.selected || 1 === opt.selected || '1' === opt.selected ) );
490 #>
491 <div class="wpbc_bfb__options_row" data-index="{{ idx }}">
492 <span class="wpbc_bfb__drag-handle" title="<?php echo esc_attr__( 'Drag to reorder', 'booking' ); ?>"><span class="wpbc_icn_drag_indicator"></span></span>
493
494 <input type="text" class="wpbc_bfb__opt-label" placeholder="<?php echo esc_attr__( 'Label (e.g. 10:00 AM - 10:30 AM)', 'booking' ); ?>" value="{{ opt && opt.label || '' }}">
495
496 <# if ( (data.gen_label_fmt||'ampm') === '24h' ) { #>
497 <input type="text" class="wpbc_bfb__opt-start js-rt-mask" data-mask-kind="24h" placeholder="HH:MM" value="{{ __start }}">
498 <span class="wpbc_bfb__opt-sep" aria-hidden="true">-</span>
499 <input type="text" class="wpbc_bfb__opt-end js-rt-mask" data-mask-kind="24h" placeholder="HH:MM" value="{{ __end }}">
500 <# } else { #>
501 <input type="time" class="wpbc_bfb__opt-start js-rt-start-time" step="300" value="{{ __start }}">
502 <span class="wpbc_bfb__opt-sep" aria-hidden="true">-</span>
503 <input type="time" class="wpbc_bfb__opt-end js-rt-end-time" step="300" value="{{ __end }}">
504 <# } #>
505
506 <input type="text" class="wpbc_bfb__opt-value" value="{{ _val }}" hidden>
507
508 <div class="wpbc_bfb__opt-selected">
509 <div class="inspector__control wpbc_ui__toggle">
510 <input type="checkbox" class="wpbc_bfb__opt-selected-chk inspector__input" id="{{ __uid }}" role="switch" aria-checked="{{ __sel ? 'true' : 'false' }}" <# if ( __sel ) { #> checked <# } #> >
511 <label class="wpbc_ui__toggle_icon_radio" for="{{ __uid }}"></label>
512 <label class="wpbc_ui__toggle_label" for="{{ __uid ?>"><?php echo esc_js( __( 'Default', 'booking' ) ); ?></label>
513 </div>
514 </div>
515
516 <div class="wpbc_ui_el wpbc_ui_el_container wpbc_ui_el__dropdown">
517 <a href="javascript:void(0)" data-toggle="wpbc_dropdown" aria-expanded="false" class="ul_dropdown_menu_toggle">
518 <i class="menu_icon icon-1x wpbc_icn_more_vert"></i>
519 </a>
520 <ul class="ul_dropdown_menu" role="menu" style="right:0px; left:auto;">
521 <li><a class="ul_dropdown_menu_li_action rt_dropdown_action" data-rt-action="add_after" href="javascript:void(0)"><?php echo esc_html__( 'Add New', 'booking' ); ?><i class="menu_icon icon-1x wpbc_icn_add_circle"></i></a></li>
522 <li><a class="ul_dropdown_menu_li_action rt_dropdown_action" data-rt-action="duplicate" href="javascript:void(0)"><?php echo esc_html__( 'Duplicate', 'booking' ); ?><i class="menu_icon icon-1x wpbc_icn_content_copy"></i></a></li>
523 <li class="divider"></li>
524 <li><a class="ul_dropdown_menu_li_action rt_dropdown_action" data-rt-action="remove" href="javascript:void(0)"><?php echo esc_html__( 'Remove', 'booking' ); ?><i class="menu_icon icon-1x wpbc_icn_delete_outline"></i></a></li>
525 </ul>
526 </div>
527 </div>
528 <# }); #>
529 </div>
530
531 <div class="wpbc_bfb__options_toolbar ">
532 <small class="desc"><?php echo esc_html__( 'Drag by handle to reorder. For single-select, only one “Default” can be checked.', 'booking' ); ?></small>
533 <div class="wpbc_bfb__options_toolbar wpbc_inline_inputs">
534 <div class="inspector__control inspector__w_15">
535 <button type="button" class="button js-rt-clear"><?php
536 echo esc_html__( 'Clear all', 'booking' ); ?></button>
537 </div>
538 <div class="inspector__control inspector__w_85">
539 <button type="button" class="button button-secondary js-rt-add-option">
540 <i class="wpbc_ui_el__vert_nav_icon tooltip_right_offset menu_icon icon-1x wpbc_icn_add_circle" aria-hidden="true"></i>
541 <?php echo esc_html__( 'Add time slot', 'booking' ); ?>
542 </button>
543 </div>
544 </div>
545 </div>
546
547 <#
548 var __json = JSON.stringify(_opts2 || []);
549 __json = __json.replace(/<\/textarea/gi, '<\\/textarea');
550 #>
551 <textarea class="wpbc_bfb__options_state inspector__input" data-inspector-key="options" hidden>{{ __json }}</textarea>
552 </div>
553
554
555 <div class="inspector__row js-placeholder-row">
556 <label class="inspector__label"><?php echo esc_html__( 'Placeholder (single only)', 'booking' ); ?></label>
557 <div class="inspector__control">
558 <input type="text" class="inspector__input js-placeholder" data-inspector-key="placeholder" value="{{ data.placeholder || '<?php echo '--- ' . esc_js( __( 'Select time', 'booking' ) ) . ' ---'; ?>' }}">
559 <p class="wpbc_bfb__help js-placeholder-note" style="margin-top:6px; display:none;"><?php echo esc_html__( 'Placeholder is used only for single-select when no default is set.', 'booking' ); ?></p>
560 </div>
561 </div>
562 <?php /* ?>
563 <div class="inspector__row">
564 <label class="inspector__label"><?php echo esc_html__( 'Allow multiple selection', 'booking' ); ?></label>
565 <div class="inspector__control">
566 <input type="checkbox" class="inspector__checkbox js-opt-multiple" data-inspector-key="multiple"
567 <# if ( true === data.multiple || 'true' === data.multiple || 1 === data.multiple || '1' === data.multiple ) { #> checked <# } #> >
568 </div>
569 </div>
570
571 <div class="inspector__row">
572 <label class="inspector__label"><?php echo esc_html__( 'Size (rows, for multiple)', 'booking' ); ?></label>
573 <div class="inspector__control">
574 <div class="wpbc_len_group wpbc_inline_inputs" data-len-group="select-size-rows">
575 <input data-len-range type="range" class="inspector__input" min="2" max="20" step="1" value="{{ data.size || '' }}">
576 <input data-len-value type="number" class="inspector__input inspector__w_30" data-inspector-key="size" min="2" max="20" value="{{ data.size || '' }}">
577 </div>
578 </div>
579 </div>
580 <?php */ ?>
581
582
583
584 </div>
585 </section>
586
587 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="appearance">
588 <button type="button" class="group__header">
589 <h3><?php echo esc_html__( 'Appearance', 'booking' ); ?></h3>
590 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
591 </button>
592 <div class="group__fields">
593 <?php wpbc_bfb_time_picker__print_inspector_group(); ?>
594
595 <div class="inspector__row">
596 <label class="inspector__label"><?php echo esc_html__( 'CSS class', 'booking' ); ?></label>
597 <div class="inspector__control">
598 <input type="text" class="inspector__input" data-inspector-key="cssclass" value="{{ data.cssclass || '' }}">
599 </div>
600 </div>
601
602 <div class="inspector__row">
603 <label class="inspector__label"><?php echo esc_html__( 'HTML ID', 'booking' ); ?></label>
604 <div class="inspector__control">
605 <input type="text" class="inspector__input" data-inspector-key="html_id" value="{{ data.html_id || '' }}">
606 </div>
607 </div>
608
609 <div class="inspector__row">
610 <label class="inspector__label"><?php echo esc_html__( 'Min width', 'booking' ); ?></label>
611 <div class="inspector__control">
612 <input type="text" class="inspector__input" data-inspector-key="min_width" placeholder="240px" value="{{ data.min_width || '240px' }}">
613 </div>
614 </div>
615 </div>
616 </section>
617
618 <?php /* ?>
619 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="advanced">
620 <button type="button" class="group__header">
621 <h3><?php echo esc_html__( 'Advanced', 'booking' ); ?></h3>
622 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
623 </button>
624 <div class="group__fields">
625 <div class="inspector__row">
626 <label class="inspector__label"><?php echo esc_html__( 'Default (value or CSV for multiple)', 'booking' ); ?></label>
627 <div class="inspector__control">
628 <input type="text" class="inspector__input js-default-value" data-inspector-key="default_value" value="{{ data.default_value || '' }}">
629 <p class="wpbc_bfb__help js-default-value-note" style="margin-top:6px; display:none;"><?php echo esc_html__( 'Clear row defaults to use the text field.', 'booking' ); ?></p>
630 </div>
631 </div>
632 </div>
633 </section>
634 <?php */ ?>
635
636 </div><!-- .wpbc_bfb__inspector__body -->
637 </div><!-- .wpbc_bfb__inspector_rangetime wpbc_bfb__inspector_timepicker-->
638 </script>
639
640 <?php
641 }
642