1function getURLVar(key) { 2 var value = []; 3 4 var query = String(document.location).split('?'); 5 6 if (query[1]) { 7 var part = query[1].split('&'); 8 9 for (i = 0; i < part.length; i++) { 10 var data = part[i].split('='); 11 12 if (data[0] && data[1]) { 13 value[data[0]] = data[1]; 14 } 15 } 16 17 if (value[key]) { 18 return value[key]; 19 } else { 20 return ''; 21 } 22 } 23} 24 25$(document).ready(function() { 26 // Tooltip 27 var oc_tooltip = function() { 28 // Get tooltip instance 29 tooltip = bootstrap.Tooltip.getInstance(this); 30 if (!tooltip) { 31 // Apply to current element 32 tooltip = bootstrap.Tooltip.getOrCreateInstance(this); 33 tooltip.show(); 34 } 35 } 36 37 $(document).on('mouseenter', '[data-bs-toggle=\'tooltip\']', oc_tooltip); 38 39 $(document).on('click', 'button', function() { 40 $('.tooltip').remove(); 41 }); 42 43 // Date 44 var oc_datetimepicker = function() { 45 $(this).daterangepicker({ 46 singleDatePicker: true, 47 autoApply: true, 48 autoUpdateInput: false, 49 locale: { 50 format: 'YYYY-MM-DD' 51 } 52 }, function(start, end) { 53 $(this.element).val(start.format('YYYY-MM-DD')); 54 }); 55 } 56 57 $(document).on('focus', '.date', oc_datetimepicker); 58 59 // Time 60 var oc_datetimepicker = function() { 61 $(this).daterangepicker({ 62 singleDatePicker: true, 63 datePicker: false, 64 autoApply: true, 65 autoUpdateInput: false, 66 timePicker: true, 67 timePicker24Hour: true, 68 locale: { 69 format: 'HH:mm' 70 } 71 }, function(start, end) { 72 $(this.element).val(start.format('HH:mm')); 73 }).on('show.daterangepicker', function(ev, picker) { 74 picker.container.find('.calendar-table').hide(); 75 }); 76 } 77 78 $(document).on('focus', '.time', oc_datetimepicker); 79 80 // Date Time 81 var oc_datetimepicker = function() { 82 $(this).daterangepicker({ 83 singleDatePicker: true, 84 autoApply: true, 85 autoUpdateInput: false, 86 timePicker: true, 87 timePicker24Hour: true, 88 locale: { 89 format: 'YYYY-MM-DD HH:mm' 90 } 91 }, function(start, end) { 92 $(this.element).val(start.format('YYYY-MM-DD HH:mm')); 93 }); 94 } 95 96 $(document).on('focus', '.datetime', oc_datetimepicker); 97 98 var oc_alert = function() { 99 window.setTimeout(function() { 100 $('.alert-dismissible').fadeTo(3000, 0, function() { 101 $(this).remove(); 102 }); 103 }, 3000); 104 } 105 106 $(document).on('click', 'button', oc_alert); 107 $(document).on('click', 'change', oc_alert); 108}); 109 110$(document).ready(function() { 111 // Currency 112 $('#form-currency .dropdown-item').on('click', function(e) { 113 e.preventDefault(); 114 115 $('#form-currency input[name=\'code\']').val($(this).attr('href')); 116 117 $('#form-currency').submit(); 118 }); 119 120 // Search 121 $('#search input[name=\'search\']').parent().find('button').on('click', function() { 122 var url = $('base').attr('href') + 'index.php?route=product/search&language=' + $(this).attr('data-lang'); 123 124 var value = $('header #search input[name=\'search\']').val(); 125 126 if (value) { 127 url += '&search=' + encodeURIComponent(value); 128 } 129 130 location = url; 131 }); 132 133 $('#search input[name=\'search\']').on('keydown', function(e) { 134 if (e.keyCode == 13) { 135 $('header #search input[name=\'search\']').parent().find('button').trigger('click'); 136 } 137 }); 138 139 // Menu 140 $('#menu .dropdown-menu').each(function() { 141 var menu = $('#menu').offset(); 142 var dropdown = $(this).parent().offset(); 143 144 var i = (dropdown.left + $(this).outerWidth()) - (menu.left + $('#menu').outerWidth()); 145 146 if (i > 0) { 147 $(this).css('margin-left', '-' + (i + 10) + 'px'); 148 } 149 }); 150 151 // Product List 152 $('#button-list').on('click', function() { 153 var element = this; 154 155 $('#product-list').attr('class', 'row row-cols-1 product-list'); 156 157 $('#button-grid').removeClass('active'); 158 $('#button-list').addClass('active'); 159 160 localStorage.setItem('display', 'list'); 161 }); 162 163 // Product Grid 164 $('#button-grid').on('click', function() { 165 var element = this; 166 167 // What a shame bootstrap does not take into account dynamically loaded columns 168 $('#product-list').attr('class', 'row row-cols-1 row-cols-sm-2 row-cols-md-2 row-cols-lg-3'); 169 170 $('#button-list').removeClass('active'); 171 $('#button-grid').addClass('active'); 172 173 localStorage.setItem('display', 'grid'); 174 }); 175 176 // Local Storage 177 if (localStorage.getItem('display') == 'list') { 178 $('#product-list').attr('class', 'row row-cols-1 product-list'); 179 $('#button-list').addClass('active'); 180 } else { 181 $('#product-list').attr('class', 'row row-cols-1 row-cols-sm-2 row-cols-md-2 row-cols-lg-3'); 182 $('#button-grid').addClass('active'); 183 } 184 185 /* Agree to Terms */ 186 $('body').on('click', '.modal-link', function(e) { 187 e.preventDefault(); 188 189 var element = this; 190
191 $('#modal-information').remove(); 192 193 $.ajax({ 194 url: $(element).attr('href'), 195 dataType: 'html', 196 success: function(html) { 197 $('body').append(html); 198 199 $('#modal-information').modal('show'); 200 } 201 }); 202 }); 203 204 // Cookie Policy 205 $('#cookie button').on('click', function() { 206 var element = this; 207 208 $.ajax({ 209 url: $(this).val(), 210 type: 'get', 211 dataType: 'json', 212 beforeSend: function() { 213 $(element).button('loading'); 214 }, 215 complete: function() { 216 $(element).button('reset'); 217 }, 218 success: function(json) { 219 if (json['success']) { 220 $('#cookie').fadeOut(400, function() { 221 $('#cookie').remove(); 222 }); 223 } 224 }, 225 error: function(xhr, ajaxOptions, thrownError) { 226 console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 227 } 228 }); 229 }); 230}); 231 232// Forms 233$(document).on('submit', 'form', function (e) { 234 var element = this; 235 236 if (e.originalEvent !== undefined && e.originalEvent.submitter !== undefined) { 237 var button = e.originalEvent.submitter; 238 } else { 239 var button = ''; 240 } 241 242 var status = false; 243 244 var ajax = $(element).attr('data-oc-toggle'); 245 246 if (ajax == 'ajax') { 247 status = true; 248 } 249 250 var ajax = $(button).attr('data-oc-toggle'); 251 252 if (ajax == 'ajax') { 253 status = true; 254 } 255 256 if (status) { 257 e.preventDefault(); 258 259 // Form attributes 260 var form = e.target; 261 262 var action = $(form).attr('action'); 263 264 var method = $(form).attr('method'); 265 266 if (method === undefined) { 267 method = 'post'; 268 } 269 270 var enctype = $(form).attr('enctype'); 271 272 if (enctype === undefined) { 273 enctype = 'application/x-www-form-urlencoded'; 274 } 275 276 // Form button overrides 277 var formaction = $(button).attr('formaction'); 278 279 if (formaction !== undefined) { 280 action = formaction; 281 } 282 283 var formmethod = $(button).attr('formmethod'); 284 285 if (formmethod !== undefined) { 286 method = formmethod; 287 } 288 289 var formenctype = $(button).attr('formenctype'); 290 291 if (formenctype !== undefined) { 292 enctype = formenctype; 293 } 294 295 if (button) { 296 var formaction = $(button).attr('data-type'); 297 } 298 299 console.log(e); 300 console.log('element ' + element); 301 console.log('action ' + action); 302 console.log('button ' + button); 303 console.log('formaction ' + formaction); 304 console.log('method ' + method); 305 console.log('enctype ' + enctype); 306 console.log($(element).serialize()); 307 308 // https://github.com/opencart/opencart/issues/9690 309 if (typeof CKEDITOR != 'undefined') { 310 for (instance in CKEDITOR.instances) { 311 CKEDITOR.instances[instance].updateElement(); 312 } 313 } 314 315 $.ajax({ 316 url: action.replaceAll('&', '&'), 317 type: method, 318 data: $(form).serialize(), 319 dataType: 'json', 320 contentType: enctype, 321 beforeSend: function () { 322 $(button).button('loading'); 323 }, 324 complete: function () { 325 $(button).button('reset'); 326 }, 327 success: function (json, textStatus) { 328 console.log(json); 329 console.log(textStatus); 330 331 $('.alert-dismissible').remove(); 332 $(element).find('.is-invalid').removeClass('is-invalid'); 333 $(element).find('.invalid-feedback').removeClass('d-block'); 334 335 if (json['redirect']) { 336 location = json['redirect']; 337 } 338 339 if (typeof json['error'] == 'string') { 340 $('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>'); 341 } 342 343 if (typeof json['error'] == 'object') { 344 if (json['error']['warning']) { 345 $('#alert').prepend('<dirv class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error']['warning'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></dirv>'); 346 } 347 348 for (key in json['error']) { 349 $('#input-' + key.replaceAll('_', '-')).addClass('is-invalid').find('.form-control, .form-select, .form-check-input, .form-check-label').addClass('is-invalid'); 350 $('#error-' + key.replaceAll('_', '-')).html(json['error'][key]).addClass('d-block'); 351 } 352 } 353 354 if (json['success']) { 355 $('#alert').prepend('<div class="alert alert-success alert-dismissible"><i class="fa-solid fa-circle-check"></i> ' + json['success'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>'); 356 357 // Refresh 358 var url = $(form).attr('data-oc-load'); 359 var target = $(form).attr('data-oc-target'); 360 361 if (url !== undefined && target !== undefined) { 362 $(target).load(url); 363 } 364 } 365 366 // Replace any form values that correspond to form names. 367 for (key in json) { 368 $(element).find('[name=\'' + key + '\']').val(json[key]); 369 } 370 }, 371 error: function (xhr, ajaxOptions, thrownError) { 372 console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 373 } 374 }); 375 } 376}); 377 378// Upload 379$(document).on('click', 'button[data-oc-toggle=\'upload\']', function() { 380 var element = this; 381 382 if (!$(element).prop('disabled')) { 383 $('#form-upload').remove(); 384 385 $('body').prepend('<form enctype="multipart/form-data" id="form-upload" style="display: none;"><input type="file" name="file" value=""/></form>'); 386 387 $('#form-upload input[name=\'file\']').trigger('click'); 388 389 $('#form-upload input[name=\'file\']').on('change', function(e) { 390 if ((this.files[0].size / 1024) > $(element).attr('data-oc-size-max')) { 391 alert($(element).attr('data-oc-size-error')); 392 393 $(this).val(''); 394 } 395 }); 396 397 if (typeof timer !== 'undefined') { 398 clearInterval(timer); 399 } 400 401 var timer = setInterval(function() { 402 if ($('#form-upload input[name=\'file\']').val() != '') { 403 clearInterval(timer); 404 405 $.ajax({ 406 url: $(element).attr('data-oc-url'), 407 type: 'post', 408 data: new FormData($('#form-upload')[0]), 409 dataType: 'json', 410 cache: false, 411 contentType: false, 412 processData: false, 413 beforeSend: function() { 414 $(element).button('loading'); 415 }, 416 complete: function() { 417 $(element).button('reset'); 418 }, 419 success: function(json) { 420 console.log(json); 421 422 if (json['error']) { 423 alert(json['error']); 424 } 425 426 if (json['success']) { 427 alert(json['success']); 428 } 429 430 if (json['code']) { 431 $($(element).attr('data-oc-target')).attr('value', json['code']); 432 } 433 }, 434 error: function(xhr, ajaxOptions, thrownError) { 435 console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 436 } 437 }); 438 } 439 }, 500); 440 } 441}); 442 443// Chain ajax calls. 444class Chain { 445 constructor() { 446 this.start = false;
447 this.data = []; 448 } 449 450 attach(call) { 451 this.data.push(call); 452 453 if (!this.start) { 454 this.execute(); 455 } 456 } 457 458 execute() { 459 if (this.data.length) { 460 this.start = true; 461 462 var call = this.data.shift(); 463 464 var jqxhr = call(); 465 466 jqxhr.done(function() { 467 chain.execute(); 468 }); 469 } else { 470 this.start = false; 471 } 472 } 473} 474 475var chain = new Chain(); 476 477// Autocomplete 478+function($) { 479 $.fn.autocomplete = function(option) { 480 return this.each(function() { 481 var element = this; 482 var $dropdown = $('#' + $(element).attr('data-oc-target')); 483 484 this.timer = null; 485 this.items = []; 486 487 $.extend(this, option); 488 489 // Focus in 490 $(element).on('focusin', function() { 491 element.request(); 492 }); 493 494 // Focus out 495 $(element).on('focusout', function(e) { 496 if (!e.relatedTarget || !$(e.relatedTarget).hasClass('dropdown-item')) { 497 $dropdown.removeClass('show'); 498 } 499 }); 500 501 // Input 502 $(element).on('input', function(e) { 503 element.request(); 504 }); 505 506 // Click 507 $dropdown.on('click', 'a', function(e) { 508 e.preventDefault(); 509 510 var value = $(this).attr('href'); 511 512 if (element.items[value] !== undefined) { 513 element.select(element.items[value]); 514 515 $dropdown.removeClass('show'); 516 } 517 }); 518 519 // Request 520 this.request = function() { 521 clearTimeout(this.timer); 522 523 $('#autocomplete-loading').remove(); 524 525 $dropdown.prepend('<li id="autocomplete-loading"><span class="dropdown-item text-center disabled"><i class="fa-solid fa-circle-notch fa-spin"></i></span></li>'); 526 $dropdown.addClass('show'); 527 528 this.timer = setTimeout(function(object) { 529 object.source($(object).val(), $.proxy(object.response, object)); 530 }, 50, this); 531 } 532 533 // Response 534 this.response = function(json) { 535 var html = ''; 536 var category = {}; 537 var name; 538 var i = 0, j = 0; 539 540 if (json.length) { 541 for (i = 0; i < json.length; i++) { 542 // update element items 543 this.items[json[i]['value']] = json[i]; 544 545 if (!json[i]['category']) { 546 // ungrouped items 547 html += '<li><a href="' + json[i]['value'] + '" class="dropdown-item">' + json[i]['label'] + '</a></li>'; 548 } else { 549 // grouped items 550 name = json[i]['category']; 551 552 if (!category[name]) { 553 category[name] = []; 554 } 555 556 category[name].push(json[i]); 557 } 558 } 559 560 for (name in category) { 561 html += '<li><h6 class="dropdown-header">' + name + '</h6></li>'; 562 563 for (j = 0; j < category[name].length; j++) { 564 html += '<li><a href="' + category[name][j]['value'] + '" class="dropdown-item">' + category[name][j]['label'] + '</a></li>'; 565 } 566 } 567 } 568 569 $dropdown.html(html); 570 } 571 }); 572 } 573}(jQuery); 574 575// Button 576$(document).ready(function() { 577 +function($) { 578 $.fn.button = function(state) { 579 return this.each(function() { 580 var element = this; 581 582 if (state == 'loading') { 583 this.html = $(element).html(); 584 this.state = $(element).prop('disabled'); 585 586 $(element).prop('disabled', true).width($(element).width()).html('<i class="fa-solid fa-circle-notch fa-spin text-light"></i>'); 587 } 588 589 if (state == 'reset') { 590 $(element).prop('disabled', this.state).width('').html(this.html); 591 } 592 }); 593 } 594 }(jQuery); 595});
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.