PluginProbe
Booking Calendar / 11.8.4
Booking Calendar v11.8.4
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
← All changes | js/wpbc_time-selector.js +109 -59 11.4.311.8.4 View file →
@@ -1,4 +1,4 @@
1 1 // FixIn: 8.7.11.10.
2 2 (function ( $ ){
3 3
4 4 $.fn.extend( {
@@ -26,12 +26,12 @@
26 26 } );
27 27
28 28 } );
29 29
30 - var times_options_html = $.fn.wpbc_timeselector.format( times_options );
30 + var times_options_element = $.fn.wpbc_timeselector.format( times_options );
31 +
32 + el.after( times_options_element );
31 33
32 - el.after( times_options_html );
33 -
34 34 el.next('.wpbc_times_selector').find('div').not('.wpbc_time_picker_disabled').on( "click", function() {
35 35
36 36 // Get data value of clicked DIV time-slot
37 37 var selected_value = jQuery( this ).attr( 'data-value' );
@@ -41,10 +41,12 @@
41 41 // Set time item with selected Class
42 42 jQuery( this ).addClass('wpbc_time_selected');
43 43
44 44 el.find( 'option' ).prop( 'selected', false );
45 - // Find option in selectbox with this value
46 - el.find( 'option[value="' + selected_value + '"]' ).prop( 'selected', true );
45 + // Match the literal value without interpreting it as selector syntax.
46 + el.find( 'option' ).filter( function (){
47 + return selected_value === jQuery( this ).val();
48 + } ).prop( 'selected', true );
47 49
48 50 el.trigger( 'change' );
49 51 });
50 52
@@ -66,59 +68,83 @@
66 68 }
67 69 } );
68 70
69 71
70 - // Get HTML structure of times selection
71 - $.fn.wpbc_timeselector.format = function ( el_arr ) {
72 + /**
73 + * Build the visual time-slot selector from native option data.
74 + *
75 + * Values and labels can originate in saved form configuration or modified
76 + * DOM state. Creating elements and assigning text/attributes separately
77 + * prevents either value from becoming executable markup.
78 + *
79 + * @param {Array<Object>} el_arr Time-slot option records.
80 + * @return {jQuery} Detached, safely populated time-slot selector.
81 + */
82 + $.fn.wpbc_timeselector.format = function ( el_arr ) {
83 +
84 + var times_selector = jQuery( document.createElement( 'div' ) ).addClass( 'wpbc_times_selector' );
85 + var has_available_times = false;
86 +
87 + $.each( el_arr, function (index, el_item){
88 +
89 + if ( !el_item.disabled ){
90 + var time_option_value = ( 'undefined' === typeof el_item.value || null === el_item.value ) ? '' : el_item.value;
91 + var time_option_title = ( 'undefined' === typeof el_item.title || null === el_item.title ) ? '' : el_item.title;
92 + var time_option = jQuery( document.createElement( 'div' ) )
93 + .attr( 'data-value', String( time_option_value ) )
94 + .attr( 'tabindex', '0' )
95 + .text( String( time_option_title ) );
96 +
97 + if ( el_item.selected ){
98 + time_option.addClass( 'wpbc_time_selected' );
99 + }
100 +
101 + times_selector.append( time_option );
102 + has_available_times = true;
103 + } else {
104 + // Uncomment row bellow to Show booked time slots as unavailable RED slots // FixIn: 9.9.0.2.
105 + // Add a disabled element through the same DOM construction path when this feature is enabled.
106 + }
107 +
108 + } );
109 +
110 + if ( ! has_available_times ){
111 + times_selector.append(
112 + jQuery( document.createElement( 'span' ) )
113 + .addClass( 'wpbc_no_time_pickers' )
114 + .text( 'No available times' )
115 + );
116 + }
117 +
118 + return times_selector;
119 + };
72 120
73 - var select_div = '';
74 - var css_class='';
75 121
76 - $.each( el_arr, function (index, el_item){
77 -
78 - if ( !el_item.disabled ){
79 -
80 - if (el_item.selected){
81 - css_class = 'wpbc_time_selected';
82 - } else {
83 - css_class = '';
84 - }
85 -
86 - select_div += '<div '
87 - + ' data-value="' + el_item.value + '" '
88 - + ' class="' + css_class + '" '
89 - + ' tabindex="0" '
90 - + '>'
91 - + el_item.title
92 - + '</div>'
93 - } else {
94 - // Uncomment row bellow to Show booked time slots as unavailable RED slots // FixIn: 9.9.0.2.
95 - // select_div += '<div class="wpbc_time_picker_disabled">' + el_item.title + '</div>';
96 - }
97 -
98 - } );
99 -
100 - if ( '' == select_div ){
101 - select_div = '<span class="wpbc_no_time_pickers">'
102 - + 'No available times'
103 - + '</span>'
104 - }
105 - return '<div class="wpbc_times_selector">' + select_div + '</div>';
106 - }
107 -
108 -
109 122 })( jQuery );
110 123
111 124
112 -/**
113 - * Init time selector
114 - */
115 -function wpbc_hook__init_timeselector(){
125 +/**
126 + * Initialize the visual time-slot selectors when the WPBC runtime is ready.
127 + *
128 + * The readiness check prevents a JavaScript error when a third-party optimizer
129 + * delays wpbc_all.js, which creates window._wpbc, beyond document ready.
130 + *
131 + * @return {boolean} True when initialization is complete or not required;
132 + * otherwise false when the WPBC runtime is not ready yet.
133 + */
134 +function wpbc_hook__init_timeselector(){
135 +
136 + if (
137 + ( 'object' !== typeof window._wpbc )
138 + || ( 'function' !== typeof window._wpbc.get_other_param )
139 + ) {
140 + return false;
141 + }
142 +
143 + if ( true !== window._wpbc.get_other_param( 'is_enabled_booking_timeslot_picker' ) ) {
144 + return true;
145 + }
116 146
117 - if ( true !== _wpbc.get_other_param( 'is_enabled_booking_timeslot_picker' ) ) {
118 - return false;
119 - }
120 -
121 147 // Load after page loaded
122 148 jQuery( 'select[name^="rangetime"]' ).wpbc_timeselector();
123 149 jQuery( 'select[name^="starttime"]' ).wpbc_timeselector();
124 150 jQuery( 'select[name^="endtime"]' ).wpbc_timeselector();
@@ -128,13 +154,37 @@
128 154 jQuery( ".booking_form_div" ).on( 'wpbc_hook_timeslots_disabled', function ( event, bk_type, all_dates ){
129 155 jQuery( '#booking_form_div' + bk_type + ' select[name^="rangetime"]' ).wpbc_timeselector();
130 156 jQuery( '#booking_form_div' + bk_type + ' select[name^="starttime"]' ).wpbc_timeselector();
131 157 jQuery( '#booking_form_div' + bk_type + ' select[name^="endtime"]' ).wpbc_timeselector();
132 - jQuery( '#booking_form_div' + bk_type + ' select[name^="durationtime"]' ).wpbc_timeselector();
133 - } );
134 -}
135 -
136 -jQuery(document).ready(function(){
137 -// setTimeout( function ( ) { // Need to have some delay for loading of all times in Garbage
138 - wpbc_hook__init_timeselector();
139 -// }, 1000 );
140 -});
158 + jQuery( '#booking_form_div' + bk_type + ' select[name^="durationtime"]' ).wpbc_timeselector();
159 + } );
160 +
161 + return true;
162 +}
163 +
164 +
165 +/**
166 + * Initialize the time selector now or after the WPBC core signals readiness.
167 + *
168 + * @return {void}
169 + */
170 +function wpbc_init_timeselector_when_wpbc_ready(){
171 +
172 + if ( wpbc_hook__init_timeselector() ) {
173 + return;
174 + }
175 +
176 + var wpbc_timeselector_ready_handler = function (){
177 + if ( wpbc_hook__init_timeselector() ) {
178 + document.removeEventListener( 'wpbc-ready', wpbc_timeselector_ready_handler );
179 + }
180 + };
181 +
182 + document.addEventListener( 'wpbc-ready', wpbc_timeselector_ready_handler );
183 +}
184 +
185 +
186 +jQuery(document).ready(function(){
187 +// setTimeout( function ( ) { // Need to have some delay for loading of all times in Garbage
188 + wpbc_init_timeselector_when_wpbc_ready();
189 +// }, 1000 );
190 +});