1/* global common, modal */ 2/* exported freeAdmissionVoucher */ 3 4/** 5 * Methods related to adding a free admission voucher on the event page. 6 */ 7const freeAdmissionVoucher = { 8 9 /** 10 * The current event category ID. 11 * @type Number 12 */ 13 categoryId: null, 14 15 /** 16 * Data of the added free admission vouchers. 17 * @type Object 18 */ 19 voucherData: null, 20 21 /** 22 * Initialize the free admission voucher on event page. 23 * @param {Number} categoryId The event category ID 24 */ 25 init: function(categoryId) { 26 this.categoryId = categoryId; 27 28 // Do we have any voucher code we want to preadd? 29 let voucherCode = '0'; 30 if (location.hash.length > 1) { 31 const hash = location.hash.substr(1).split('='); 32 if (hash.length === 2 && hash[0] === 'voucher_code') { 33 voucherCode = hash[1]; 34 location.hash = ''; 35 } 36 } 37 38 // Load the voucher data 39 common.ajaxLoader({ 40 url: '/voucher/addFreeAdmission', 41 method: 'POST', 42 data: { 43 voucherCode: voucherCode, 44 categoryId: this.categoryId, 45 cleanup: 1 46 }, 47 success: function(response) { 48 if (voucherCode !== '0') { 49 // We have added a voucher code, so we need to reload the page to find the correct sections 50 window.location.reload(); 51 52 return; 53 } 54 55 freeAdmissionVoucher.voucherData = response.data.vouchers === undefined ? [] : response.data.vouchers; 56 $('#num-tickets').prop('disabled', false); 57 58 // Make sure that a refreshed page displays the correct number of tickets 59 freeAdmissionVoucher.loadEventSelections(); 60 61 // Render the voucher list (if the modal is ready) 62 freeAdmissionVoucher.populateList(); 63 } 64 }); 65 }, // End freeAdmission.init() 66 67 /** 68 * Show the free admission voucher modal. 69 */ 70 show: function() { 71 // Use existing modal if any 72 const $modal = $('#free_admission_voucher_modal'); 73 if ($modal.length > 0) { 74 $modal.modal('show'); 75 76 return; 77 } 78 79 // Create a new modal and show it 80 modal.create('free_admission_voucher_modal', { 81 title: common.getResource('free_admission_voucher.modal.title'), 82 body: common.getResource('free_admission_voucher.modal.body'), 83 buttons: ['buttons.close'], 84 focus: 'voucher_code', 85 keyboard: false 86 }); 87 88 // Render the voucher list (if the data is ready) 89 this.populateList(); 90 }, // End freeAdmission.show() 91 92 /** 93 * Render the list of active free admission vouchers. 94 * Will only render if the data has been received from the server and the modal is created. 95 * Will not do anything if the list has already been rendered. 96 */ 97 populateList: function() { 98 if (this.voucherData === null) { 99 // The data is not ready yet 100 return; 101 } 102 const $placeholder = $('#free_admission_voucher_list_placeholder'); 103 if ($placeholder.length === 0) { 104 // The modal is not ready, or the list has already been rendered 105 return; 106 } 107 if (this.voucherData.length === 0) { 108 // No vouchers to list 109 $placeholder.remove(); 110 111 return; 112 } 113 const listTemplate = common.getResource('free_admission_voucher.list'); 114 const rowTemplate = common.getResource('free_admission_voucher.row'); 115 const rows = []; 116 for (let voucherCodeId in this.voucherData) { 117 rows.push( 118 rowTemplate 119 .replace('{id}', voucherCodeId) 120 .replace('{code}', this.voucherData[voucherCodeId].code) 121 .replace('{status}', common.getResource('free_admission_voucher.status.' + this.voucherData[voucherCodeId].status)) 122 ); 123 } 124 const $list = $(listTemplate.replace('{rows}', rows.join(''))); 125 $placeholder.replaceWith($list); 126 common.initScope($list); 127 }, // End freeAdmission.populateList() 128 129 /** 130 * Shows modal for entering voucher code. 131 */ 132 showVoucherModal: function() { 133 modal.create( 134 'voucher_modal', 135 { 136 title: common.getResource('multihall.voucher_modal.title'), 137 body: common.getResource('multihall.voucher_modal.body'), 138 buttons: ['button.close', 'multihall.voucher_modal.submit_button'], 139 reload: true, 140 show: true 141 } 142 ); 143 144 }, // End showVoucherModal() 145 146 /** 147 * Handle submit of the add free admission voucher form. 148 * @param {HTMLFormElement} form 149 */ 150 submit: function(form) { 151 const $form = $(form); 152 const $errorFeedback = $('#free_admission_voucher_feedback').hide(); 153 const voucherCode = $form.find('input[name="voucher_code"]').val(); 154 if (voucherCode === '') { 155 156 return; 157 } 158 159 const $loader = $form.closest('.loader_container'); 160 common.ajaxLoader({ 161 loader: $loader, 162 url: '/voucher/addFreeAdmission', 163 method: 'POST', 164 data: { 165 voucherCode: voucherCode, 166 categoryId: this.categoryId 167 }, 168 success: function(response) { 169 if (response.data.voucherValid) { 170 // Save the current selections and reload the page 171 freeAdmissionVoucher.saveEventSelections(); 172 location.reload(); 173 } 174 else { 175 $errorFeedback.text(response.data.voucherErrorMessage); 176 $errorFeedback.show(); 177 } 178 } 179 }); 180 }, // End freeAdmission.submit() 181 182 /** 183 * Remove all added free admission vouchers 184 */ 185 removeAll: function() { 186 $('#free_admission_voucher_modal .loader_container').addClass('loader'); 187 common.ajaxLoader({ 188 url: '/voucher/deleteAllFreeAdmission', 189 method: 'POST', 190 success: function(response) { 191 freeAdmissionVoucher.saveEventSelections(); 192 location.reload(); 193 } 194 }); 195 }, // End freeAdmission.removeAll() 196 197 /** 198 * Remove a specific added free admission voucher. 199 * @param {Number} voucherCodeId 200 */ 201 remove: function(voucherCodeId) { 202 $('#free_admission_voucher_modal .loader_container').addClass('loader'); 203 common.ajaxLoader({ 204 url: '/voucher/deleteFreeAdmission', 205 method: 'POST', 206 data: { 207 voucherCodeId: voucherCodeId 208 }, 209 success: function(response) { 210 freeAdmissionVoucher.saveEventSelections(); 211 location.reload(); 212 } 213 }); 214 }, // End freeAdmission.remove() 215 216 /** 217 * Save the event selections in the sessionStorage. 218 * Typically done before a reload. 219 */ 220 saveEventSelections: function() { 221 if (window.sessionStorage === undefined) { 222 return; 223 } 224 sessionStorage.setItem('num-tickets', $('#num-tickets').val()); 225 }, // End freeAdmission.saveEventSelections() 226 227 /** 228 * Load the saved event selections from the sessionStorage. 229 * Typically done on page load. 230 * @return {Boolean} Returns True if any event data where loaded, and the DOM updated. 231 */ 232 loadEventSelections: function() { 233 if (window.sessionStorage === undefined) { 234 return false;
235 } 236 const numTickets = sessionStorage.getItem('num-tickets'); 237 if (numTickets) { 238 sessionStorage.removeItem('num-tickets'); 239 240 // Set the ticket number and trigger its change event 241 $('#num-tickets').val(numTickets).change(); 242 243 // We do not select ticket types as we expect the customer to want to use the newly added free admission voucher tickets 244 return true; 245 } 246 247 return false; 248 }, // End freeAdmission.loadEventSelections() 249 250 /** 251 * Get a list of available voucher products. 252 * This is called in context of MultiHallSeatmap, meaning *this* refers to MultiHallSeatmap! 253 * We expect all vouchers to be usable in all possible sections. Other scenarios are usually not possible in practice. 254 * @returns {Array} Array of products in a regular array, meaning NOT indexed by their ID. 255 */ 256 getVoucherProducts: function() { 257 if (freeAdmissionVoucher.voucherData === null) { 258 // Wow, we're not ready yet! 259 return null; 260 } 261 262 // Find a product for each voucher code. 263 // It is actually the same product for all voucher codes, 264 // but the presentation varies. 265 const result = []; 266 for (let voucherCodeId in freeAdmissionVoucher.voucherData) { 267 const voucherCode = freeAdmissionVoucher.voucherData[voucherCodeId]; 268 if (voucherCode.status !== 'available') { 269 continue; 270 } 271 272 // There is only one possible product for a free admission voucher. 273 // But the product is stored for each possible section. 274 // Therefor, find the first product of the first section and use that. 275 let productFound = false; 276 for (let sectionId in voucherCode.sections) { 277 if (productFound) { 278 break; 279 } 280 const section = voucherCode.sections[sectionId]; 281 for (let productId in section.products) { 282 const product = section.products[productId]; 283 product.id = productId; 284 result.push(product); 285 productFound = true; 286 break; 287 } 288 } 289 } 290 291 return result; 292 }, // End freeAdmission.getVoucherProducts() 293 294 /** 295 * Set the status of the given voucher codes as "in cart". 296 * This is called in context of MultiHallSeatmap, meaning *this* refers to MultiHallSeatmap! 297 * 298 * @param {Array} voucherCodeIds 299 */
300 setAsInCart: function(voucherCodeIds) { 301 if (freeAdmissionVoucher.voucherData === null) { 302 return; 303 } 304 305 for (let i in voucherCodeIds) { 306 const voucherCodeId = voucherCodeIds[i]; 307 if (freeAdmissionVoucher.voucherData[voucherCodeId] === undefined) { 308 continue; 309 } 310 freeAdmissionVoucher.voucherData[voucherCodeId].status = 'in_cart'; 311 } 312 } // End setAsInCart() 313 314};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.