1/** 2 * Created by waimansing on 11/1/2021. 3 */ 4$(document).ready(function () { 5 const setCookie = (cname, cvalue, exdays = 1) => { 6 const d = new Date(); 7 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 8 let expires = "expires=" + d.toUTCString(); 9 // document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 10 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;sameSite=None;secure=true"; 11// Cookies.set(cname, cvalue, {sameSite: 'None', secure: true, expires: expires}); 12 } 13 14 function getCookie(cname) { 15 let name = cname + "="; 16 let ca = document.cookie.split(';'); 17 for (let i = 0; i < ca.length; i++) { 18 let c = ca[i]; 19 while (c.charAt(0) === ' ') { 20 c = c.substring(1); 21 } 22 if (c.indexOf(name) === 0) { 23 return c.substring(name.length, c.length); 24 } 25 } 26 return ""; 27 } 28 29 const logout = (targetHref = '') => { 30 // console.log('logout'); 31 setCookie("SessionKey", '', -1); 32 setCookie("MemberNo", '', -1); 33 changeLocation(targetHref); 34 } 35 36 const getLang = () => { 37 return document.getElementsByTagName('html')[0]?.getAttribute('lang')?.toLowerCase(); 38 } 39 const getLangInt = () => { 40 const lang = getLang(); 41 if (lang.startsWith('en')) { 42 return 1; 43 } else if (lang.startsWith('zh-cn')) { 44 return 3; 45 } 46 return 2; 47 } 48 49 const getErrorMsg = (data) => { 50 const lang = getLang(); 51 const langKey = lang.startsWith('en') ? 'Message' : lang === 'zh-cn' ? 'MessageSC' : 'MessageTC'; 52 return data[langKey] ?? data.message; 53 } 54 55 const displaySuccessMsg = () => { 56 const msg = { 57 'Message': 'Success', 58 'MessageSC': 'æå', 59 'MessageTC': 'æå', 60 } 61 return getErrorMsg(msg); 62 } 63 64 const buttonCountdown = (btn, count = 61) => { 65 const text = btn.text(); 66 btn.attr('disabled', true); 67 const resendInterval = setInterval(() => { 68 if (count-- >= 0) { 69 btn.attr('disabled', true); 70 btn.text(`${count}s`); 71 } else { 72 btn.text(text); 73 btn.attr('disabled', false); 74 clearInterval(resendInterval); 75 } 76 }, 1000); 77 } 78 79 const openModal = (id, actionFn) => { 80 $(id).addClass('hr-show'); 81 if (actionFn) actionFn(); 82 } 83 84 const changeLocation = (targetLoc) => { 85 const currentPage = window.location || window.document.location; 86 try { 87 const url = new URL(targetLoc); 88 if (currentPage.hostname === url.hostname) { 89 window.location = url; 90 return 91 } 92 } catch (e) { 93 } 94 window.location.reload(); 95 } 96 const formChangePage = (formId) => { 97 const targetLoc = $(formId).attr("data-target"); 98 changeLocation(targetLoc); 99 } 100 101 const generateQRCode = (elemId, text, width = 140, height = 140) => { 102 new QRCode(document.getElementById(elemId), { 103 text: text, 104 width: width, 105 height: height, 106 }); 107 } 108 109 const groupArrayByKey = (array, groupKeys, countKey, stackKey, stackResultKey, otherStackKeyArray) => { 110 const groupedArray = []; 111 // console.log(groupKeys); 112 array.forEach((a) => { 113 const index = groupedArray.findIndex((g) => { 114 return groupKeys.reduce((prev, key) => prev && g[key] === a[key], true); 115 }); 116 // console.log(a, index); 117 // exist 118 if (index > -1) { 119 const count = groupedArray[index][countKey]; 120 groupedArray[index][countKey] = count + 1; 121 const stacked = groupedArray[index][stackResultKey]; 122 stacked.push(a[stackKey]) 123 groupedArray[index][stackResultKey] = stacked; 124 125 otherStackKeyArray.forEach((otherStackKey) => { 126 const _otherStackedKey = "_" + otherStackKey; 127 const otherStackedArray = groupedArray[index][_otherStackedKey] ?? []; 128 otherStackedArray.push(a[otherStackKey]) 129 groupedArray[index][_otherStackedKey] = otherStackedArray; 130 }) 131 } else { 132 a[countKey] = 1; 133 groupedArray.push(a); 134 a[stackResultKey] = [a[stackKey]]; 135 otherStackKeyArray.forEach((otherStackKey) => { 136 a["_" + otherStackKey] = [a[otherStackKey]]; 137 }) 138 } 139 }) 140 return groupedArray; 141 } 142 143 const generateRewards = (rewards) => { 144 const img = rewards['ImageURL']; 145 const name = rewards['Name']; 146 const till = rewards['EffectiveTo']; 147 const id = rewards['RewardId']; 148 const lang = getLangInt(); 149 const _redeem_til = lang === 1 ? "Redemption Until:" : (lang === 3 ? "å æ¢æè³:" : 'å ææè³:'); 150 const _more = lang === 1 ? "MORE DETAILS" : (lang === 3 ? "详æ " : '詳æ '); 151 152 return `<div class='hrdm-reward-card'> 153<img class="hrdmc-img" src="${img}" alt="${name}"> 154<div class="hrdmc-wrapper"> 155<div class="hrdmc-name font-h fs-21 fw-600">${name}</div> 156<div class="hrdmc-details"> 157<div class="hrdmc-details-l"> 158<div class="hrdmc-until font-h fs-16 fw-600">${_redeem_til}</div> 159<div class="hrdmc-until-date font-h fs-16 fw-300">${till}</div> 160</div> 161<div class="hrdmc-details-r hrdmc-view-details-click" data-reward-id='${id}'> 162<div class="font-h fs-16 fw-600">${_more}</div> 163<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
163ox="0 0 20.738 20.738"> 164 <g transform="translate(-1782.714 -1638.547)"> 165 <path data-name="Icon material-arrow_back" d="M20.738,9.073H4.964L12.21,1.828,10.369,0,0,10.369,10.369,20.738,12.2,18.911,4.964,11.665H20.738Z" transform="translate(1803.452 1659.286) rotate(180)"/> 166 </g> 167</svg> 168</div> 169</div> 170</div> 171</div>`; 172 } 173 174 const generateGift = (gift, node) => { 175 const img = gift['ImageURL']; 176 const qty = gift['_count']; 177 // const til = gift['ExpiryDate']; 178 const expiryList = {}; 179 gift['_ExpiryDate'].forEach((date) => { 180 if (date in expiryList) { 181 expiryList[date] += 1; 182 } else { 183 expiryList[date] = 1; 184 } 185 }); 186 const til = Object.keys(expiryList).map((key) => `${key} (${expiryList[key]})`).join(", "); 187 const name = gift['RewardName']; 188 const status = gift['Status'].toLowerCase(); 189 const stackedGifts = gift['_gift'].join(','); 190 const lang = getLangInt(); 191 const _qty = lang === 1 ? "QTY" : (lang === 3 ? "æ°é" : 'æ¸é'); 192 const _redeem_til = lang === 1 ? "Redemption Until:" : (lang === 3 ? "å æ¢æè³:" : 'å ææè³:'); 193 const _use = lang === 1 ? "USE NOW" : '使ç¨'; 194 const _use_date = lang === 1 ? "Use Date:" : (lang === 3 ? "ä½¿ç¨æ¶é´:" : 'ä½¿ç¨æé:'); 195 const _expired_date = lang === 1 ? "Expired Date:" : 'ä½¿ç¨æé:'; 196 const _view_details = lang === 1 ? "View Details" : (lang === 3 ? 'æ¥ç详æ ' : 'æ¥ç詳æ '); 197 198 let innerNode = ""; 199 if (status === 'active') { 200 innerNode = `<div class="hrdmc-gift-qty"><b>${_qty}:</b><br/>${qty}</div> 201<div class="hrdmc-gift-til"><b>${_redeem_til}</b> ${til}</div> 202<div class="hrdmc-gift-btn"> 203 <button class="btn-explore-more hr-login hrdmc-use-coupon" data-name="${name}" data-qty="${qty}" data-gift="${stackedGifts}">${_use}</button> 204 <div class="hrdmc-view-more hrdmc-view-details-click" data-gift-id="${stackedGifts.split(",")[0]}"> 205 ${_view_details} 206 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 20.738 20.738"> 207 <g transform="translate(-1782.714 -1638.547)"> 208 <path data-name="Icon material-arrow_back" d="M20.738,9.073H4.964L12.21,1.828,10.369,0,0,10.369,10.369,20.738,12.2,18.911,4.964,11.665H20.738Z" transform="translate(1803.452 1659.286) rotate(180)"/> 209 </g> 210 </svg> 211 </div> 212</div>` 213 } else { 214 const usedDate = gift['_DateUsed'].join(" // "); 215 const text = status === 'used' ? `<b>${_use_date}</b> ${usedDate}` : `<b>${_expired_date}</b> ${til}` 216 innerNode = `<div>${text}</div>`; 217 } 218 219 const refNo = gift['_ReferenceNo'].filter(n => n).join(", "); 220 const refNoText = (status === 'used' && refNo) ? `<br/>(Ref#: ${refNo})` : ''; 221 222 const finalNode = `<div class="hrdmc-gift-wrapper --${status}"> 223<img class="hrdmc-gift-img" src="${img}" alt="${name}"> 224<div class="hrdmc-gift-r font-h fs-21"> 225<div class="hrdmc-gift-name fw-600">${name}${refNoText}</div> 226${innerNode} 227</div> 228</div>`; 229 node.append(finalNode); 230 } 231 232 const binaryHideField = (field1, field2, showField1) => { 233 field1.css('display', showField1 ? 'block' : 'none'); 234 field2.css('display', showField1 ? 'none' : 'block'); 235 } 236 237 const dataHandler = (action, resData, formData) => { 238 switch (action) { 239 case "login": 240 setCookie('SessionKey', resData['SessionKey']); 241 setCookie('MemberNo', resData['MemberNo']); 242 formChangePage("#login-form"); 243 break; 244 case "register": 245 // console.log(formData); 246 openModal('#verifyModal', () => { 247 const mobileNo = formData['MobileNoDistrict'] + formData['MobileNo']; 248 $('#hr-ver-mob').val(mobileNo); 249 $('#hr-ver-mob2').val(mobileNo); 250 251 const emailAddress = formData['EmailAddress']; 252 $('#hr-ver-email').val(emailAddress); 253 $('#hr-ver-email2').val(emailAddress); 254 255 const mobileWrapper = $('#hr-ver-mob-wrapper'); 256 const emailWrapper = $('#hr-ver-email-wrapper'); 257 const isLocalMobile = mobileNo.startsWith('+852-'); 258 binaryHideField(mobileWrapper, emailWrapper, isLocalMobile); 259 260 const memberNo = resData['MemberNo']; 261 $('#hr-ver-member-no2').val(memberNo); 262 263 if (!isLocalMobile) { 264 $("#hr-ver-resend-btn").click(); 265 } 266 }) 267 break; 268 case "verify": 269 const verifyForm = $("#verify-form"); 270
271 const targetLoc = verifyForm.attr("data-target"); 272 verifyForm.find(".display-error").text(displaySuccessMsg()); 273 setTimeout(() => { 274 changeLocation(targetLoc); 275 }, 1500); 276 break; 277 case "resend": 278 const resendFormSubmit = $("#resend-form").find('.form-submit'); 279 buttonCountdown(resendFormSubmit); 280 break; 281 // change password 282 case 'change': 283 break; 284 case 'gift_list': 285 const allGift = resData['Gifts']; 286 const validGift = $('#hrdm-valid'); 287 const usedGift = $('#hrdm-used'); 288 const expiredGift = $('#hrdm-expired'); 289 validGift.text(''); 290 usedGift.text(''); 291 expiredGift.text(''); 292 if (allGift && allGift.length > 0) { 293 let sortedGift = allGift.sort((a, b) => a['ExpiryDate'].localeCompare(b['ExpiryDate'])); 294 const groupedGift = groupArrayByKey( 295 sortedGift, 296 ['Status', 'RewardId'/*'TimeStampVal'*/], 297 '_count', 298 'GiftId', 299 '_gift', 300 ["ReferenceNo", "ExpiryDate", "DateUsed"] 301 ); 302 console.log(groupedGift); 303 groupedGift.forEach((gift) => { 304 const node = gift['Status'] === 'Active' ? validGift : 305 (gift['Status'] === 'Used' ? usedGift : expiredGift); 306 generateGift(gift, node); 307 }) 308 } else { 309 const lang = getLangInt(); 310 const _no_gift = lang === 1 ? "No available gifts" : (lang === 3 ? "没æçºªå½" : 'æ²æç´é'); 311 $('#hrdm-no-gift').text(_no_gift); 312 } 313 break; 314 case 'reward': { 315 const allRewards = resData['Rewards']; 316 const target = $('.hrd-content-reward'); 317 const touristTarget = $('.hrd-content-tourist-reward'); 318 const touristRewards = allRewards?.filter((r) => r.Tags.toLowerCase().includes("tourist")) ?? []; 319 const normalRewards = allRewards?.filter((r) => !r.Tags.toLowerCase().includes("tourist")) ?? []; 320 321 const lang = getLangInt(); 322 const _noReward = lang === 1 ? 'Coming soon. Stay tuned!' : 323 (lang === 3 ? "æå伿 å³å°ç»åºï¼å¯åçæã" : 'é©ååªæ å³å°ç»å ´ï¼å¯åçæã'); 324 325 if (touristRewards.length > 0) { 326 const html = touristRewards.reduce((p, c) => p + generateRewards(c), ''); 327 touristTarget.html(html); 328 } else { 329 touristTarget.text(_noReward); 330 } 331 332 if (normalRewards.length > 0) { 333 // console.log(allRewards); 334 const html = normalRewards.reduce((p, c) => p + generateRewards(c), ''); 335 target.html(html); 336 // noGiftDiv.text(''); 337 } else { 338 target.text(_noReward); 339 // noGiftDiv.text(_noReward); 340 } 341 } 342 break; 343 case 'reward_detail': 344 case 'gift_detail': 345 // console.log(resData); 346 openModal('#rewardDetailsModal'); 347 $('.hrd-general').css('display', 'none'); 348 $('.hrdh-img').css('display', 'none'); 349 $('.hrd-reward').css('display', ''); 350 $('.hrd-content-details form').css('display', action === 'gift_detail' ? 'none' : ""); 351 352 const image = $('.hrdr-img'); 353 image.css('display', ''); 354 const lang = getLangInt(); 355 const _now_til = lang === 1 ? "NOW TILL " : "ç´è³"; 356 $('.hrdr-date').text(`${_now_til}${resData['EffectiveTo'] ?? resData['ExpiryDate']}`); 357 $('.hrdr-title').text(resData['Name'] ?? resData['RewardName']); 358 image[0].src = resData['ImageURL'];
359 $('.hrdr-content').html(resData['Description']); 360 $('.hrdr-tnc-content').html(resData['TAC'] ?? resData['RewardTAC']); 361 $('.hrd-head-wrapper').addClass('--reward'); 362 $('.hrdr-redeem-input').val(resData['RewardId']); 363 break; 364 case 'reserve_reward': 365 $('.hrdrm-loading').css('display', 'none'); 366 $('.hrdrm-ok').css('display', ''); 367 setTimeout(() => { 368 memberDataSessionChanged('hrdh-wallet'); 369 }, 800); 370 break; 371 case 'use': 372 $("#hr-use-submit").attr("disabled", true); 373 $("#hr-use-error").text(`Success. Reference No.: ${resData['ReferenceNo']}`); 374 handleMemberDataHeaderActionClick('hrdh-wallet'); 375 $(".hr-modal-cross").attr("data-fresh", "wallet"); 376 break; 377 case 'otp': { 378 const lang = getLangInt(); 379 const _sent = lang === 1 ? "One-time password has been sent to your mailbox" : 380 (lang === 3 ? "䏿¬¡æ§å¯ç å·²åéå°ä½ ççµåé®ç®±å " : "䏿¬¡æ§å¯ç¢¼å·²ç¼éå°ä½ çé»åéµç®±å §"); 381 $("#hr-reset-error").text(_sent); 382 buttonCountdown($("#hr-otp-btn")); 383 } 384 break; 385 case 'reset': { 386 const lang = getLangInt(); 387 const _sent = lang === 1 ? "New password has been sent to your mailbox" : 388 (lang === 3 ? "æ°å¯ç å·²åéå°ä½ ççµåé®ç®±å " : "æ°å¯ç¢¼å·²ç¼éå°ä½ çé»åéµç®±å §"); 389 $("#hr-reset-error").text(_sent); 390 } 391 break; 392 } 393 } 394 395 const callAjaxAction = (formAction, targetAction, formData = undefined, mForm = undefined, errorDiv = undefined, submitBtn = undefined) => { 396 const lang = getLangInt(); 397 398 const originSubmitText = submitBtn?.text(); 399 submitBtn?.html('<div class="lds-ring"><div></div><div></div><div></div><div></div></div>'); 400 401 jQuery.ajax({ 402 url: sbiajaxurl + "?action=" + formAction, 403 data: {data: formData, lang: lang}, 404 type: 'POST', 405 success: (data) => { 406 if (data.includes('{')) { 407 const i = data.indexOf('{'); 408 data = data.slice(i); 409 } 410 data = data.replace(/\d*$/, ""); 411 try { 412 data = JSON.parse(data); 413 // console.log(data, data['code'], data['code'] === 0); 414 if (data['code'] === 0) { 415 // console.log(targetAction, data['data'], formData); 416 dataHandler(targetAction, data['data'], formData); 417 if (!submitBtn?.data('preserve')) { 418 mForm?.reset(); 419 } 420 if (targetAction === 'change') { 421 errorDiv.text(getErrorMsg(data)); 422 } 423 } else { 424 const errorMessage = getErrorMsg(data); 425 if (errorDiv) errorDiv.text(errorMessage); 426 if (targetAction === 'reserve_reward') { 427 const failWrapper = $('.hrdrm-no'); 428 failWrapper.css('display', ''); 429 $('.hrdrm-loading').css('display', 'none'); 430 failWrapper.find('.hrdrm-content').text(errorMessage); 431 } else if (targetAction === 'gift_list') { 432 logout(); 433 } 434 } 435 } catch (e) { 436 // console.error(e); 437 errorDiv?.text('Internal server error. Please retry again later.'); 438 } 439 }, 440 error: (err) => { 441 try { 442 err = JSON.parse(err); 443 errorDiv?.text(getErrorMsg(err) ?? err?.message ?? 'Server error. Please retry again later'); 444 } catch (e) { 445 console.error(e); 446 errorDiv?.text(`Internal Server error. Please retry again later.`); 447 } 448 }, 449 complete: () => { 450 submitBtn?.attr("disabled", false); 451 submitBtn?.text(originSubmitText); 452 } 453 }); 454 }; 455 456 457 458 // register tourist 459 $("#tourist-terms").click((e) => { 460 e.preventDefault(); 461 openModal("#tourist-tnc-modal"); 462 }); 463 $("#form-hr-register").on('change', '#hr-country', function () { 464 let selectedValue = $(this).find("option:selected").val(); 465 // console.log(selectedValue); 466 const touristCheckBox = $("#hr-tourist-tnc-checkbox"); 467 if (parseInt(selectedValue) === 1) { 468 $("#hr-tourist-tnc").hide(); 469 touristCheckBox.prop("checked", false); 470 touristCheckBox.removeAttr("required"); 471 // $("input#form-P_AGREE_TOURIST").removeAttr("required"); 472 } else { 473 $("#hr-tourist-tnc").show(); 474 touristCheckBox.attr("required", "required"); 475 } 476 }); 477 478 479 document.querySelectorAll('form.submitForm').forEach((e) => { 480 e.addEventListener('submit', (e) => { 481 // console.log(e); 482 e.preventDefault(); 483 // e.stopPropagation(); 484 const mForm = $(e.target); 485 var errorDiv = mForm.find('.display-error'); 486 errorDiv.text(''); 487 488 var submitBtn = $(e.submitter); 489 submitBtn.attr("disabled", true); 490 491 const formData = mForm.serializeArray().reduce((o, kv) => ({...o, [kv.name]: kv.value}), {}); 492 var formAction = submitBtn.data('name') ?? mForm.attr('name'); 493 var targetAction = submitBtn.attr('data-type') ?? mForm.attr('data-type'); 494 495 // console.log(formAction, targetAction); 496 497 // special handle for otp 498 if (targetAction === 'reset' && formData.OneTimePassword === '') { 499 const optBtn = $("#hr-otp-btn"); 500 if (optBtn.attr('disabled') !== 'disabled') { 501 formAction = 'post_hr_otp'; 502 targetAction = 'otp'; 503 submitBtn.attr("disabled", false); 504 submitBtn = optBtn; 505 } 506 } else if (targetAction === 'register') { 507 const countryInt = formData['Country']; 508 console.log(countryInt); 509 if (+countryInt >= 4) { 510 formData['Country'] = 4; 511 formData['OtherArea'] = $("#hr-country option:selected").text(); 512 } 513 } 514 515 callAjaxAction(formAction, targetAction, formData, mForm[0], errorDiv, submitBtn); 516 517 return false;
518 }, {passive: false}) 519 }) 520 521 // open modals 522 $('[data-bs-toggle="modal"]').each((i, el) => { 523 // console.log(el); 524 const target = el.getAttribute('data-bs-target'); 525 if (target) { 526 const targetNode = $(target); 527 el.addEventListener('click', () => { 528 targetNode.addClass('hr-show'); 529 }) 530 } 531 }); 532 $('.hr-modal-cross, .hr-modal-close').each((i, el) => { 533 el.addEventListener('click', () => { 534 const parentModal = $(el).parents('.hr-modal'); 535 parentModal?.removeClass('hr-show'); 536 parentModal?.find('form')?.trigger('reset'); 537 $("#hr-use-error").text(""); 538 }) 539 }); 540 541 // member details page 542 const memberDataSessionChanged = (id) => { 543 const walletDisplay = id === 'hrdh-wallet' ? '' : 'none'; 544 const rewardDisplay = id === 'hrdh-reward' ? '' : 'none'; 545 const touristDisplay = id === 'hrdh-tourist' ? '' : 'none'; 546 547 $('.hrd-back').attr('data-target', ''); 548 549 $('.hrd-content-reward').css('display', rewardDisplay); 550 $('.hrd-title.--reward').css('display', rewardDisplay); 551 552 $('.hrd-content-tourist-reward').css('display', touristDisplay); 553 $('.hrd-title.--tourist').css('display', touristDisplay); 554 555 $('.hrd-content-wallet').css('display', walletDisplay); 556 $('.hrd-title.--wallet').css('display', walletDisplay); 557 558 $('#hrd-logout-text').text(getLangInt() === 1 ? 'logout' : 'ç»åº'); 559 560 // remove reward session 561 $('.hrd-general').css('display', ''); 562 $('.hrdh-img').css('display', ''); 563 $('.hrd-head-wrapper').removeClass('--reward'); 564 565 $('.hrd-content-details').css('display', 'none'); 566 $('.hrd-reward').css('display', 'none'); 567 $('.hrdr-img').css('display', 'none'); 568 } 569 570 const handleMemberDataHeaderActionClick = (id) => { 571 switch (id) { 572 case 'hrdh-pwd': 573 openModal('#changePwdModal'); 574 break; 575 case 'hrdh-wallet': 576 memberDataSessionChanged(id); 577 if ($('#hrdm-valid').children().length === 0) { 578 $('#hrdm-no-gift').text(); 579 callAjaxAction('get_hr_gift', 'gift_list'); 580 } 581 break; 582 case 'hrdh-reward': 583 case 'hrdh-tourist': 584 memberDataSessionChanged(id); 585 if ($('.hrd-content-reward').children().length === 0) { 586 $('#hrdm-no-gift').text(); 587 callAjaxAction('get_hr_avail_reward', 'reward'); 588 } 589 break; 590 case 'hrdh-shop': 591 window.open('https://eshop.timessquare.com.hk', '_blank'); 592 break; 593 case 'hrdm-valid': 594 // callAjaxAction('get_hr_gift', 'valid'); 595 break; 596 case 'hrdm-used': 597 // callAjaxAction('get_hr_redeemed_gift', 'used'); 598 break; 599 case 'hrdm-expired': 600 // callAjaxAction('get_hr_redeemed_gift', 'expired'); 601 break; 602 } 603 } 604 605 $('#hr-member-action').click((e) => { 606 let self = $(e.target); 607 if (!self.hasClass('hrdh-action')) { 608 self = self.parents('.hrdh-action'); 609 } 610 // console.log(self, $(e.target)); 611 if (self.length > 0) { 612 handleMemberDataHeaderActionClick(self[0].id); 613 } 614 }); 615 616 // click reward details 617 $(document).on('click', '.hrdmc-view-details-click', (e) => { 618 let self = $(e.target); 619 if (!self.hasClass('hrdmc-view-details-click')) { 620 self = self.parents('.hrdmc-view-details-click'); 621 } 622 if (self) { 623 const rewardId = self.data('reward-id'); 624 const giftId = self.data('gift-id'); 625 if (!rewardId && !giftId) return; 626 627 // change page header and content 628 $('.hrd-title').css('display', 'none'); 629 $('.hrd-content-reward').css('display', 'none'); 630 $('.hrd-content-tourist-reward').css('display', 'none'); 631 $('.hrd-content-details').css('display', ''); 632 // change redeem modal display 633 $('.hrdrm-result').css('display', 'none'); 634 $('.hrdrm-loading').css('display', ''); 635 $('.hrd-content-wallet').css('display', 'none'); 636 637 $('#hrd-logout-text').text(getLangInt() === 1 ? 'Back' : 'è¿å'); 638 const formData = {}; 639 window.scrollTo(0, 0); 640 // back to reward list for reward, wallet page for gift 641 $('.hrd-back').attr('data-target', rewardId ? 'reward' : 'wallet'); 642 643 if (rewardId) { 644 formData['RewardId'] = rewardId; 645 callAjaxAction('get_hr_reward_detail', 'reward_detail', formData); 646 } else if (giftId) { 647 formData['GiftId'] = giftId; 648 callAjaxAction('get_hr_gift_detail', 'gift_detail', formData); 649 } 650 } 651 }); 652 653 // click use coupon
654 $(document).on('click', '.hrdmc-use-coupon', (e) => { 655 let self = $(e.target); 656 const name = self.data('name'); 657 $('.hrdm-use-name').text(name); 658 659 const qty = self.data('qty'); 660 const gift = self.data('gift'); 661 662 $("#hr-giftIds").val(gift); 663 const selectLabel = $("#hr-qty-label"); 664 const labelText = selectLabel.text(); 665 selectLabel.text(labelText.replace(/\d+/g, qty)); 666 const select = $("#hr-qty"); 667 select.empty(); 668 for (let i = 1; i <= +qty; i++) { 669 const option = `<option value="${i}">${i}</option>`; 670 select.append(option); 671 } 672 673 $('#useModal').addClass('hr-show'); 674 675 }) 676 677 if ($('#hrdm-no-gift').length > 0) { 678 handleMemberDataHeaderActionClick('hrdh-wallet'); 679 } 680 681 // qr code 682 const qrDiv = $("#hrdh-qr-code"); 683 if (qrDiv.length > 0) { 684 generateQRCode('hrdh-qr-code', qrDiv.data('type')); 685 } 686 687 // back 688 const hrBack = $("#hrd-back"); 689 if (hrBack.length > 0) { 690 hrBack.on('click', (e) => { 691 if ($(".hrd-general").css('display') === 'none') { 692 const self = $(e.target) 693 memberDataSessionChanged(`hrdh-${self.data('target') ?? 'reward'}`); 694 } else { 695 logout(hrBack.data('href')); 696 } 697 }) 698 } 699 700 // default show exclusive rewards 701 if ($("#hrdh-reward").length > 0) { 702 handleMemberDataHeaderActionClick('hrdh-reward'); 703 } 704 705});
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.