PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
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-start / field-starttime-wptpl.php

field-starttime-wptpl.php in Booking Calendar 11.8, at includes/page-form-builder/field-packs/time-start/field-starttime-wptpl.php

551 lines 29.1 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: Start Time (single time points).
4 *
5 * - Adds a "starttime" field that renders dropdown options like:
6 * [selectbox starttime "08:00" "09:00" ... ]
7 * - Labels can be AM/PM or 24h; values are always strict "HH:MM" (24h).
8 * - Inspector:
9 * - AM/PM </> 24H switch (radio)
10 * - Generator: From/To + Duration (step) -> builds single time points
11 * - Options editor with rows that mirror the chosen format
12 * - Respects global "Show as time picker" toggle used by time-based fields.
13 * - Requires iMask.js (already loaded on the Builder page) for 24h masking.
14 *
15 * @package Booking Calendar
16 * @author wpdevelop
17 * @since 11.0.0
18 * @modified 31.10.2025 16:45
19 * @version 1.0.0
20 */
21
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26
27 /**
28 * Register the "starttime" field pack (AM/PM labels by default).
29 *
30 * @param array $packs Packs map.
31 * @return array
32 */
33 function wpbc_bfb_register_field_packs__field_starttime_wptpl( $packs ) {
34 $packs['starttime'] = array(
35 'kind' => 'field',
36 'type' => 'starttime',
37 'label' => __( 'Start time', 'booking' ),
38 'icon' => 'wpbc-bi-clock',
39 'usage_key' => 'starttime',
40
41 'schema' => array(
42 'props' => array(
43 'label' => array( 'type' => 'string', 'default' => __( 'Start time', 'booking' ) ),
44 'name' => array( 'type' => 'string', 'default' => 'starttime' ),
45 'html_id' => array( 'type' => 'string', 'default' => '' ),
46 'required' => array( 'type' => 'boolean', 'default' => true ),
47 'multiple' => array( 'type' => 'boolean', 'default' => false ),
48 'size' => array( 'type' => 'number', 'default' => null, 'min' => 2, 'max' => 20 ),
49 'cssclass' => array( 'type' => 'string', 'default' => '' ),
50 'help' => array( 'type' => 'string', 'default' => '' ),
51 'default_value' => array( 'type' => 'string', 'default' => '' ),
52 'placeholder' => array( 'type' => 'string', 'default' => '--- ' . __( 'Select time', 'booking' ) . ' ---' ),
53 'value_differs' => array( 'type' => 'boolean', 'default' => true ),
54
55 // AM/PM labels, 24h values.
56 'options' => array(
57 'type' => 'array',
58 'default' => array(
59 array( 'label' => '08:00 AM', 'value' => '08:00', 'selected' => false ),
60 array( 'label' => '09:00 AM', 'value' => '09:00', 'selected' => false ),
61 array( 'label' => '10:00 AM', 'value' => '10:00', 'selected' => false ),
62 array( 'label' => '11:00 AM', 'value' => '11:00', 'selected' => false ),
63 array( 'label' => '12:00 PM', 'value' => '12:00', 'selected' => false ),
64 array( 'label' => '01:00 PM', 'value' => '13:00', 'selected' => false ),
65 array( 'label' => '02:00 PM', 'value' => '14:00', 'selected' => false ),
66 array( 'label' => '03:00 PM', 'value' => '15:00', 'selected' => false ),
67 array( 'label' => '04:00 PM', 'value' => '16:00', 'selected' => false ),
68 array( 'label' => '05:00 PM', 'value' => '17:00', 'selected' => false ),
69 array( 'label' => '06:00 PM', 'value' => '18:00', 'selected' => false ),
70 array( 'label' => '07:00 PM', 'value' => '19:00', 'selected' => false ),
71 array( 'label' => '08:00 PM', 'value' => '20:00', 'selected' => false ),
72 array( 'label' => '09:00 PM', 'value' => '21:00', 'selected' => false ),
73 array( 'label' => '10:00 PM', 'value' => '22:00', 'selected' => false ),
74 ),
75 ),
76
77 // Generator defaults -> AM/PM initially.
78 'gen_label_fmt' => array( 'type' => 'string', 'default' => 'ampm' ), // 'ampm' | '24h'
79 'gen_start_24h' => array( 'type' => 'string', 'default' => '08:00' ),
80 'gen_end_24h' => array( 'type' => 'string', 'default' => '22:00' ),
81 'gen_start_ampm_t' => array( 'type' => 'string', 'default' => '08:00' ),
82 'gen_end_ampm_t' => array( 'type' => 'string', 'default' => '22:00' ),
83 'gen_step_h' => array( 'type' => 'number', 'default' => 1, 'min' => 0, 'max' => 12 ),
84 'gen_step_m' => array( 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 59 ),
85
86 'min_width' => array( 'type' => 'string', 'default' => '180px' ),
87 ),
88 ),
89
90 'templates_printer' => 'wpbc_bfb_field_starttime_wptpl_print_templates',
91 );
92
93 return $packs;
94 }
95 add_filter( 'wpbc_bfb_register_field_packs', 'wpbc_bfb_register_field_packs__field_starttime_wptpl' );
96
97 /**
98 * Palette item defaults — AM/PM labels, 24h values.
99 *
100 * @param string $group Group key.
101 * @param string $position Position key.
102 * @return void
103 */
104 function wpbc_bfb_palette_register_items__starttime_wptpl( $group, $position ) {
105 if ( 'times' !== $group || 'bottom' !== $position ) {
106 return;
107 }
108
109 $default_options = array(
110 array( 'label' => '08:00 AM', 'value' => '08:00', 'selected' => false ),
111 array( 'label' => '09:00 AM', 'value' => '09:00', 'selected' => false ),
112 array( 'label' => '10:00 AM', 'value' => '10:00', 'selected' => false ),
113 array( 'label' => '11:00 AM', 'value' => '11:00', 'selected' => false ),
114 array( 'label' => '12:00 PM', 'value' => '12:00', 'selected' => false ),
115 array( 'label' => '01:00 PM', 'value' => '13:00', 'selected' => false ),
116 array( 'label' => '02:00 PM', 'value' => '14:00', 'selected' => false ),
117 array( 'label' => '03:00 PM', 'value' => '15:00', 'selected' => false ),
118 array( 'label' => '04:00 PM', 'value' => '16:00', 'selected' => false ),
119 array( 'label' => '05:00 PM', 'value' => '17:00', 'selected' => false ),
120 array( 'label' => '06:00 PM', 'value' => '18:00', 'selected' => false ),
121 array( 'label' => '07:00 PM', 'value' => '19:00', 'selected' => false ),
122 array( 'label' => '08:00 PM', 'value' => '20:00', 'selected' => false ),
123 array( 'label' => '09:00 PM', 'value' => '21:00', 'selected' => false ),
124 array( 'label' => '10:00 PM', 'value' => '22:00', 'selected' => false ),
125 );
126 ?>
127 <li class="wpbc_bfb__field"
128 data-id="starttime"
129 data-type="starttime"
130 data-usage_key="starttime"
131 data-usagenumber="1"
132 data-min_width="180px"
133 data-label="<?php echo esc_attr( __( 'Start time', 'booking' ) ); ?>"
134 data-name="starttime"
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_restore"></i>
141 <span class="wpbc_bfb__field-label"><?php echo esc_html( __( 'Start time', 'booking' ) ); ?></span>
142 <span class="wpbc_bfb__field-type">starttime</span>
143 </li>
144 <?php
145 }
146 add_action( 'wpbc_bfb_palette_register_items', 'wpbc_bfb_palette_register_items__starttime_wptpl', 10, 2 );
147
148
149 /**
150 * Enqueue the Start Time pack JS.
151 *
152 * @param string $page Current admin page slug.
153 * @return void
154 */
155 function wpbc_bfb_enqueue__field_starttime_wptpl_js( $page ) {
156 // iMask.js is already enqueued on this page.
157 wp_enqueue_script(
158 'wpbc-bfb_field_starttime_wptpl',
159 wpbc_plugin_url( '/includes/page-form-builder/field-packs/time-start/_out/field-starttime-wptpl.js' ),
160 array( 'wp-util', 'wpbc-bfb', 'wpbc-bfb-time-utils' ),
161 WP_BK_VERSION_NUM,
162 true
163 );
164 }
165 add_action( 'wpbc_enqueue_js_field_pack', 'wpbc_bfb_enqueue__field_starttime_wptpl_js', 10, 1 );
166
167
168 /**
169 * Print wp.template() blocks (Preview + Inspector) for Start Time.
170 *
171 * @param string $page Builder page slug.
172 * @return void
173 */
174 function wpbc_bfb_field_starttime_wptpl_print_templates( $page ) {
175
176 if ( WPBC_BFB_BUILDER_PAGE_SLUG !== $page ) {
177 return;
178 }
179
180 ?>
181 <script type="text/html" id="tmpl-wpbc-bfb-field-starttime">
182 <span class="wpbc_bfb__noaction wpbc_bfb__no-drag-zone" inert="" style="min-width: {{ data.min_width || '180px' }}">
183 <# var is_req = ( true === data.required || 'true' === data.required || 1 === data.required || '1' === data.required ); #>
184
185 <# if ( data.label && data.label !== '' ) { #>
186 <label class="wpbc_bfb__field-label" <# if ( data.html_id ) { #> for="{{ data.html_id }}" <# } #>>
187 {{ data.label }} <# if ( is_req ) { #><span aria-hidden="true">*</span><# } #>
188 </label>
189 <# } #>
190
191 <span class="wpbc_wrap_text wpdev-form-control-wrap">
192 <select
193 class="wpbc_bfb__preview-input wpbc_bfb__preview-select wpbc_bfb__preview-starttime wpbc_bfb__preview-timepicker {{ data.cssclass || '' }}"
194 name="{{ (data.name || data.id || 'starttime') }}"
195 tabindex="-1" aria-disabled="true"
196 <# if ( data.html_id ) { #> id="{{ data.html_id }}" <# } #>
197 <# if ( is_req ) { #> required aria-required="true" <# } #>
198 >
199 <#
200 var has_marked = Array.isArray( data.options ) && data.options.some( function(o){
201 return !! o && ( true === o.selected || 'true' === o.selected || 1 === o.selected || '1' === o.selected );
202 } );
203 var has_text_default = ( (data.default_value != null) && String( data.default_value ).trim() !== '' );
204 var has_any_default = has_marked || has_text_default;
205
206 var selected_set = {};
207 if ( has_marked ) {
208 ( data.options || [] ).forEach( function(o){
209 if ( o && ( true === o.selected || 'true' === o.selected || 1 === o.selected || '1' === o.selected ) ) {
210 selected_set[ String( o.value || '' ) ] = true;
211 }
212 } );
213 } else if ( has_text_default ) {
214 selected_set[ String( data.default_value ) ] = true;
215 }
216 #>
217
218 <# if ( data.placeholder && ! has_any_default ) { #>
219 <option value="" selected="selected" disabled="disabled">{{ data.placeholder }}</option>
220 <# } #>
221
222 <#
223 var _opts = Array.isArray( data.options ) ? data.options
224 : ( function(o){ var a=[],k; for ( k in (o||{}) ){ if ( Object.prototype.hasOwnProperty.call(o,k) ){ a.push( o[k] ); } } return a; } )( data.options );
225 _opts.forEach( function( opt ){
226 if ( ! opt ) { return; }
227 var _val = String( opt.value || '' );
228 var _lbl = String( opt.label || '' );
229 var _sel = !! selected_set[ _val ];
230 #>
231 <option value="{{ _val }}" <# if ( _sel ) { #> selected <# } #> >{{ _lbl }}</option>
232 <# }); #>
233 </select>
234 </span>
235
236 <# if ( data.help ) { #>
237 <div class="wpbc_bfb__help">{{ data.help }}</div>
238 <# } #>
239 </span>
240 </script>
241
242 <script type="text/html" id="tmpl-wpbc-bfb-inspector-starttime">
243 <style type="text/css">
244 .wpbc_admin .wpbc_ui_el__vert_right_bar__wrapper:has(.wpbc_bfb__inspector_timepicker) {
245 --wpbc_ui_left_vert_nav__width_max: Min(580px, 100%);
246 }
247 </style>
248 <div class="wpbc_bfb__inspector_starttime wpbc_bfb__inspector_timepicker" data-type="starttime"
249 data-i18n-add="<?php echo esc_attr__( 'Add New', 'booking' ); ?>"
250 data-i18n-duplicate="<?php echo esc_attr__( 'Duplicate', 'booking' ); ?>"
251 data-i18n-remove="<?php echo esc_attr__( 'Remove', 'booking' ); ?>"
252 data-i18n-default="<?php echo esc_attr__( 'Default', 'booking' ); ?>"
253 data-i18n-reorder="<?php echo esc_attr__( 'Drag to reorder', 'booking' ); ?>"
254 data-i18n-rowlabel="<?php echo esc_attr__( 'Label (e.g. 10:00 AM)', 'booking' ); ?>"
255 >
256 <div class="wpbc_bfb__inspector__head">
257 <div class="header_container">
258 <div class="header_title_content">
259 <h3 class="title"><?php echo esc_html__( 'Start time', 'booking' ); ?></h3>
260 <div class="desc"><?php echo esc_html__( 'Use the generator to quickly create time points.', 'booking' ); ?></div>
261 </div>
262 <div class="actions wpbc_ajx_toolbar wpbc_no_borders">
263 <div class="ui_container ui_container_small">
264 <div class="ui_group">
265 <div class="ui_element">
266 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button" data-action="deselect" aria-label="<?php echo esc_attr__( 'Deselect', 'booking' ); ?>">
267 <i class="menu_icon icon-1x wpbc_icn_remove_done"></i>
268 </button>
269 <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' ); ?>">
270 <i class="menu_icon icon-1x wpbc_icn_ads_click filter_center_focus"></i>
271 </button>
272 </div>
273 <div class="ui_element">
274 <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' ); ?>">
275 <i class="menu_icon icon-1x wpbc_icn_arrow_upward"></i>
276 </button>
277 <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' ); ?>">
278 <i class="menu_icon icon-1x wpbc_icn_arrow_downward"></i>
279 </button>
280 </div>
281 <div class="ui_element">
282 <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">
283 <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>
284 </button>
285 </div>
286 </div><!-- .ui_group -->
287 </div><!-- .ui_container -->
288 </div><!-- .actions -->
289
290 </div><!-- .header_container -->
291 </div><!-- .wpbc_bfb__inspector__head -->
292
293 <div class="wpbc_bfb__inspector__body">
294 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="basic">
295 <button type="button" class="group__header">
296 <h3><?php echo esc_html__( 'Basic', 'booking' ); ?></h3>
297 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
298 </button>
299 <div class="group__fields">
300 <div class="inspector__row">
301 <label class="inspector__label"><?php echo esc_html__( 'Label', 'booking' ); ?></label>
302 <div class="inspector__control">
303 <input type="text" class="inspector__input" data-inspector-key="label" value="{{ data.label || '<?php echo esc_js( __( 'Start time', 'booking' ) ); ?>' }}">
304 </div>
305 </div>
306
307 <div class="inspector__row">
308 <label class="inspector__label"><?php echo esc_html__( 'Name', 'booking' ); ?></label>
309 <div class="inspector__control">
310 <input type="text" class="inspector__input" value="{{ (data.name && data.name !== '' ? data.name : 'starttime') }}" disabled="disabled" aria-disabled="true">
311 <input type="hidden" class="inspector__input js-locked-name" data-inspector-key="name" data-locked="1" value="{{ (data.name && data.name !== '' ? data.name : 'starttime') }}">
312 <p class="wpbc_bfb__help" style="margin-top:6px;"><?php echo esc_html__( 'This field name is fixed for compatibility.', 'booking' ); ?></p>
313 </div>
314 </div>
315
316 <div class="inspector__row">
317 <div class="inspector__control ">
318 <span class="wpbc_ui__toggle">
319 <# var input_id = window.WPBC_BFB_Core.UI.WPBC_BFB_Toggle_Normalizer.generate_unique_id( 'wpbc_ins_auto_' + 'toggle_required' + '_' ); #>
320 <input type="checkbox" id="{{input_id}}" class="inspector__checkbox js-required-visible" checked disabled aria-disabled="true" data-wpbc-ui-no-toggle="1">
321 <label class="wpbc_ui__toggle_icon" for="{{input_id}}"></label>
322 <label class="wpbc_ui__toggle_label" for="{{input_id}}"><?php echo esc_html__( 'Required', 'booking' ); ?></label>
323 </span>
324 <input type="checkbox" class="inspector__checkbox js-required-proxy" data-inspector-key="required" data-locked="1" checked data-wpbc-ui-no-toggle="1" style="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;">
325 <p class="wpbc_bfb__help" style="margin-inline-start:1em;display: inline-block;"><?php echo esc_html__( 'This field is always required.', 'booking' ); ?></p>
326 </div>
327 </div>
328
329 <div class="inspector__row">
330 <label class="inspector__label"><?php echo esc_html__( 'Help text', 'booking' ); ?></label>
331 <div class="inspector__control">
332 <textarea class="inspector__textarea" rows="3" data-inspector-key="help">{{ data.help || '' }}</textarea>
333 </div>
334 </div>
335 </div>
336 </section>
337
338 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group is-open" data-group="options">
339 <button type="button" class="group__header">
340 <h3><?php echo esc_html__( 'Time options', 'booking' ); ?></h3>
341 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
342 </button>
343
344 <div class="group__fields inspector__group__fields__times">
345
346 <?php /* ===== Generator ===== */ ?>
347 <div class="inspector__row">
348 <div class="inspector__control inspector__control__generator_times">
349
350 <# var __fmt_name = 'st_label_fmt_' + ( data.html_id ? data.html_id : ( 'id_' + String( Math.random() ).slice(2) ) ); #>
351 <h2><?php echo esc_html__( 'Generate times', 'booking' ); ?></h2>
352 <div class="wpbc_bfb__st_gen_format wpbc_inline_inputs" role="radiogroup" aria-label="<?php echo esc_attr__( 'Time format', 'booking' ); ?>">
353 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'Time format', 'booking' ); ?>:</label>
354 <div class="wpbc_inline_inputs inspector__w_70">
355
356 <input type="hidden" class="inspector__input js-st-label-fmt-value" data-inspector-key="gen_label_fmt" value="{{ data.gen_label_fmt || 'ampm' }}">
357
358 <label>
359 <input type="radio" name="{{ __fmt_name }}" class="js-st-label-fmt" value="ampm" <# if ( (data.gen_label_fmt||'ampm') === 'ampm' ) { #> checked <# } #> >
360 <?php echo esc_html__( 'AM/PM', 'booking' ); ?>
361 </label>
362 &nbsp;&nbsp;
363 <label>
364 <input type="radio" name="{{ __fmt_name }}" class="js-st-label-fmt" value="24h" <# if ( (data.gen_label_fmt||'ampm') === '24h' ) { #> checked <# } #> >
365 <?php echo esc_html__( '24H', 'booking' ); ?>
366 </label>
367 </div>
368 </div>
369
370 <div class="wpbc_bfb__st_gen_times" style="margin-top:8px;">
371 <!-- 24H group (masked text inputs) -->
372 <div class="js-st-24h wpbc_inline_inputs" <# if ( (data.gen_label_fmt||'24h') !== '24h' ) { #> style="display:none" hidden aria-hidden="true" <# } #>>
373 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'From / To', 'booking' ); ?>:</label>
374 <div class="wpbc_inline_inputs inspector__w_70">
375 <div class="inspector__control inspector__w_45">
376 <input type="text" class="inspector__input inspector__w_25 js-st-mask js-gen-start-24h" data-mask-kind="24h" placeholder="HH:MM" data-inspector-key="gen_start_24h" value="{{ data.gen_start_24h || '08:00' }}">
377 </div>
378 <div class="inspector__control inspector__w_10" style="text-align: center;font-size: 18px;line-height: 2;font-weight: 700;">&ndash;</div>
379 <div class="inspector__control inspector__w_45">
380 <input type="text" class="inspector__input inspector__w_25 js-st-mask js-gen-end-24h" data-mask-kind="24h" placeholder="HH:MM" data-inspector-key="gen_end_24h" value="{{ data.gen_end_24h || '22:00' }}">
381 </div>
382 </div>
383 </div>
384
385 <!-- AM/PM group (native time inputs) -->
386 <div class="js-st-ampm wpbc_inline_inputs" <# if ( (data.gen_label_fmt||'24h') === '24h' ) { #> style="display:none" hidden aria-hidden="true" <# } #>>
387 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'From / To', 'booking' ); ?>:</label>
388 <div class="wpbc_inline_inputs inspector__w_70">
389 <div class="inspector__control inspector__w_45">
390 <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 || '08:00' }}">
391 </div>
392 <div class="inspector__control inspector__w_10" style="text-align: center;font-size: 18px;line-height: 2;font-weight: 700;">&ndash;</div>
393 <div class="inspector__control inspector__w_45">
394 <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 || '22:00' }}">
395 </div>
396 </div>
397 </div>
398 </div>
399
400 <div class="wpbc_bfb__st_gen_step wpbc_inline_inputs">
401 <label class="inspector__label inspector__w_30"><?php echo esc_html__( 'Step', 'booking' ); ?></label>
402 <div class="wpbc_len_group wpbc_inline_inputs inspector__w_70" data-len-group="st-step-hours">
403 <div class="inspector__control inspector__w_10"><?php echo esc_html__( 'hours', 'booking' ); ?>:</div>
404 <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 || 1 }}">
405 <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 || 1 }}">
406 </div>
407 </div>
408
409 <div class="wpbc_bfb__st_gen_step wpbc_inline_inputs">
410 <label class="inspector__label inspector__w_30"></label>
411 <div class="wpbc_len_group wpbc_inline_inputs inspector__w_70" data-len-group="st-step-minutes">
412 <div class="inspector__control inspector__w_10"><?php echo esc_html__( 'minutes', 'booking' ); ?>:</div>
413 <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 || 0 }}">
414 <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 || 0 }}">
415 </div>
416 </div>
417
418 <div class="wpbc_bfb__options_toolbar wpbc_inline_inputs">
419 <div class="inspector__control inspector__w_100" style="text-align: center;">
420 <button type="button" class="button button-primary js-st-generate"><?php echo esc_html__( 'Generate times', 'booking' ); ?> <i class="menu_icon icon-1x wpbc_icn_arrow_downward" aria-hidden="true"></i></button>
421 </div>
422 </div>
423
424 </div>
425 </div>
426
427 <?php /* ===== Options editor ===== */ ?>
428 <div class="inspector__row wpbc_bfb__options_editor">
429 <div class="wpbc_bfb__options_list__header">
430 <div class="wpbc_bfb__header_col__drag-handle"></div>
431 <div class="wpbc_bfb__header_col__label"><?php echo esc_html__( 'Label', 'booking' ) . ' (' . esc_html__( 'any text', 'booking' ) . ')'; ?></div>
432 <div class="wpbc_bfb__header_col__value"><?php echo esc_html__( 'Time', 'booking' ); ?></div>
433 <div class="wpbc_bfb__header_col__action"></div>
434 </div>
435 <div class="wpbc_bfb__options_list">
436 <#
437 var _opts2 = Array.isArray( data.options ) ? data.options
438 : ( function(o){ var a=[],k; for ( k in (o || {}) ) { if ( Object.prototype.hasOwnProperty.call( o, k ) ) { a.push( o[ k ] ); } } return a; } )( data.options );
439 #>
440
441 <# _opts2.forEach( function( opt, idx ){
442 var _val = String( opt && opt.value || '' );
443 var __uid = 'wpbc_ins_st_' + Math.random().toString(36).slice(2,10);
444 var __sel = !!( opt && ( true === opt.selected || 'true' === opt.selected || 1 === opt.selected || '1' === opt.selected ) );
445 #>
446 <div class="wpbc_bfb__options_row" data-index="{{ idx }}">
447 <span class="wpbc_bfb__drag-handle" title="<?php echo esc_attr__( 'Drag to reorder', 'booking' ); ?>"><span class="wpbc_icn_drag_indicator"></span></span>
448
449 <input type="text" class="wpbc_bfb__opt-label" placeholder="<?php echo esc_attr__( 'Label (e.g. 10:00 AM)', 'booking' ); ?>" value="{{ opt && opt.label || '' }}">
450
451 <# if ( (data.gen_label_fmt||'24h') === '24h' ) { #>
452 <input type="text" class="wpbc_bfb__opt-time js-st-mask" data-mask-kind="24h" placeholder="HH:MM" value="{{ _val }}">
453 <# } else { #>
454 <input type="time" class="wpbc_bfb__opt-time js-st-time" step="300" value="{{ _val }}">
455 <# } #>
456
457 <input type="text" class="wpbc_bfb__opt-value" value="{{ _val }}" hidden>
458
459 <div class="wpbc_bfb__opt-selected">
460 <div class="inspector__control wpbc_ui__toggle">
461 <input type="checkbox" class="wpbc_bfb__opt-selected-chk inspector__input" id="{{ __uid }}" role="switch" aria-checked="{{ __sel ? 'true' : 'false' }}" <# if ( __sel ) { #> checked <# } #> >
462 <label class="wpbc_ui__toggle_icon_radio" for="{{ __uid }}"></label>
463 <label class="wpbc_ui__toggle_label" for="{{ __uid ?>"><?php echo esc_js( __( 'Default', 'booking' ) ); ?></label>
464 </div>
465 </div>
466
467 <div class="wpbc_ui_el wpbc_ui_el_container wpbc_ui_el__dropdown">
468 <a href="javascript:void(0)" data-toggle="wpbc_dropdown" aria-expanded="false" class="ul_dropdown_menu_toggle">
469 <i class="menu_icon icon-1x wpbc_icn_more_vert"></i>
470 </a>
471 <ul class="ul_dropdown_menu" role="menu" style="right:0px; left:auto;">
472 <li><a class="ul_dropdown_menu_li_action st_dropdown_action" data-st-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>
473 <li><a class="ul_dropdown_menu_li_action st_dropdown_action" data-st-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>
474 <li class="divider"></li>
475 <li><a class="ul_dropdown_menu_li_action st_dropdown_action" data-st-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>
476 </ul>
477 </div>
478 </div>
479 <# }); #>
480 </div>
481
482 <div class="wpbc_bfb__options_toolbar ">
483 <small class="desc"><?php echo esc_html__( 'Drag by handle to reorder. Only one “Default” can be checked.', 'booking' ); ?></small>
484 <div class="wpbc_bfb__options_toolbar wpbc_inline_inputs">
485 <div class="inspector__control inspector__w_15">
486 <button type="button" class="button js-st-clear"><?php echo esc_html__( 'Clear all', 'booking' ); ?></button>
487 </div>
488 <div class="inspector__control inspector__w_85">
489 <button type="button" class="button button-secondary js-st-add-option">
490 <i class="wpbc_ui_el__vert_nav_icon tooltip_right_offset menu_icon icon-1x wpbc_icn_add_circle" aria-hidden="true"></i>
491 <?php echo esc_html__( 'Add time', 'booking' ); ?>
492 </button>
493 </div>
494 </div>
495 </div>
496
497 <#
498 var __json = JSON.stringify(_opts2 || []);
499 __json = __json.replace(/<\/textarea/gi, '<\\/textarea');
500 #>
501 <textarea class="wpbc_bfb__options_state inspector__input" data-inspector-key="options" hidden>{{ __json }}</textarea>
502 </div>
503
504 <div class="inspector__row js-placeholder-row">
505 <label class="inspector__label"><?php echo esc_html__( 'Placeholder', 'booking' ); ?></label>
506 <div class="inspector__control">
507 <input type="text" class="inspector__input js-placeholder" data-inspector-key="placeholder" value="{{ data.placeholder || '<?php echo '--- ' . esc_js( __( 'Select time', 'booking' ) ) . ' ---'; ?>' }}">
508 <p class="wpbc_bfb__help js-placeholder-note" style="margin-top:6px;"><?php echo esc_html__( 'Placeholder is used when no default is set.', 'booking' ); ?></p>
509 </div>
510 </div>
511
512 </div>
513 </section>
514
515 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="appearance">
516 <button type="button" class="group__header">
517 <h3><?php echo esc_html__( 'Appearance', 'booking' ); ?></h3>
518 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
519 </button>
520 <div class="group__fields">
521 <?php wpbc_bfb_time_picker__print_inspector_group(); ?>
522
523 <div class="inspector__row">
524 <label class="inspector__label"><?php echo esc_html__( 'CSS class', 'booking' ); ?></label>
525 <div class="inspector__control">
526 <input type="text" class="inspector__input" data-inspector-key="cssclass" value="{{ data.cssclass || '' }}">
527 </div>
528 </div>
529
530 <div class="inspector__row">
531 <label class="inspector__label"><?php echo esc_html__( 'HTML ID', 'booking' ); ?></label>
532 <div class="inspector__control">
533 <input type="text" class="inspector__input" data-inspector-key="html_id" value="{{ data.html_id || '' }}">
534 </div>
535 </div>
536
537 <div class="inspector__row">
538 <label class="inspector__label"><?php echo esc_html__( 'Min width', 'booking' ); ?></label>
539 <div class="inspector__control">
540 <input type="text" class="inspector__input" data-inspector-key="min_width" placeholder="180px" value="{{ data.min_width || '180px' }}">
541 </div>
542 </div>
543 </div>
544 </section>
545
546 </div><!-- .wpbc_bfb__inspector__body -->
547 </div><!-- .wpbc_bfb__inspector_starttime -->
548 </script>
549 <?php
550 }
551