1$(document).ready(function(){ 2 //set active selected menu navbar 3 var path = window.location.href; 4 $('ul a').each(function() { 5 if (this.href === path) { 6 $(this).addClass('active'); 7 } 8 }); 9 10 //initiate cart 11 getFullCart(); 12 getFullCartNoLogin(); 13 14 //nav tab location option 15 $('#location-option a').on('click', function (location) { 16 location.preventDefault(); 17 $(this).tab('show'); 18 }); 19 20 getPointsAndVouchersNav(); 21}); 22 23function listCart(objCart){ 24 let cartContainer = $('div#show-cart'); 25 let cartInfo = $('div#cart-info'); 26 cartInfo.html(``); 27 cartContainer.html(``); 28 29 let chekoutButton = $('a#checkout-button'); 30 let cart = JSON.parse(objCart); 31 let total_items_qty = 0; 32 let total_items_price = 0; 33 34 if (!$.isEmptyObject(cart)){ 35 if((typeof cart.statusCode !== "undefined") && (cart.statusCode === 0)){ 36 if((!$.isEmptyObject(cart.response)) && (typeof cart.response !== "undefined")){ 37 if(cart.response.items.length === 0){ 38 //if length items = 0 39 cartContainer.append(`<div class='alert alert-danger' role='alert'>${cart.message}</div>`); 40 chekoutButton.hide(); 41 } else { 42 $.each(cart.response.items, function (index, menu) { 43 let menuPrice = parseInt(menu.cart_item_qty) * parseInt(menu.menu_price); 44 45 total_items_qty += parseInt(menu.cart_item_qty); 46 total_items_price += menuPrice; 47 48 //console.log(menu); 49 50 cartContainer.append(` 51 <form id="form-update-menu-${menu.cart_item_id}"> 52 <div class="card card-rounded mb-3"> 53 <div class="card-body"> 54 <div class="row"> 55 <div class="col-6 col-md-2 mb-3 d-flex align-items-center justify-content-center justify-content-md-start"> 56 <img class="img-fluid rounded my-auto" src="${menu.menu_picture}" style="max-width: 50px"> 57 </div> 58 <div class="col-6 col-md-3 mb-3 d-flex align-items-start flex-column justify-content-start"> 59 <p class="small mb-0">${menu.menu_name_idn}</p> 60 ${ 61 menu.menu_no_plu_simplification && menu.cart_item_simplification_notes 62 ? `<p class="small text-muted mb-0">${JSON.parse(menu.cart_item_simplification_notes).join(', ')}</p>` 63 : '' 64 } 65 </div> 66 <div class="col-6 col-md-4 mb-3 d-flex align-items-center"> 67 <input type="number" id="cart-cart-item-qty-${menu.cart_item_id}" name="cart_item_qty" min="1" max="50" class="form-control" value="${menu.cart_item_qty}"> 68 </div> 69 <div class="col-6 col-md-3 mb-3 d-flex align-items-center justify-content-end"> 70 <p class="small mb-0" id="cart-item-price-${menu.cart_item_id}">Rp. ${menuPrice.toLocaleString("id-ID")}</p> 71 </div> 72 </div> 73 <div id="cart-addon-upgrade-${menu.cart_item_id}"></div> 74 <div class="form-group"> 75 <label for="order-menu-notes-update" class="small">${cart.response.note_title} :</label> 76 <textarea class="form-control form-control-sm" id="cart-cart-item-notes-${menu.cart_item_id}" name="cart_item_notes" rows="1">${menu.cart_item_notes}</textarea> 77 </div> 78 <div class="d-flex flex-row justify-content-center"> 79 <button class="btn btn-sm btn-outline-hokben mr-3" type="button" onclick="updateMenu(${menu.cart_item_id})">${cart.response.updateBtn}</button> 80 <button type="button" class="btn btn-sm btn-primary-hokben" onclick="deleteMenu(${menu.store_id},${menu.cart_item_id})">${cart.response.deleteBtn}</button> 81 </div> 82 </div> 83 </div> 84 <input type="hidden" name="store_id" value="${cart.response.store_id}"/> 85 <input type='hidden' name='service_id' value="${cart.response.service_id}"/> 86 <input type="hidden" name="parent_menu_no_plu" value="${menu.menu_no_plu}"/> 87 <input type="hidden" name="parent_category_id" value="${menu.category_id}"/> 88 <input type="hidden" name="parent_cart_item_id" value="${menu.cart_item_id}"/> 89 90 ${(() => { 91 let flavor = ""; 92 let fried_menu = ""; 93 if (menu.cart_item_simplification_notes) { 94 const notesArray = JSON.parse(menu.cart_item_simplification_notes); 95 flavor = notesArray[0] || ""; 96 fried_menu = notesArray[1] || ""; 97 } 98 return ` 99 <input type="hidden" name="flavor" value="${flavor}"/> 100 <input type="hidden" name="fried_menu" value="${fried_menu}"/> 101 `; 102 })()} 103 </form> 104 `); 105 106 107 cartAddonUpgrade(menu.upgrade,menu.cart_item_id); 108 cartAddonUpgrade(menu.addon,menu.cart_item_id); 109 110 let spinner = $("input#cart-cart-item-qty-"+menu.cart_item_id); 111 let notes = $("textarea#cart-cart-item-notes-"+menu.cart_item_id); 112 113 spinner.inputSpinner(); 114 spinner.attr("min",'1'); 115 spinner.attr("max",cart.response.max_order); 116 117 var clickTimeout; 118 119 spinner.on("input change", function (event) { 120 clearTimeout(clickTimeout); 121 clickTimeout = setTimeout(function(){ 122 updateMenu(menu.cart_item_id); // replace with your update code 123 }, 500); 124 }); 125 126 notes.on("keyup change", function (event) { 127 clearTimeout(clickTimeout); 128 clickTimeout = setTimeout(function(){ 129 updateMenu(menu.cart_item_id); // replace with your update code 130 }, 500); 131 }); 132 }); 133 134 chekoutButton.show(); 135 cartInfo.append(` 136 <table class="table table-sm table-borderless w-auto"> 137 <tr> 138 <td class="small">${cart.response.service_title}</td> 139 <td class="small">:</td> 140 <td class="text-hokben-red small">${cart.response.service_name}</td> 141 </tr> 142 <tr> 143 <td class="small">Outlet</td> 144 <td class="small">:</td> 145 <td class="small text-hokben-red">${cart.response.store_name}</td> 146 </tr> 147 </table> 148 `); 149 } 150 } else { 151 cartContainer.append(`<div class='alert alert-danger' role='alert'>${cart.message}</div>`); 152 chekoutButton.hide(); 153 } 154 } else { 155 cartContainer.append(`<div class='alert alert-danger' role='alert'>${cart.message}</div>`); 156 chekoutButton.hide(); 157 } 158 } else { 159 cartContainer.append(`<div class='alert alert-danger' role='alert'>${cart.message}</div>`); 160 chekoutButton.hide(); 161 } 162 163 if(total_items_qty >= 100){ 164 $('span#cart-counter').html('99+'); 165 } else { 166 $('span#cart-counter').html(total_items_qty); 167 } 168 169 $('p#cart-subtotal').text('Rp. ' + total_items_price.toLocaleStr
169ing("id-ID")); 170} 171 172function getFullCart(){ 173 var result = get(baseurl + "cart"); 174 result.done(function(objCart) { 175 listCart(hexDecode(objCart)); 176 }); 177} 178 179function cartAddonUpgrade(items,cart_item_id) { 180 let childContainer = $('div#cart-addon-upgrade-'+cart_item_id); 181 182 if(items !== null){ 183 $.each(items, function (index,item) { 184 let menuPrice = parseInt(item.cart_item_qty) * parseInt(item.menu_price); 185 childContainer.append(` 186 <div class="row"> 187 <div class="col-2 mb-3 d-flex align-items-center justify-content-start"><img class="img-fluid rounded my-auto" src="${item.menu_picture}" style="max-width: 50px"></div> 188 <div class="col-2 col-md-3 mb-3 d-flex align-items-center justify-content-start"><p class="small mb-0">${item.menu_name_idn}</p></div> 189 <div class="col-5 col-md-4 mb-3 d-flex align-items-center"><input type="number" id="cart-cart-item-qty-${item.cart_item_id}" name="cart_item_qty" min="1" max="50" class="form-control form-control-sm" value="${item.cart_item_qty}"></div> 190 <div class="col-3 mb-3 d-flex align-items-center justify-content-end"><p class="small mb-0">Rp. ${menuPrice.toLocaleString("id-ID")}</p></div> 191 </div> 192 `); 193 }); 194 } 195} 196 197function setLocale(locale){ 198 let result = post(baseurl + "set-locale", { 199 lang: locale, 200 [csrfName] : csrfHash 201 }); 202 203 result.done(function (result) { 204 $ret = JSON.parse(hexDecode(result)); 205 csrfHash = $ret.csrfhash; 206 location.reload(); 207 }); 208} 209 210//for nav 211function getPointsAndVouchersNav() { 212 var result = get(baseurl + 'vouchers/status'); 213 214 result.done(function (result) { 215 var obj = JSON.parse(hexDecode(result)); 216 217 $('#PointsValue').text(obj.points); 218 $('#VouchersValue').text(obj.vouchers); 219 }) 220} 221 222function checkCartSelectedMenu(menuId, recommended = undefined) { 223 var result = get(baseurl + "cart"); 224 225 result.done(function (obj) { 226 var cart = JSON.parse(hexDecode(obj)); 227 var sameMenuContainer = $('div#show-add-same-menu'); 228 sameMenuContainer.html(``); 229 var found = false; 230 var menuFound = {}; 231 232 if (!$.isEmptyObject(cart)){ 233 if(cart.statusCode === 0){ 234 if(!$.isEmptyObject(cart.response)){ 235 if(cart.response.items.length !== 0){ 236 var items = []; 237 238 $.each(cart.response.items, function (index, item) { 239 if(item.menu_store_id == menuId){ 240 found = true; 241 items.push(item); 242 } 243 }); 244 245 menuFound = { 246 store_id : cart.response.store_id, 247 service_id : cart.response.service_id, 248 items : items 249 }; 250 } 251 } 252 } 253 } 254 255 if (found === true){ 256 $.each(menuFound.items, function (index, menu) { 257 sameMenuContainer.append(` 258 <form id="update-selected-menu${menu.cart_item_id}"> 259 <div class="card card-rounded mb-3"> 260 <div class="card-body"> 261 <div class="row"> 262 <div class="col-4 mb-3 d-flex align-items-center justify-content-start"><img class="img-fluid rounded my-auto" src="${menu.menu_picture}" style="max-width: 50px"></div> 263 <div class="col-3 col-md-4 mb-3 d-flex align-items-center justify-content-start"><p class="small mb-0">${menu.menu_name_idn}</p> 264 ${ 265 menu.menu_no_plu_simplification && menu.cart_item_simplification_notes 266 ? `<p class="small text-muted mb-0">${JSON.parse(menu.cart_item_simplification_notes).join(', ')}</p>` 267 : '' 268 } 269 </div> 270 <div class="col-5 col-md-4 mb-3 d-flex align-items-center"><input type="number" id="same-cart-item-qty-${menu.cart_item_id}" name="cart_item_qty" min="1" max="50" class="form-control form-control-sm" value="${menu.cart_item_qty}"></div> 271 </div> 272 <div id="cart-addon-upgrade-${menu.cart_item_id}"></div> 273 <div class="form-group"> 274 <label for="order-menu-notes-update" class="small">${cart.response.note_title} :</label> 275 <textarea class="form-control form-control-sm" id="same-cart-item-notes-${menu.cart_item_id}" name="cart_item_notes" rows="1">${menu.cart_item_notes}</textarea> 276 </div> 277 <div class="d-flex justify-content-center"> 278 <button class="btn btn-sm btn-outline-hokben mr-3" type="button" onclick="updateSelectedMenu(${menu.cart_item_id})" data-dismiss="modal">${cart.response.updateBtn}</button> 279 </div> 280 </div> 281 </div> 282 <input type="hidden" name="store_id" value="${menuFound.store_id}"/> 283 <input type='hidden' name='service_id' value="${menuFound.service_id}"/> 284 <input type="hidden" name="parent_menu_no_plu" value="${menu.menu_no_plu}"/> 285 <input type="hidden" name="parent_category_id" value="${menu.category_id}"/> 286 <input type="hidden" name="parent_cart_item_id" value="${menu.cart_item_id}"/> 287 288 ${(() => { 289 let flavor = ""; 290 let fried_menu = ""; 291 if (menu.cart_item_simplification_notes) { 292 const notesArray = JSON.parse(menu.cart_item_simplification_notes); 293 flavor = notesArray[0] || ""; 294 fried_menu = notesArray[1] || ""; 295 } 296 return ` 297 <input type="hidden" name="flavor" value="${flavor}"/> 298 <input type="hidden" name="fried_menu" value="${fried_menu}"/> 299 `; 300 })()} 301 </form> 302 `); 303 304 let spinner = $("input#same-cart-item-qty-"+menu.cart_item_id); 305 let notes = $("textarea#same-cart-item-notes-"+menu.cart_item_id); 306 307 spinner.inputSpinner(); 308 spinner.attr("min",'1'); 309 spinner.attr("max",cart.response.max_order); 310 311 var clickTimeout; 312 313 spinner.on("input change", function (event) { 314 clearTimeout(clickTimeout); 315 clickTimeout = setTimeout(function(){ 316 updateSelectedMenu(menu.cart_item_id); // replace with your update code 317 }, 500); 318 }); 319 320 notes.on("change keyup", function (event) { 321 clearTimeout(clickTimeout); 322 clickTimeout = setTimeout(function(){ 323 updateSelectedMenu(menu.cart_item_id); // replace with your update code 324 }, 500); 325 }); 326 327 $('#confirmMakeAnotherBtn').unbind(); 328 $('#confirmMakeAnotherBtn').bind('click', function () { 329 makeAnother(menuId, recommended); 330 }); 331 332 $('#sameMenuModal').modal('show'); 333 }); 334 } else { 335 $('#menuModal' + menuId + (recommended ? "-r" : "")).modal('show'); 336 } 337 }); 338} 339 340function checkActiveOrder() { 341 get(baseurl + 'checkorder').done(function (result) { 342 var res = JSON.parse(hexDecode(result)); 343 if(res.status === "active"){ 344 var alertModal = $('#ActiveOrderModal'); 345 alertModal.modal({backdrop: 'static', keyboard: false}); 346 alertModal.modal('show'); 347 } else if(res.status === "unauthorized"){ 348 window.location.href = baseurl+'login'; 349 } 350 }); 351} 352 353function makeAnother(menuId, recommended = undefined) 354{ 355 $('#sameMenuModal').modal('hide'); 356 $('#menuModal' + menuId + (recommended ? "-r" : "")).modal('show'); 357} 358 359function changeCart(menuId) 360{ 361 $('#cartConfirmationModal').modal('hide'); 362 selectMenu(menuId,true); 363} 364 365function selectMenu(menuId,force = false,source = null){ 366 var changeCartBtn = $('#changeCartBtn'); 367 var data = $('#form-menu-'+menuId).serializeArray(); 368 369 if(force === true){ 370 data.push({name: 'force', value: true}); 371 } 372 373 var select = post(baseurl + "cart", objectifyForm(data)); 374 375 select.done(function (objCart) { 376 let cart = JSON.parse(hexDecode(objCart)); 377 378 if (cart.statusCode === -111){ 379 changeCartBtn.unbind(); //clear bind event before 380 $('#cartConfirmationModal').modal('show'); 381 changeCartBtn.bind('click',function () { 382 changeCart(menuId); 383 }); 384 } else { 385 analytics.logEvent('add_to_cart', { menu_id : menuId }); 386 387 $('#form-menu-'+menuId).trigger("reset"); 388 $('input#cart-item-qty-'+menuId).val(1); 389 listCart(hexDecode(objCart)); 390 391 if((source !== null) && (source === "recc")){ 392 location.reload(); 393 } 394 } 395 }); 396} 397 398function updateSelectedMenu(ParentId) { 399 var data = objectifyForm($('#update-selected-menu'+ParentId).serializeArray()); 400 var result = post(baseurl + "cart", data); 401 402 result.done(function (objCart) { 403 listCart(hexDecode(objCart)); 404 }); 405} 406 407function updateMenu(ParentId,ExtrasId) 408{ 409 var option = ""; 410 411 //untuk update child item (hanya hapus, qty = 0) 412 var data = objectifyForm($('#form-update-menu-'+ParentId).serializeArray()); 413 if (ExtrasId != null){ 414 data["updateExtrasItem"] = ExtrasId; 415 } 416 417 var result = post(baseurl + "cart", data); 418 419 result.done(function (objCart) { 420 listCart(hexDecode(objCart)) 421 }); 422} 423 424function deleteMenu(storeId,cartItem) { 425 var result = post(baseurl + "deletecartitem", { 426 store_id : storeId, 427 cart_item_id : cartItem, 428 [csrfName] : csrfHash 429 }); 430 431 result.done(function (objCart) { 432 listCart(hexDecode(objCart)) 433 }); 434} 435 436function postLocation(service_id) { 437 if (navigator.geolocation) { 438 navigator.geolocation.getCurrentPosition(function (position) { 439 postNearestStore(position.coords.latitude,position.coords.longitude,service_id); 440 }); 441 } else { 442 alert("Geolocation is not supported by this browser."); 443 } 444} 445 446function postNearestStore(lat,lon,service_id) { 447 var result = post(baseurl + "service/outlet", { 448 service_id: service_id, 449 cust_addr_long: lon, 450 cust_addr_lat: lat, 451 [csrfName] : csrfHash 452 }); 453 454 result.done(function (res) { 455 $("html").html(hexDecode(res)); 456 }); 457} 458 459function confirmReplacePayment() { 460 $('#payment_method_replace').val($('input[name="payment_method"]:checked').val()); 461 $('#forceCancelBtn').unbind(); 462 $('#forceCancelBtn').on('click',function () { 463 $('#cancelPaymentMessageModal').modal('hide'); 464 $('#confirmCancelPaymentMessageModal').modal('show'); 465 }); 466 $('#confirmForceCancelBtn').unbind(); 467 $('#confirmForceCancelBtn').on('click',function () { 468 $('#form_create_payment').submit(); 469 }); 470 $('#cancelPaymentMessageModal').modal('show'); 471} 472 473function confirmCancelPayment(party = false) { 474 $('#forceCancelBtn').unbind(); 475 $('#forceCancelBtn').on('click',function () { 476 $('#cancelPaymentMessageModal').modal('hide'); 477 $('#confirmCancelPaymentMessageModal').modal('show'); 478 }); 479 $('#confirmForceCancelBtn').unbind(); 480 $('#confirmForceCancelBtn').on('click',function () { 481 let result = post(baseurl+'order/payment/cancel', { 482 [csrfName]: csrfHash, 483 payment_id : $('#active_payment_id').val(), 484 order_id : $('#order_id').val() 485 }); 486 487 result.done(function (cancelOrder) { 488 var resCancelOrder = JSON.parse(hexDecode(cancelOrder)); 489 if(resCancelOrder.res === true){ 490 if(party === true){ 491 window.location.href = baseurl + 'order/party'; 492 } else { 493 window.location.href = baseurl + 'order/review-order'; 494 } 495 } else { 496 $('#cancelPaymentMessageModal').modal('hide'); 497 } 498 }); 499 }); 500 $('#cancelPaymentMessageModal').modal('show'); 501 502} 503 504function checkFields(menuStoreId, parentNoPlu) { 505 const form = document.getElementById(`form-menu-${menuStoreId}`); 506 const selectedFlavor = form.querySelector('input[name="flavor"]:checked')?.value; 507 const selectedFriedMenu = form.querySelector('input[name="fried_menu"]:checked')?.value; 508 509 // Kirim data menggunakan AJAX 510 $.post(baseurl + 'order/get-simplification-plu-by-param', { 511 [csrfName]: csrfHash, 512 parent_no_plu: parentNoPlu, 513 flavor: selectedFlavor, 514 fried_menu: selectedFriedMenu 515 }) 516 .done(function (result) { 517 showModal(result.response[0].image); 518 updateNutritionFact(menuStoreId, result.response[0].menu_nutrition); 519 520 }) 521 .fail(function (xhr) { 522 console.error('Error:', xhr.responseText); 523 }); 524 525} 526 527 528function updateNutritionFact(menuStoreId, nutritionData) { 529 530 // Pastikan container ada 531 let container = document.getElementById(`nutrition-facts-container-${menuStoreId}`); 532 if (!container) { 533 console.error(`Container nutrition-facts-container-${menuStoreId} tidak ditemukan`); 534 return; 535 } 536 537 // Kosongkan container sebelum menambahkan elemen baru 538 container.innerHTML = ''; 539 540 if (typeof nutritionData === "string") { 541 try { 542 nutritionData = JSON.parse(nutritionData); 543 } catch (error) { 544 console.error("Gagal parse menu_nutrition:", error); 545 return; 546 } 547 } 548 549 if (Array.isArray(nutritionData)) { 550 nutritionData.forEach(nutrition => { 551 // Jika picture null, pakai gambar default 552 let imageSrc = (nutrition.picture && nutrition.picture !== "null") 553 ? nutrition.picture 554 : "https://hokben-image.s3.ap-southeast-3.amazonaws.com/img_assets/menu/no_photos.png"; 555 556 let item = ` 557 <div class="pr-4 d-flex flex-column menu-nutrition"> 558 <img class="mx-auto d-block mb-1" width="30" src="${imageSrc}" loading="lazy" alt="${nutrition.name_en}"> 559 <p class="small text-center mb-1">${nutrition.name_en}</p> 560 <p class="small text-center text-hokben-red">${nutrition.value}</p> 561 </div> 562 `;
563 container.innerHTML += item; 564 }); 565 } else { 566 console.warn("menu_nutrition bukan array atau tidak ditemukan."); 567 } 568} 569 570 571function updateModal(imageUrl) { 572 const modalContent = document.getElementById('modal-content'); 573 modalContent.innerHTML = imageUrl 574 ? `<img src="${imageUrl}" alt="Selected Combination" style="width:100%; height:100%; object-fit:cover;">` 575 : '<p>No image available for the selected combination.</p>'; 576} 577 578function showModal(imageUrl) { 579 updateModal(imageUrl); 580 const modal = document.getElementById('popUpModal'); 581 582 modal.style.display = 'block'; 583 setTimeout(() => { 584 modal.classList.add('show'); 585 }, 10); 586} 587 588function closeModal() { 589 const modal = document.getElementById('popUpModal'); 590 modal.classList.remove('show'); 591 592 setTimeout(() => { 593 modal.style.display = 'none'; 594 }, 500); 595} 596 597
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.