1jQuery(document).ready(function(){ 2 loadMoreSearch(); 3 ajaxLoadProduct() 4}) 5 6function loadMoreSearch(){ 7 jQuery(document).delegate(".load-more-search", "click", function(e){ 8 e.preventDefault(); 9 10 var thisBtn = jQuery(this), 11 max = thisBtn.data("max"), 12 page = thisBtn.data("page"), 13 postType = thisBtn.data("post-type"), 14 limit = thisBtn.data("limit"), 15 search = thisBtn.data("search"); 16 17 18 jQuery.ajax({ 19 url: `${nk.ajax_url}?action=load_more_search`, 20 method: "POST", 21 data:{ 22 page : page, 23 postType : postType, 24 limit : limit, 25 search : search, 26 }, 27 beforeSend: function(){ 28 thisBtn.addClass("btn-loading"); 29 } 30 }).done(function(respond){ 31 jQuery(".search-tab-content.tab-"+postType+" .search-grid").append(respond.html); 32 page++; 33 if(page > max){ 34 thisBtn.remove(); 35 } 36 else{ 37 thisBtn.data("page", page); 38 } 39 }).fail(function(error){ 40 41 }).always(function(){ 42 thisBtn.removeClass("btn-loading"); 43 }) 44 }) 45} 46 47 48 49jQuery(function($){ 50 51 /* ========================= 52 1) Custom multi-dropdown 53 ========================= */ 54 function initMultiDropdown($select){ 55 const taxonomy = $select.data('taxonomy') || 'unknown'; 56 const placeholder = $select.find('option').first().text() || 'Select'; 57 58 // â nếu là filter_sort thì chá» cho chá»n 1 59 const isSingle = $select.attr('id') === 'filter_sort'; 60 61 const $wrap = $('<div class="custom-multidrop" data-taxonomy="'+taxonomy+'"></div>'); 62 const $trigger = $('<div class="trigger"><span class="label">'+placeholder+'</span><span class="caret">â¾</span></div>'); 63 const $panel = $('<div class="panel"></div>'); 64 65 $panel.append('<div class="note">Chá»n nhiá»u mục (click Äá» chá»n/bá» chá»n)</div>'); 66 67 $select.find('option').each(function(){ 68 const val = $(this).val(); 69 const txt = $(this).text(); 70 if(val === 'all') return; 71 const id = taxonomy + '_' + val; 72 73 const $item = $(` 74 <label class="item" for="${id}"> 75 <input type="checkbox" id="${id}" value="${val}" /> 76 <span class="txt">${txt}</span> 77 </label> 78 `); 79 80 $panel.append($item); 81 }); 82 83 $select.after($wrap); 84 $wrap.append($trigger).append($panel); 85 $select.hide(); 86 87 $trigger.on('click', function(e){ 88 e.stopPropagation(); 89 $('.custom-multidrop .panel').not($panel).slideUp(120); 90 $panel.stop(true, true).slideToggle(120); 91 }); 92 93 $panel.on('change', 'input[type="checkbox"]', function(){ 94 // â Nếu là single select thì bá» chá»n các option còn lại 95 if(isSingle && this.checked){ 96 $panel.find('input[type="checkbox"]').not(this).prop('checked', false); 97 } 98 99 updateTriggerLabel(); 100 }); 101 102 function updateTriggerLabel(){ 103 const selected = []; 104 $panel.find('input:checked').each(function(){ 105 selected.push($(this).siblings('.txt').text().trim()); 106 }); 107 108 const $label = $wrap.find('.trigger .label'); 109 110 if(selected.length === 0){ 111 $label.text(placeholder); 112 } else if(selected.length === 1){ 113 $label.text(selected[0]); 114 } else { 115 $label.text(selected.length + ' selected'); 116 } 117 } 118 119 $(document).on('click.'+taxonomy, function(e){ 120 if(!$(e.target).closest($wrap).length){ 121 $panel.slideUp(100); 122 } 123 }); 124 125 $wrap.data('getSelected', function(){ 126 const arr = []; 127 $panel.find('input[type="checkbox"]:checked').each(function(){ 128 arr.push($(this).val()); 129 }); 130 return arr; 131 }); 132 133 updateTriggerLabel(); 134 } 135 136 137 // Khá»i tạo dropdown (các select hiá»n có) 138 $('#filter_type, #filter_year,#filter_sort').each(function(){ 139 initMultiDropdown($(this)); 140 });
141 142 143 if (jQuery('.project_table_wrap').size()){ 144 /* ========================= 145 2) AJAX render + pagination 146 ========================= */ 147 function renderProjects(filters, paged = 1) { 148 filters = filters || {}; 149 150 $.ajax({ 151 url: `${nk.ajax_url}?action=filter_projects`, 152 method: 'POST', 153 data: { 154 filters: filters, 155 paged: paged, 156 }, 157 beforeSend: function(){ 158 $('.wrap_filter_project').addClass('loading'); 159 }, 160 success: function(res){ 161 $('.wrap_filter_project').removeClass('loading'); 162 if(res.success){ 163 $('.project_table_wrap').html(res.data.html); 164 165 // â Cáºp nháºt class active cho pagination 166 $('.ajax_pagination a').removeClass('active'); 167 $(`.ajax_pagination a[data-paged="${paged}"]`).addClass('active'); 168 169 // Cuá»n lên Äầu bảng (tùy chá»n UX) 170 $('html, body').animate({ 171 scrollTop: $('.project_table_wrap').offset().top - 200 172 }, 300); 173 } else { 174 $('.project_table_wrap').html('<p>No projects found.</p>'); 175 } 176 }, 177 error: function(){ 178 $('.wrap_filter_project').removeClass('loading'); 179 $('.project_table_wrap').html('<p>Error loading data.</p>'); 180 } 181 }); 182 183 $('.wrap_filter_project').data('lastFilters', filters); 184 $('.wrap_filter_project').data('lastPage', paged); 185 } 186 187 // Nút Apply 188 $('.actionFilter').on('click', function(e){ 189 e.preventDefault(); 190 const filters = {}; 191 $('.custom-multidrop').each(function(){ 192 const taxonomy = $(this).data('taxonomy'); 193 const vals = $(this).data('getSelected')(); 194 filters[taxonomy] = vals; 195 }); 196 197 const projectCatVals = []; 198 const $activeCat = $('.filter_cat a.active'); 199 if($activeCat.length){ 200 const id = $activeCat.data('id'); 201 if(String(id) !== 'all'){ 202 projectCatVals.push(String(id)); 203 } 204 } 205 filters['project-category'] = projectCatVals; 206 207 renderProjects(filters, 1); 208 }); 209 210 // Pagination click (delegated) 211 $(document).on('click', '.ajax_pagination a', function(e){ 212 e.preventDefault(); 213 const paged = $(this).data('paged') || 1; 214 const filters = $('.wrap_filter_project').data('lastFilters') || {}; 215 216 const $activeCat = $('.filter_cat a.active'); 217 if($activeCat.length){ 218 const id = $activeCat.data('id'); 219 if(String(id) === 'all'){ 220 filters['project-category'] = []; 221 } else { 222 filters['project-category'] = [ String(id) ]; 223 } 224 } 225 226 renderProjects(filters, paged); 227 }); 228 229 230 /* ========================= 231 3) Click on filter_cat (project-category) 232 ========================= */ 233 $(document).on('click', '.filter_cat a', function(e){ 234 e.preventDefault(); 235 const $a = $(this); 236 const id = String($a.data('id')); 237 238 $('.filter_cat a').removeClass('active'); 239 $a.addClass('active'); 240 241 const filters = {}; 242 $('.custom-multidrop').each(function(){ 243 const taxonomy = $(this).data('taxonomy'); 244 const vals = $(this).data('getSelected')(); 245 filters[taxonomy] = vals; 246 }); 247 248 if(id === 'all'){ 249 filters['project-category'] = []; 250 } else { 251 filters['project-category'] = [ id ]; 252 } 253 254 renderProjects(filters, 1); 255 }); 256 257 258 } 259 260 if (jQuery('.wrap_presentations').length){ 261 262 function renderRelations(filters, paged = 1, search = ''){ 263 filters = filters || {}; 264 265 $.ajax({
266 url: `${nk.ajax_url}?action=filter_relations`, 267 type: 'POST', 268 data: { 269 filters: filters, 270 paged: paged, 271 search: search 272 }, 273 beforeSend: function(){ 274 $('.wrap_filter_relation').addClass('loading'); 275 }, 276 success: function(res){ 277 $('.wrap_filter_relation').removeClass('loading'); 278 279 if(res.success){ 280 $('.wrap_presentations').html(res.data.html); 281 282 // Active pagination 283 $('.ajax_pagination a').removeClass('active'); 284 $(`.ajax_pagination a[data-paged="${paged}"]`).addClass('active'); 285 286 $('html, body').animate({ 287 scrollTop: $('.wrap_presentations').offset().top - 200 288 }, 300); 289 290 } else { 291 $('.wrap_presentations').html('<p>No relation found.</p>'); 292 } 293 }, 294 error:function(){ 295 $('.wrap_filter_relation').removeClass('loading'); 296 $('.wrap_presentations').html('<p>Error loading data</p>'); 297 } 298 }); 299 300 $('.wrap_filter_relation').data('lastFilters', filters); 301 $('.wrap_filter_relation').data('lastPage', paged); 302 $('.wrap_filter_relation').data('lastSearch', search); 303 } 304 305 // APPLY & SEARCH 306 $('.wrap_filter_relation').on('click','.actionFilter',function(e){ 307 e.preventDefault(); 308 309 const filters = {}; 310 311 $('.custom-multidrop').each(function(){ 312 const taxonomy = $(this).data('taxonomy'); 313 const vals = $(this).data('getSelected')(); 314 315 if(taxonomy === 'property-category'){ 316 filters['sort'] = vals[0] || ''; 317 } else { 318 filters[taxonomy] = vals; 319 } 320 }); 321 322 const search = $('#search_title').val().trim(); 323 324 renderRelations(filters,1, search); 325 }); 326 327 // PAGINATION 328 $(document).on('click','.ajax_pagination a',function(e){ 329 e.preventDefault(); 330 331 const paged = $(this).data('paged') || 1; 332 const filters = $('.wrap_filter_relation').data('lastFilters') || {}; 333 const search = $('.wrap_filter_relation').data('lastSearch') || ''; 334 335 renderRelations(filters, paged, search); 336 }); 337 338 } 339 340 341}); 342 343function ajaxLoadProduct(){ 344// Khá»i tạo Swiper 345 const sliderProduct = new Swiper(".slider_product", { 346 slidesPerView: "auto", 347 centeredSlides: false, 348 spaceBetween: 0, 349 navigation: { 350 nextEl: ".next", 351 prevEl: ".prev", 352 }, 353 }); 354 355// Khi click và o slide â active Äá»ng bá» vá»i danh sách 356 jQuery(document).ready(function ($) { 357 const $links = $('.product_list ul a'); 358 const $slides = $('.slider_product .swiper-slide'); 359 360 // ð¹ Active mặc Äá»nh: phần tá» Äầu tiên 361 $slides.removeClass('active').first().addClass('active'); 362 $links.removeClass('active').first().addClass('active'); 363 364 // ð¹ Click slide â di chuyá»n và active link tương ứng 365 $slides.on('click', function () { 366 const index = $(this).index(); 367 const id = $(this).data('id'); 368 369 sliderProduct.slideTo(index, 500); 370 $slides.removeClass('active'); 371 $(this).addClass('active'); 372 373 $links.removeClass('active'); 374 $links.filter('[data-id="' + id + '"]').addClass('active'); 375 376 actionFilter() 377 378 }); 379 380 // ð¹ Click link â di chuyá»n Äến slide tương ứng 381 $links.on('click', function (e) { 382 e.preventDefault(); 383 const id = $(this).data('id'); 384 const $targetSlide = $slides.filter('[data-id="' + id + '"]'); 385 const index = $targetSlide.index(); 386 387 if (index >= 0) { 388 sliderProduct.slideTo(index, 500); 389 } 390 391 $slides.removeClass('active'); 392 $targetSlide.addClass('active'); 393 394 $links.removeClass('active'); 395 $(this).addClass('active'); 396 397 398 actionFilter() 399 }); 400 401 402 403 });
404 405} 406 407function actionFilter(){ 408 409 var id = jQuery('.product_list ul a.active').data('id'); 410 var name = jQuery('.load_info_product').data('name'); 411 412 console.log(id) 413 414 jQuery.ajax({ 415 url: `${nk.ajax_url}?action=ajaxLoadProduct`, 416 method: "POST", 417 data:{ 418 id : id, 419 name : name, 420 421 }, 422 423 }).done(function(respond){ 424 jQuery('.load_info_product').empty().append(respond.html) 425 initFilterTableByStandards(); 426 tabsProduct() 427 428 }).fail(function(error){ 429 430 }).always(function(){ 431 432 }) 433} 434 435 436jQuery(document).ready(function($){ 437 438 $('body').on('click','.add_to_cart',function(e){ 439 e.preventDefault(); 440 441 let product_id = $(this).data('id'); 442 let qty = $(this).data('qty'); // lấy trực tiếp từ data-qty="1" 443 444 $.ajax({ 445 url: nk.ajax_url, 446 type: 'POST', 447 dataType: 'json', 448 data:{ 449 action:'add_to_quote_cart', 450 product_id: product_id, 451 qty: qty 452 }, 453 success:function(res){ 454 jQuery('.item_cart').removeClass('hide_number'); 455 if(res.success){ 456 console.log(res.data.total_items); 457 $('.item_cart span').text(res.data.total_items); 458 459 Swal.fire({ 460 title: 'Added to cart successfully', 461 icon: "success" 462 }); 463 }else{ 464 console.log('Add to cart failed'); 465 } 466 467 } 468 }); 469 470 }); 471 472 473 function updateCart(product_id, type, row){ 474 475 $.ajax({
476 url: nk.ajax_url, 477 type: 'POST', 478 dataType: 'json', 479 data: { 480 action: 'update_quote_cart', 481 product_id: product_id, 482 type: type 483 }, 484 success: function(res){ 485 486 if(res.success){ 487 488 // update badge 489 $('.item_cart span').text(res.data.total_items); 490 491 // update qty text 492 if(type !== 'remove'){ 493 row.find('.qty_text').text(res.data.qty); 494 } 495 496 // nếu = 0 hoặc remove â xóa item 497 if(res.data.qty <= 0 || type === 'remove'){ 498 row.slideUp(200, function(){ 499 $(this).remove(); 500 }); 501 } 502 503 } 504 505 } 506 }); 507 508 } 509 510 511 512});
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.