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
← All changes | js/wpbc_time-selector.js +133 -11 11.8.4 → 11.9 View file →
@@ -1,6 +1,63 @@
1 1 // FixIn: 8.7.11.10.
2 -(function ( $ ){
2 +(function ( $ ){
3 +
4 + /**
5 + * Normalize native time options for the visual time-picker presentation.
6 + *
7 + * Empty values are select-box placeholders rather than bookable choices, so
8 + * they must not become visual picker cards. If the native select currently
9 + * points to a placeholder or a disabled option, select the first enabled real
10 + * time to match the browser behavior of a picker-mode form exported without a
11 + * placeholder.
12 + *
13 + * @param {Array<Object>} option_records Native option records.
14 + * @return {Array<Object>} Normalized non-placeholder option records with at
15 + * most one enabled selection.
16 + */
17 + function wpbc_timeselector_normalize_options( option_records ) {
18 +
19 + var normalized_options = [];
20 + var selected_option_index = -1;
21 +
22 + $.each( Array.isArray( option_records ) ? option_records : [], function ( index, option_record ) {
23 + var option_value = ( 'undefined' === typeof option_record.value || null === option_record.value ) ? '' : option_record.value;
24 +
25 + if ( '' === String( option_value ).trim() ) {
26 + return;
27 + }
28 +
29 + normalized_options.push( {
30 + title : ( 'undefined' === typeof option_record.title || null === option_record.title ) ? '' : option_record.title,
31 + value : option_value,
32 + disabled: !! option_record.disabled,
33 + selected: !! option_record.selected
34 + } );
35 +
36 + if (
37 + -1 === selected_option_index
38 + && ! option_record.disabled
39 + && option_record.selected
40 + ) {
41 + selected_option_index = normalized_options.length - 1;
42 + }
43 + } );
44 +
45 + if ( -1 === selected_option_index ) {
46 + $.each( normalized_options, function ( index, option_record ) {
47 + if ( ! option_record.disabled ) {
48 + selected_option_index = index;
49 + return false;
50 + }
51 + } );
52 + }
53 +
54 + $.each( normalized_options, function ( index, option_record ) {
55 + option_record.selected = index === selected_option_index;
56 + } );
57 +
58 + return normalized_options;
59 + }
3 60
4 61 $.fn.extend( {
5 62
6 63 wpbc_timeselector: function (){
@@ -6,12 +63,21 @@
6 63 wpbc_timeselector: function (){
7 64
8 65 var times_options = [];
9 66
10 - this.each( function (){
67 + this.each( function (){
68 +
69 + var el = $( this );
70 + var native_selected_option = el.find( 'option:selected' ).first();
71 + var native_selected_value = native_selected_option.length ? String( native_selected_option.val() ) : '';
72 + var automatic_selection_value = el.attr( 'data-wpbc-time-picker-auto-value' );
73 + var has_explicit_native_selection = (
74 + native_selected_option.length
75 + && ! native_selected_option.is( ':disabled' )
76 + && '' !== native_selected_value.trim()
77 + && automatic_selection_value !== native_selected_value
78 + );
11 79
12 - var el = $( this );
13 -
14 80 // On new days click we are searching for old time items, and remove them from this booking form
15 81 if ( el.parent().find( '.wpbc_times_selector' ).length ) {
16 82 el.parent().find( '.wpbc_times_selector' ).remove();
17 83 }
@@ -26,8 +92,24 @@
26 92 } );
27 93
28 94 } );
29 95
96 + times_options = wpbc_timeselector_normalize_options( times_options );
97 +
98 + $.each( times_options, function ( index, option_record ) {
99 + if ( option_record.selected ) {
100 + var selected_time_value = String( option_record.value );
101 +
102 + el.val( selected_time_value );
103 + if ( has_explicit_native_selection ) {
104 + el.removeAttr( 'data-wpbc-time-picker-auto-value' );
105 + } else {
106 + el.attr( 'data-wpbc-time-picker-auto-value', selected_time_value );
107 + }
108 + return false;
109 + }
110 + } );
111 +
30 112 var times_options_element = $.fn.wpbc_timeselector.format( times_options );
31 113
32 114 el.after( times_options_element );
33 115
@@ -45,10 +127,11 @@
45 127 // Match the literal value without interpreting it as selector syntax.
46 128 el.find( 'option' ).filter( function (){
47 129 return selected_value === jQuery( this ).val();
48 130 } ).prop( 'selected', true );
49 -
50 - el.trigger( 'change' );
131 + el.removeAttr( 'data-wpbc-time-picker-auto-value' );
132 +
133 + el.trigger( 'change' );
51 134 });
52 135
53 136 // Execute a function when the user presses a key (13 - Enter) on the keyboard. (FixIn: EAA)
54 137 el.next( '.wpbc_times_selector' ).find( 'div' ).not( '.wpbc_time_picker_disabled' ).on( "keypress", function (event) {
@@ -65,11 +148,10 @@
65 148 } );
66 149
67 150 return this; // Chain
68 151 }
69 - } );
70 -
71 -
152 + } );
153 +
72 154 /**
73 155 * Build the visual time-slot selector from native option data.
74 156 *
75 157 * Values and labels can originate in saved form configuration or modified
@@ -82,10 +164,11 @@
82 164 $.fn.wpbc_timeselector.format = function ( el_arr ) {
83 165
84 166 var times_selector = jQuery( document.createElement( 'div' ) ).addClass( 'wpbc_times_selector' );
85 167 var has_available_times = false;
168 + var normalized_options = wpbc_timeselector_normalize_options( el_arr );
86 169
87 - $.each( el_arr, function (index, el_item){
170 + $.each( normalized_options, function (index, el_item){
88 171
89 172 if ( !el_item.disabled ){
90 173 var time_option_value = ( 'undefined' === typeof el_item.value || null === el_item.value ) ? '' : el_item.value;
91 174 var time_option_title = ( 'undefined' === typeof el_item.title || null === el_item.title ) ? '' : el_item.title;
@@ -118,9 +201,48 @@
118 201 return times_selector;
119 202 };
120 203
121 204
122 -})( jQuery );
205 +})( jQuery );
206 +
207 +
208 +/**
209 + * Remove visual time pickers and restore native select-box placeholders.
210 + *
211 + * Only values automatically chosen by the visual picker are restored. An
212 + * explicit customer choice remains selected when a live settings preview is
213 + * switched back to Select box mode.
214 + *
215 + * @param {HTMLElement|Document|jQuery|null} context Optional preview boundary.
216 + * @return {void}
217 + */
218 +function wpbc_hook__destroy_timeselector( context ){
219 +
220 + var selector = 'select[name^="rangetime"], select[name^="starttime"], select[name^="endtime"], select[name^="durationtime"]';
221 + var scope = context ? jQuery( context ) : jQuery( document );
222 +
223 + scope.find( '.wpbc_times_selector' ).remove();
224 + scope.find( selector ).each( function (){
225 + var select_element = jQuery( this );
226 + var current_value = select_element.val();
227 + var automatic_value = select_element.attr( 'data-wpbc-time-picker-auto-value' );
228 +
229 + current_value = ( 'undefined' === typeof current_value || null === current_value ) ? '' : String( current_value );
230 + if ( 'undefined' !== typeof automatic_value && automatic_value === current_value ) {
231 + var placeholder_option = select_element.find( 'option' ).filter( function (){
232 + var option_value = jQuery( this ).val();
233 +
234 + return 'undefined' === typeof option_value || null === option_value || '' === String( option_value ).trim();
235 + } ).first();
236 +
237 + if ( placeholder_option.length ) {
238 + select_element.val( placeholder_option.val() );
239 + }
240 + }
241 +
242 + select_element.removeAttr( 'data-wpbc-time-picker-auto-value' ).show();
243 + } );
244 +}
123 245
124 246
125 247 /**
126 248 * Initialize the visual time-slot selectors when the WPBC runtime is ready.