1/** 2 * Query Loop Scripts 3 * - post-slider 4 * - sorting 5 * - table sorting 6 * 7 * Moved from classic greyd default.js 8 */ 9 10var greyd = greyd || {}; 11 12( function() { 13 jQuery( function() { 14 if ( typeof $ === 'undefined' ) $ = jQuery; 15 16 greyd.query.init(); 17 18 console.log( "Query Scripts: loaded" ); 19 } ); 20} )( jQuery ); 21 22 23/** 24 * init greyd.query var 25 */ 26greyd.query = greyd.query || {}; 27 28/** 29 * init all query features 30 */ 31greyd.query.init = function() { 32 greyd.query.slider.init(); 33 greyd.query.sorting.init(); 34 greyd.query.table.init(); 35} 36 37 38/** 39 * slider features 40 * 41 * was global default.js variable 'post' 42 */ 43greyd.query.slider = new function() { 44 45 this.loaded = false; 46 47 this.init = function() { 48 this.addEvents(); 49 // console.log('Posts Pagination Script: loaded'); 50 } 51 52 this.addEvents = function() { 53 var wrapper = $(".greyd-posts-slider.js:not([data-init])"); 54 if (wrapper.length > 0) { 55 56 wrapper.each(function() { 57 if ($(this).hasClass('autoplay')) { 58 var time = $(this).data('interval')*1000; 59 var that = this; 60 $(this).timer = setInterval(function() { 61 if (!$(that).hasClass('pause') && !$(that).hasClass('forcePause')) { 62 greyd.query.slider.paginateNext($(that)); 63 } 64 }, time); 65 // $(this).on('mouseenter', function() { 66 // if ( !$(that).hasClass('pause') ) { 67 // $(that).addClass('pause'); 68 // $(this).on('mouseleave', function() { 69 // $(that).removeClass('pause'); 70 // }); 71 // } 72 // }); 73 } 74 75 $(this).off('next').on('next', function() { 76 greyd.query.slider.paginateNext(this); 77 }); 78 $(this).off('prev').on('prev', function() { 79 greyd.query.slider.paginatePrevious(this); 80 }); 81 $(this).off('first').on('first', function() { 82 greyd.query.slider.paginate(this, 1); 83 }); 84 $(this).off('last').on('last', function() { 85 var pages = $(this).children('.query-pages-wrapper').children('.query-page'); 86 greyd.query.slider.paginate(this, pages.length); 87 }); 88 $(this).off('stop').on('stop', function() { 89 $(this).addClass('forcePause pause'); 90 }); 91 $(this).off('start').on('start', function() { 92 $(this).removeClass('forcePause pause'); 93 }); 94 95 /** 96 * We insert the event listeners using PHP for more reliability. 97 * @since 2.7.0 98 */ 99 // // next/previous 100 // $(this).find('.pagination > a, a.pgn_arrows, .pgn_arrows a').off('click').on("click", function(e) { 101 // var wrapper = $(this).closest('.greyd-posts-slider'); 102 // wrapper.trigger( $(this).data('pagelink') ); 103 // wrapper.trigger('stop'); 104 // }); 105 // console.log( 106 // $(this).find('.pagination > a, a.pgn_arrows, .pgn_arrows a'), 107 // $(this).find('.pagination > .pgn_numbers > a') 108 // ); 109 110 // // numbers 111 // $(this).find('.pagination > .pgn_numbers > a').off('click').on("click", function(e) { 112 // var wrapper = $(this).closest('.greyd-posts-slider'); 113 // greyd.query.slider.paginate( wrapper, $(this).data('pagelink') ); 114 // wrapper.trigger('stop'); 115 // }); 116 117 // core pagination 118 $(this).closest('.wp-block-query').find('.wp-block-query-pagination').each(function() { 119 greyd.query.slider.addCorePagination(this); 120 121 }); 122 123 // touch support 124 $(this).off('touchstart').on('touchstart', function(e) { 125 greyd.query.slider.touchStart(this, e); 126 $(this).trigger('stop'); 127 }); 128 $(this).off('touchmove').on('touchmove', function(e) { 129 greyd.query.slider.touchMove(this, e); 130 $(this).trigger('stop'); 131 }); 132 133 // add onload event to images inside slider to re-calculate height 134 $(this).find('img').each(function() { 135 // console.log(this); 136 $(this).off('load').on('load', function(e) { 137 // console.log("img loaded"); 138 if ( greyd.query.slider.loaded ) greyd.query.slider.calc(); 139 }); 140 }); 141 142 $(this).attr('data-init', 'true'); 143 }); 144 145 // size wrapper 146 window.addEventListener("resize", function() { 147 greyd.query.slider.calc() 148 }); 149 setTimeout(function(){ 150 greyd.query.slider.calc() 151 }, 100); 152 153 $(document).keydown(function(e){ 154 // arrow left 155 if (e.keyCode == 37) { 156 var wrapper = $(".greyd-posts-slider.js:hover"); 157 if ( wrapper.length > 0 ) { 158 wrapper.trigger('prev'); 159 wrapper.trigger('stop'); 160 } 161 return false;
162 } 163 // arrow right 164 if (e.keyCode == 39) { 165 var wrapper = $(".greyd-posts-slider.js:hover"); 166 if ( wrapper.length > 0 ) { 167 wrapper.trigger('next'); 168 wrapper.trigger('stop'); 169 } 170 return false; 171 } 172 }); 173 } 174 } 175 176 this.calc = function() { 177 $('.greyd-posts-slider.js > .query-pages-wrapper').each(function(e) { 178 var pages = $(this).children('.query-page'); 179 var wrapper = $(this).closest('.greyd-posts-slider'); 180 var current = wrapper.data('currentpage'); 181 182 // console.log(offset); 183 // $(this).finish().animate({ scrollLeft: offset }, 0); 184 185 // get slider height 186 var height = $(this)[0].offsetHeight; 187 var newHeight = null; 188 189 /** 190 * Adjust the slider height. 191 * 192 * The naming of the options are misleading: 193 * (1) 'auto' => 'as high as highest slide' 194 * This is called auto, because the height of the slider 195 * is automatically this way due to 'display: flex'. We 196 * do not need to do anything in JS. 197 * (2) 'max' => 'adjust automatically' 198 * We need to adjust the slider's height to the height 199 * of the current slide each step. 200 * (3) 'custom' => 'manual height' 201 * Set the height to a manual input. 202 */ 203 if ( wrapper.data('height') == 'auto' ) { 204 // (1) 205 } 206 else if ( wrapper.data('height') === 'max') { 207 // (2) 208 newHeight = pages.length > 1 ? pages[current-1].offsetHeight+"px" : null; 209 } 210 else { 211 // (3) 212 newHeight = wrapper.data('height'); 213 if ( screen.width <= 767 && typeof wrapper.data('height_mobile') != 'undefined' && wrapper.data('height_mobile') != 'max' ) { 214 newHeight = wrapper.data('height_mobile'); 215 } 216 } 217 218 // set height for new slider 219 if ( newHeight && newHeight != height ) { 220 $(this).css('height', newHeight); 221 } 222 }); 223 224 // set loaded state to only re-calculate height after initial calc is done 225 greyd.query.slider.loaded = true; 226 } 227 228 /** 229 * When a pagination link is clicked, this function is called to paginate. 230 * @since 2.7.0 231 * 232 * @param {object} e The event object. 233 * @param {object} el The element that was clicked. 234 * @param {number} pagelink The page number to paginate to. 235 */ 236 this.onPaginateClick = function(e, el, pagelink) { 237 // console.log("paginate click", e, el, pagelink); 238 var wrapper = $(el).closest('.greyd-posts-slider'); 239 greyd.query.slider.paginate( wrapper, pagelink ); 240 wrapper.trigger('stop'); 241 } 242 this.paginateNext = function(wrapper) { 243 // console.log("next page"); 244 var newpage = parseInt($(wrapper).data('currentpage')) + 1; 245 this.paginate(wrapper, newpage); 246 } 247 this.paginatePrevious = function(wrapper) { 248 // console.log("previous page"); 249 var newpage = parseInt($(wrapper).data('currentpage')) - 1; 250 this.paginate(wrapper, newpage); 251 } 252 this.paginate = function(wrapper, newpage) { 253 254 // function to check is a string is numeric 255 const isNumeric = (str) => { 256 if (typeof str != "string") return false; 257 return !isNaN(str) && !isNaN(parseFloat(str)); 258 } 259 260 // get the new page number 261 if ( isNumeric(newpage) ) { 262 newpage = parseInt(newpage); 263 } 264 // if not numeric, like 'next' or 'prev', calculate the new page number 265 else { 266 if ( newpage == 'next' ) { 267 newpage = parseInt($(wrapper).data('currentpage')) + 1; 268 } else if ( newpage == 'prev' ) { 269 newpage = parseInt($(wrapper).data('currentpage')) - 1; 270 } else if ( newpage == 'first' ) { 271 newpage = 1; 272 } else if ( newpage == 'last' ) { 273 newpage = $(wrapper).children('.query-pages-wrapper').children('.query-page').length; 274 } 275 } 276 277 var current = $(wrapper).data('currentpage'); 278 var pages = $(wrapper).children('.query-pages-wrapper').children('.query-page'); 279 280 // return if no need to go to the next page 281 if (current == newpage) return; 282 if ( $(wrapper).hasClass('loop') ) { 283 if (newpage < 1) newpage = pages.length; 284 if (newpage > pages.length) newpage = 1; 285 } 286 else { 287 if (newpage < 1) return; 288 if (newpage > pages.length) return; 289 } 290 291 // get html elements 292 const resultsWrapper = $(wrapper).children('.query-pages-wrapper'); 293 const activeStep = pages[newpage-1]; 294 const prev = $(wrapper).find('.pgn_previous'); 295 const next = $(wrapper).find('.pgn_next'); 296 297 // get animation settings 298 const config = { 299 animation: $(wrapper).data('animation'), 300 height: $(wrapper).data('height'), 301 heightMobile: $(wrapper).data('height_mobile'), 302 offsetLeft: activeStep.offsetLeft, 303 scrollToTop: $(wrapper).hasClass('slider_scroll_top'), 304 /** 305 * Speed of the animation. 306 * 307 * @since 2.3.0 Added the global variable 'greydSliderSpeed' to enable 308 * users to set the speed of the slider in the global scope. 309 */ 310 speed: $(wrapper).data('duration') ?? ( typeof greydSliderSpeed !== "undefined" ? greydSliderSpeed : 200 ) 311 }; 312 313 if ( config.animation == 'none' ) { 314 config.speed = 0; 315 } 316 317 // update html attributes and classes 318 $(wrapper).data('currentpage', newpage); 319 pages.removeClass('is-current is-prev is-next'); 320 $(pages[newpage-2]).addClass('is-prev'); 321 $(activeStep).addClass('is-current'); 322 $(pages[newpage]).addClass('is-next'); 323 324 /** 325 * Adjust the slider height. 326 * 327 * The naming of the options are misleading: 328 * (1) 'auto' => 'as high as highest slide' 329 * This is called auto, because the height of the slider 330 * is automatically this way due to 'display: flex'. We 331 * do not need to do anything in JS. 332 * (2) 'max' => 'adjust automatically' 333 * We need to adjust the slider's height to the height 334 * of the current slide each step. 335 * (3) 'custom' => 'manual height' 336 * Set the height to a manual input. 337 */ 338 let newHeight; 339 if ( config.height == 'auto' ) { 340 // (1) 341 } 342 else if ( config.height === 'max') { 343 // (2) 344 newHeight = activeStep.offsetHeight; 345 } 346 else { 347 // (3) 348 newHeight = config.height; 349 if ( 350 screen.width <= 767 351 && typeof config.heightMobile != 'undefined' 352 && config.heightMobile != 'max' 353 ) { 354 newHeight = config.heightMobile; 355 } 356 } 357 358 // animate slider 359 if ( config.animation == 'fade' ) { 360 361 // fade out 362 $(resultsWrapper).finish().animate({ opacity: 0 }, config.speed); 363 setTimeout( () => { 364 365 /** 366 * @since 2.7.0 set the height directly and only animate the 367 * scroll x position. 368 * This is necessary to prevent the slider from jumping around 369 * which leads to errors scrolling to top, especially on mobile 370 * and safari browsers. 371 */ 372 if ( config.scrollToTop && newHeight ) { 373 resultsWrapper.css('height', newHeight); 374 } 375 376 // scroll to new position 377 $(resultsWrapper).finish().animate({ scrollLeft: config.offsetLeft }, 0); 378 379 // fade in 380 $(resultsWrapper).finish().animate({ 381 opacity: 1, 382 ...( !config.scrollToTop ) && newHeight ? { height: newHeight } : {} 383 }, config.speed); 384 }, config.speed ); 385 } 386 else if ( config.animation == 'cover' ) { 387 /** 388 * @since 2.7.0 set the height directly and only animate the 389 * scroll x position. 390 * This is necessary to prevent the slider from jumping around 391 * which leads to errors scrolling to top, especially on mobile 392 * and safari browsers. 393 */ 394 if ( config.scrollToTop && newHeight ) { 395 resultsWrapper.css('height', newHeight); 396 } else if ( newHeight ) { 397 $(resultsWrapper).finish().animate({ height: newHeight }, config.speed, 'swing'); 398 } 399 // ...the rest of cover-flow animation is entirely handled by CSS 400 } 401 else { 402 /** 403 * @since 2.7.0 set the height directly and only animate the 404 * scroll x position. 405 * This is necessary to prevent the slider from jumping around 406 * which leads to errors scrolling to top, especially on mobile 407 * and safari browsers. 408 */ 409 if ( config.scrollToTop && newHeight ) { 410 resultsWrapper.css('height', newHeight); 411 } 412 $(resultsWrapper).finish().animate({ 413 scrollLeft: config.offsetLeft, 414 ...( !config.scrollToTop ) && newHeight ? { height: newHeight } : {} 415 }, config.speed, 'swing'); 416 } 417 418 // scroll to top 419 if ( config.scrollToTop ) { 420 const offsetTop = $(wrapper).offset().top - 100; 421 if ( $(document).scrollTop() > offsetTop ) { 422 423 // backward compatibility with classic theme 424 if ( typeof nav !== 'undefined' ) { 425 console.log( "scroll to top with nav", nav ); 426 nav.scrollTo( offsetTop ); 427 } 428 else { 429 window.scrollTo( { top: offsetTop, behavior: 'auto' } ); 430 } 431 } 432 } 433 else { 434 // trigger 'scroll' event manually 435 // eg. to perform animations for now visible elements 436 setTimeout( () => { 437 document.dispatchEvent( new Event('scroll') ); 438 }, config.speed ); 439 } 440 441 // update the pagination 442 var pg_wrapper = $(wrapper).find('.pagination'); 443 if ( pg_wrapper.length ) { 444 var pg_pages = $(pg_wrapper).find('.pgn_numbers').children(); 445 var iconnormal = $(pg_wrapper).data('iconnormal') ?? $(pg_wrapper).find('.pgn_numbers').data('iconnormal'); 446 var iconactive = $(pg_wrapper).data('iconactive') ?? $(pg_wrapper).find('.pgn_numbers').data('iconactive'); 447 var imgnormal = $(pg_wrapper).data('imgnormal') ?? $(pg_wrapper).find('.pgn_numbers').data('imgnormal'); 448 var imgactive = $(pg_wrapper).data('imgactive') ?? $(pg_wrapper).find('.pgn_numbers').data('imgactive'); 449 450 for (var i=0; i<pg_pages.length; i++) { 451 // console.log( "pagination", $(pg_pages[i]) ); 452 var p = $(pg_pages[i]); 453 if (!$(p).hasClass('pgn_number')) p = $(p).find('.pgn_number'); 454 if ($(pg_pages[i]).data('pagelink') == current) { 455 $(p).removeClass('pgn_current'); 456 if (typeof iconactive !== 'undefined') $(p).removeClass(iconactive); 457 if (typeof iconnormal !== 'undefined') $(p).addClass(iconnormal); 458 if (typeof imgnormal !== 'undefined') $(p).children().attr('src', imgnormal); 459 } 460 if ($(pg_pages[i]).data('pagelink') == newpage) { 461 $(p).addClass('pgn_current'); 462 if (typeof iconnormal !== 'undefined') $(p).removeClass(iconnormal); 463 if (typeof iconactive !== 'undefined') $(p).addClass(iconactive); 464 if (typeof imgactive !== 'undefined') $(p).children().attr('src', imgactive); 465 } 466 } 467 } 468 469 // update the arrows 470 $(prev).removeClass('pgn_current'); 471 if (newpage == 1) $(prev).addClass('pgn_current'); 472 $(next).removeClass('pgn_current'); 473 if (newpage == pages.length) $(next).addClass('pgn_current'); 474 475 // trigger custom JS event 476 $(wrapper).trigger("greyd_slider_paginate", [newpage] ); 477 } 478 479 this.xDown = null; 480 this.touchStart = function(el, evt) { 481 greyd.query.slider.xDown = evt.originalEvent.touches[0].clientX; 482 } 483 this.touchMove = function(el, evt) { 484 if (!greyd.query.slider.xDown) { 485 return; 486 } 487 var xUp = evt.originalEvent.touches[0].clientX; 488 var xDiff = greyd.query.slider.xDown - xUp; 489 if (xDiff > 50) { 490 // console.log("scroll right"); 491 $(el).trigger('next'); 492 $(el).trigger('stop'); 493 greyd.query.slider.xDown = null; 494 } 495 else if (xDiff < -50) { 496 // console.log("scroll left"); 497 $(el).trigger('prev'); 498 $(el).trigger('stop'); 499 greyd.query.slider.xDown = null; 500 } 501 } 502 503 this.triggerNext = function(el) { 504 // console.log(el); 505 $(el).closest('.wp-block-query').children('.greyd-posts-slider.js').trigger('next'); 506 } 507 this.triggerPrevious = function(el) { 508 // console.log(el); 509 $(el).closest('.wp-block-query').children('.greyd-posts-slider.js').trigger('prev'); 510 } 511 this.triggerIndex = function(el, index) { 512 // console.log(el); 513 $(el).closest('.wp-block-query').children('.greyd-posts-slider.js').each(function() { 514 greyd.query.slider.paginate(this, index); 515 }); 516 } 517 518 this.addCorePagination = function(el) { 519 520 let allPages = $(el).closest('.wp-block-query').children('.greyd-posts-slider.js').find('.query-page'); 521 522 if ( ! allPages || allPages.length < 2 ) return; 523 524 525 // trigger function - also handles 'current' attributes on links 526 const trigger = ( mode, element, index = false ) => { 527 var wrapper = $(el).closest('.wp-block-query').children('.greyd-posts-slider.js'); 528 var current = $(wrapper).data('currentpage'); 529 var pages = $(wrapper).find('.query-page'); 530 var isLoop = $(wrapper).hasClass('loop'); 531 if (mode == 'previous') { 532 current--; 533 greyd.query.slider.triggerPrevious(element); 534 if (current < 1) { 535 if (isLoop) current = pages.length; 536 else return; 537 } 538 } 539 if (mode == 'next') { 540 current++; 541 greyd.query.slider.triggerNext(element); 542 if (current > pages.length) { 543 if (isLoop) current = 1; 544 else return; 545 } 546 } 547 if (mode == 'index') { 548 current = index; 549 greyd.query.slider.triggerIndex(element, index); 550 } 551 // set 'current' attributes 552 $(el).find('.wp-block-query-pagination-numbers .page-numbers:not
552(.dots)').each( (j, number) => { 553 $(number).removeClass('current'); 554 $(number).removeAttr('aria-current'); 555 if ($(number).data('page') == current) { 556 $(number).addClass('current'); 557 $(number).attr('aria-current', 'page'); 558 } 559 }) 560 }; 561 562 // previous 563 var previous = $(el).find('.wp-block-query-pagination-previous'); 564 previous.removeAttr("href"); 565 previous.off('click').on('click', function(e) { trigger('previous', this) } ); 566 567 // next 568 var next = $(el).find('.wp-block-query-pagination-next'); 569 next.removeAttr("href"); 570 next.off('click').on('click', function(e) { trigger('next', this) } ); 571 572 // numbers 573 var numbers = $(el).find('.wp-block-query-pagination-numbers .page-numbers:not(.dots)'); 574 numbers.each( (i, num) => { 575 576 // get all elements attributes 577 var attrs = {}; 578 $.each($(num)[0].attributes, function(idx, attr) { 579 attrs[attr.nodeName] = attr.nodeValue; 580 }); 581 // get index 582 let index = i+1; 583 if ( attrs['href'] ) { 584 // var params = Object.fromEntries((new URLSearchParams(attrs['href'])).entries()) 585 // Object.keys(params).forEach( (key) => { 586 // if ( key.indexOf('query-') == 0 && key.indexOf('-page') > 0 ) 587 // index = parseInt(params[key]); 588 // }); 589 delete attrs['href']; 590 } 591 // make onclick event 592 attrs['data-page'] = index; 593 // attrs['click'] = function(e) { trigger('index', this, index) }; 594 attrs['onclick'] = "greyd.query.slider.triggerIndex(this, "+index+")"; 595 596 // make new link with attributes 597 $(num).replaceWith(function() { 598 const text = $(this).contents(); 599 return $("<a />", attrs).append( text ); 600 }); 601 }); 602 603 } 604 605} 606 607/** 608 * sort posts in frontend via dropdown 609 * 610 * was global default.js variable 'sorting' 611 */ 612greyd.query.sorting = new function() { 613 614 this.init = function() { 615 // return if not needed 616 if ($(".greyd-posts-slider").length === 0) return false; 617 618 // normal pages 619 if (!($(".greyd-posts-slider.js").length === 0)) { 620 this.addEvents(); 621 } 622 // search page 623 else { 624 if ($('.greyd-posts-slider').attr("live-search") == "true") { 625 return false 626 } else { 627 this.startQuery(); 628 } 629 } 630 } 631 632 this.addEvents = function() { 633 const sortingDropdown = $('.greyd-posts-slider').find('.sorting'); 634 sortingDropdown.each(function() { 635 var wrapper = $(this); 636 var select = wrapper.find("select"); 637 var slider = wrapper.parent(); 638 var results = slider.find($(".query-post")); 639 640 // sort and redistribute search results 641 select.off("change").on("change", function() { 642 console.log(slider); 643 console.log(results); 644 var sorted_elements = greyd.query.sorting.sortElements($(this).val(), results); 645 // console.log(sorted_elements); 646 greyd.query.sorting.distributeElements(sorted_elements, slider); 647 }); 648 }); 649 650 $('[id^="filter_"]').each(function() { 651 var results = $(this).siblings('[id^="slider_"]').find($(".query-post")); 652 if (results) { 653 var select = $(this).find("select"); 654 var filter = select.val(); 655 $(results).each(function() { 656 greyd.query.sorting.filterElements(this, filter); 657 }); 658 select.off("change").on("change", function() { 659 var filter = $(this).val(); 660 $(results).each(function() { 661 greyd.query.sorting.filterElements(this, filter); 662 }); 663 }); 664 } 665 }); 666 } 667 668 this.filterElements = function(el, filter) { 669 var vals = JSON.parse(decodeURIComponent($(el).data('filter'))); 670 filter = parseInt(filter); 671 if (filter == null || filter == -1 || vals.indexOf(filter) != -1) 672 $(el).css('display', 'block'); 673 else 674 $(el).css('display', 'none'); 675 } 676 677 this.sortElements = function(mode, search_results) { 678 679 search_results.sort(function (a, b) { 680 681 if (~mode.indexOf("title")) { 682 // propably do that via php... 683 // var compA = a.dataset.title.toLowerCase().replace(/[^a-zA-Z0-9 ]/g, ""); 684 // var compB = b.dataset.title.toLowerCase().replace(/[^a-zA-Z0-9 ]/g, ""); 685 var compA = a.dataset.title; 686 var compB = b.dataset.title; 687 } 688 else if (~mode.indexOf("date")) { 689 var compA = a.dataset.date; 690 var compB = b.dataset.date; 691 } 692 else if (~mode.indexOf("views")) { 693 // propably do that via php... 694 // var compA = (a.dataset.postviews != 0) ? parseInt(a.dataset.postviews) : 0; 695 // var compB = (b.dataset.postviews != 0) ? parseInt(b.dataset.postviews) : 0; 696 var compA = parseInt(a.dataset.postviews); 697 var compB = parseInt(b.dataset.postviews); 698 } 699 //compare 700 if (~mode.indexOf("ASC")) { 701 return ((compA < compB) ? -1 : ((compA > compB) ? 1 : 0)); 702 } 703 else if (~mode.indexOf("DESC")) { 704 return ((compA > compB) ? -1 : ((compA < compB) ? 1 : 0)); 705 } 706 }); 707 return search_results; 708 } 709 this.distributeElements = function(sorted_elements, parent) { 710 var posts_per_page = $(".query-pages-wrapper").data("ppp"); 711 var pages = $(".query-page").length; 712 var i = 0; 713 714 for (var x = 1; x <= pages; x++) { 715 var limit_per_page = 1; 716 for (; i < sorted_elements.length;) { 717 718 parent.find($('.query-page[data-page="' + x + '"]')).append(sorted_elements[i]); 719 i++; 720 if (limit_per_page == posts_per_page) { 721 break; 722 } 723 limit_per_page++; 724 } 725 } 726 } 727 this.startQuery = function() { 728 const sortingDropdown = $('.greyd-posts-slider').find('.sorting'); 729 sortingDropdown.find("select").off("change").on('change', function () { 730 var url = $(this).val(); // get selected value 731 if (url) { // require a URL 732 window.location = url; // redirect 733 } 734 return false;
735 }); 736 } 737 738} 739 740/* 741 * jq.TableSort -- jQuery Table sorter Plug-in 742 * Copyright (c) 2017 Dmitry Zavodnikov 743 * Licensed under the MIT License 744 * 745 * was global default.js variable 'tablesort' 746 */ 747greyd.query.table = new function() { 748 749 this.init = function() { 750 751 // do not init if classic theme is detected 752 if ( typeof tablesort !== 'undefined' ) return; 753 754 // return if not needed 755 if ( $(".posts_table").length === 0 ) return false; 756 757 this.config = { 758 styles: { 759 'sort': 'sortable', 760 'asc': 'ascending', 761 'desc': 'descending', 762 'unsort': 'unsorted' 763 }, 764 defaultColumn: 0, 765 defaultOrder: 'asc', 766 selector: function(tbody, column) { 767 var groups = []; 768 $.each($(tbody).find('tr'), function(index, tr) { 769 var td = $(tr).find('td')[column]; 770 groups.push({ 771 'elem': [tr], 772 'text': $(td).text() 773 }); 774 }); 775 return groups; 776 }, 777 comparator: function(a, b) { 778 function convertToNum(x) { return parseFloat( x.replace(',','.') ); } 779 var regex = /^[0-9\s.,]+$/; 780 a = a.text, b = b.text; 781 if ( a.match(regex) && b.match(regex) ) return convertToNum(b) - convertToNum(a); 782 return a.localeCompare(b); 783 } 784 }; 785 786 $(".posts_table").each( function(i, wrapper) { 787 // Add click listener to the header. 788 $.each(greyd.query.table.getSortableTableHeaders(wrapper), function(j, th) { 789 $(th).off("click").on("click", function(event) { 790 var clickColumn = $.inArray(event.currentTarget, greyd.query.table.getAllTableHeaders( $(this).closest("table") )); 791 792 greyd.query.table.changeOrder(wrapper, clickColumn); 793 }); 794 // $(th).append("<span class='icon'><span></span><span></span></span>"); // already added via php 795 }); 796 // Table sort on load 797 //greyd.query.table.changeOrder(table, greyd.query.table.config.defaultColumn); 798 }); 799 } 800 801 this.getAllTableHeaders = function(wrapper) { 802 return $(wrapper).find('thead > tr > th'); 803 } 804 805 this.getNthTableHeaders = function(wrapper, n) { 806 return $(wrapper).find('thead > tr > th:nth-child('+(n+1)+')'); 807 } 808 809 this.getSortableTableHeaders = function(wrapper) { 810 return greyd.query.table.getAllTableHeaders(wrapper).filter(function(index){ 811 return $(this).hasClass(greyd.query.table.config.styles['sort']); 812 }); 813 } 814 815 this.changeOrder = function(wrapper, column) { 816 var th = greyd.query.table.getNthTableHeaders(wrapper, column); 817 818 // Order 819 var sortOrder = greyd.query.table.config.defaultOrder; 820 if (th.hasClass(greyd.query.table.config.styles['asc'])) { 821 sortOrder = 'desc'; 822 } 823 if (th.hasClass(greyd.query.table.config.styles['desc'])) { 824 sortOrder = 'asc'; 825 } 826 827 // Reset 828 var headers = greyd.query.table.getSortableTableHeaders(wrapper); 829 headers.removeClass( greyd.query.table.config.styles['asc']+" "+greyd.query.table.config.styles['desc'] ); 830 headers.addClass( greyd.query.table.config.styles['unsort'] ); 831 832 // Set classes 833 th.removeClass(greyd.query.table.config.styles['unsort']); 834 th.addClass(greyd.query.table.config.styles[sortOrder]); 835 836 // Group 837 var tbody = $(wrapper).find('tbody'); 838 var groups = greyd.query.table.config.selector(tbody, column); 839 840 // Sorting 841 groups.sort(function(a, b){ 842 var res = greyd.query.table.config.comparator(a, b); 843 return sortOrder == 'asc' ? res : -1 * res; 844 }); 845 846 // Change order 847 var rows = parseInt( $(wrapper).data('rows') ), i = 0, k = 0; 848 $.each(groups, function(i, trList) { 849 if ( i === rows * ( k+1 ) ) k++; 850 $.each(trList.elem, function(j, tr) { 851 tbody[k].append(tr); 852 }); 853 i++; 854 }); 855 } 856 857};
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.