1 2//UE Filters Version 1.26 3 4function UEDynamicFilters(){ 5 6 var g_objFilters, g_filtersData, g_urlBase; 7 var g_urlAjax, g_lastGridAjaxCall, g_cache = {}, g_objBody; 8 var g_remote = null, g_lastSyncGrids, g_initFiltersCounter = 0; 9 10 var t = this; 11 12 var g_showDebug = false; 13 var g_debugInitMode = false; 14 15 var g_debugBeforeRefreshMode = false; //debug filters state before refresh 16 17 var g_isGutenberg = false; 18 19 var g_types = { 20 PAGINATION:"pagination", 21 LOADMORE:"loadmore", 22 TERMS_LIST:"terms_list", 23 SEARCH: "search", 24 SELECT: "select", 25 SUMMARY: "summary", 26 GENERAL: "general", 27 GENERAL_MOBILE_DRAWER: "mobilefilters" 28 }; 29 30 var g_vars = { 31 CLASS_DIV_DEBUG:"uc-div-ajax-debug", 32 CLASS_GRID:"uc-filterable-grid", 33 CLASS_GRID_NOREFRESH:"uc-grid-norefresh", //grid that will not refresh 34 DEBUG_AJAX_OPTIONS: false, 35 CLASS_CLICKED:"uc-clicked", 36 CLASS_HIDDEN: "uc-filter-hidden", //don't refresh with this class 37 CLASS_INITING: "uc-filter-initing", 38 CLASS_INITING_HIDDEN: "uc-initing-filter-hidden", 39 CLASS_SKIP_REFRESH: "uc-filters-norefresh", //on some grid parent 40 CLASS_REFRESH_SOON: "uc-ajax-refresh-soon", 41 EVENT_SET_HTML_ITEMS: "uc_ajax_sethtml", 42 CLASS_FILTER_INITED:"ucfilters--filter-inited", 43 ATTRIBUTE_URLADD:"ajaxurladd", 44 GRID_DATA_SKIP_HTML: "skip_set_html", 45 46 //grid events 47 48 EVENT_BEFORE_REFRESH: "uc_before_ajax_refresh", //on grid 49 EVENT_AJAX_REFRESHED: "uc_ajax_refreshed", //on grid 50 EVENT_AJAX_REFRESHED_BODY: "uc_ajax_refreshed_body", //on body 51 EVENT_UPDATE_ACTIVE_FILTER_ITEMS: "update_active_filter_items", //on grid 52 EVENT_UNSELECT_FILTER: "uc_unselect_filter", //on grid 53 EVENT_SILENT_FILTER_CHANGE: "uc_silent_filter_change", //on grid 54 55 EVENT_DOM_UPDATED: "uc_dom_updated", //on body 56 57 //events on filters 58 59 EVENT_INIT_FILTER:"init_filter", 60 EVENT_INIT_FILTER_TYPE:"init_filter_type", 61 EVENT_GET_FILTER_DATA:"get_filter_data", 62 EVENT_FILTER_RELOADED: "uc_ajax_reloaded", 63 64 //grid actions 65 66 ACTION_CLEAR_FILTERS: "clear_filters", //on grid 67 ACTION_REFRESH_GRID: "uc_refresh", //listen on grid 68 ACTION_GET_FILTERS_URL: "uc_get_filters_url", //listen on grid 69 ACTION_FILTER_CHANGE: "uc_filter_change", //listen on grid 70 ACTION_FILTER_UNSELECT_BY_KEY: "unselect_by_key", //listen on grid 71 72 REFRESH_MODE_PAGINATION: "pagination", 73 REFRESH_MODE_LOADMORE: "loadmore", 74 trashold_handle:null, 75 class_widget_wrapper:"elementor-widget", 76 class_widget_container:"elementor-widget-container", 77 current_postid:null, 78 ucpage_url:null 79 }; 80 81 var g_options = { 82 is_cache_enabled:true, 83 urlkey_taxsap:"~" 84 }; 85 86 87 /** 88 * console log some string 89 */ 90 function trace(str){ 91 console.log(str); 92 } 93 94 function ________GENERAL_______________(){} 95 96 97 98 /** 99 * add url param 100 */ 101 function addUrlParam(url, param, value){ 102 103 if(url){ 104 if(url.indexOf("?") == -1) 105 url += "?"; 106 else 107 url += "&"; 108 } 109 110 if(typeof value == "undefined") 111 url += param; 112 else 113 url += param + "=" + value; 114 115 return(url); 116 } 117 118 119 /** 120 * get object property 121 */ 122 function getVal(obj, name, defaultValue){ 123 124 if(!defaultValue) 125 var defaultValue = ""; 126 127 var val = ""; 128 129 if(!obj || typeof obj != "object") 130 val = defaultValue; 131 else if(obj.hasOwnProperty(name) == false){ 132 val = defaultValue; 133 }else{ 134 val = obj[name]; 135 } 136 137 return(val); 138 } 139 140 /** 141 * turn string value ("true", "false") to string 142 */ 143 function strToBool(str){ 144 145 switch(typeof str){ 146 case "boolean": 147 return(str); 148 break; 149 case "undefined": 150 return(false); 151 break; 152 case "number": 153 if(str == 0) 154 return(false); 155 else 156 return(true); 157 break; 158 case "string": 159 str = str.toLowerCase(); 160 161 if(str == "true" || str == "1") 162 return(true); 163 else 164 return(false); 165 166 break; 167 } 168 169 return(false); 170 }; 171 172 /** 173 * get offsets distance 174 */ 175 function getOffsetsDistance(offset1, offset2){ 176 177 var dx = offset2.left-offset1.left; 178 var dy = offset2.top-offset1.top; 179 180 return Math.sqrt(dx*dx+dy*dy); 181 } 182 183 /** 184 * round number to one decimal 185 */ 186 function roundToOneDecimal(num) { 187 if (num % 1 !== 0) { 188 return num.toFixed(1); // Round to 1 decimal place 189 } else { 190 return num.toFixed(0); // Keep the whole number 191 } 192 } 193 194 195 /** 196 * get closest object by offset 197 */ 198 function getClosestByOffset(objParents, objElement, isVertical){ 199 200 if(objParents.length == 0){ 201 throw new Error("get closest by offset error - grids not found"); 202 } 203 204 if(g_showDebug == true){ 205 206 trace("get closest grids for"); 207 trace(objElement) 208 trace("parents"); 209 trace(objParents); 210 } 211 212 var objClosest = null; 213 var minDiff = 1000000; 214 215 var elementOffset = objElement.offset(); 216 217 jQuery.each(objParents, function(index, parent){ 218 219 var objParent = jQuery(parent); 220 221 var objGrid = jQuery(parent); //return this one 222 223 var distance = 0; 224 225 var isVisible = objParent.is(":visible"); 226 227 var constantHeight = null; 228 229 if(isVisible == false){ 230 objParent = objParent.parent(); 231 } 232 233 var parentOffset = objParent.offset(); 234 235 if(isVertical == true){ 236 237 var offsetY = elementOffset.top; 238 var parentY = parentOffset.top; 239 240 //get bottom of the parent 241 242 if(parentY < offsetY) 243 parentY += objParent.height(); 244 245 var distance = Math.abs(offsetY - parentY); 246 247 }else{ 248 249 var parentOffset = objParent.offset(); 250 251 var distance = getOffsetsDistance(parentOffset, elementOffset); 252 } 253 254 if(g_showDebug == true){ 255 256 trace(objParent); 257 trace("distance: " + distance); 258 259 trace("is vertical: " + isVertical); 260 } 261 262 if(distance < minDiff){ 263 minDiff = distance; 264 objClosest = objGrid; 265 } 266 267 }); 268 269 if(g_showDebug == true){ 270 271 trace("filter: "); 272 trace(objElement); 273 274 trace("Closest grid found:"); 275 trace(objClosest); 276 } 277 278 279 return(objClosest); 280 } 281 282 /** 283 * get all grids 284 */ 285 function getAllGrids(type){ 286 287 if(type == "loaded_only") 288 var objGrids = jQuery("."+ g_vars.CLASS_GRID).not(".ucfilters--grid-inited"); 289 else 290 var objGrids = jQuery("."+ g_vars.CLASS_GRID); 291 292 return(objGrids); 293 } 294 295 296 /** 297 * get grid from parents containers 298 */ 299 function getGridFromParentContainers(objSource){ 300 301 var objParents = objSource.parents(); 302 var objGrid = null; 303 304 if(g_showDebug == true){ 305 306 trace("get from parent containers"); 307 trace(objParents); 308 } 309 310 objParents.each(function(){ 311 312 var objParent = jQuery(this); 313 314 objGrid = objParent.find("."+ g_vars.CLASS_GRID); 315 316 //if grid found return it and exit loop 317 if(objGrid.length >= 1) 318 return(false); 319 320 });
321 322 323 return(objGrid); 324 } 325 326 327 /** 328 * get closest grid to some object 329 */ 330 function getClosestGrid(objSource){ 331 332 //in case there are nothing: 333 var objGrids = getAllGrids(); 334 335 if(objGrids.length == 0) 336 return(null); 337 338 if(g_showDebug == true){ 339 340 trace("get closest grids"); 341 trace(objSource); 342 trace(objGrids); 343 } 344 345 //get grid from parents 346 347 if(objGrids.length == 1) 348 return(objGrids); 349 350 //narrow by group 351 var group = objSource.data("connectgroup"); 352 353 if(group){ 354 var objGridsGroup = objGrids.filter("[data-filtergroup="+group+"]"); 355 356 if(objGridsGroup.length > 0){ 357 358 if(objGridsGroup.length == 1) 359 return(objGridsGroup); 360 361 objGrids = objGridsGroup; 362 } 363 364 }else{ 365 366 //get from same container - if group not set 367 368 var objGrid = getGridFromParentContainers(objSource); 369 370 if(objGrid && objGrid.length == 1) 371 return(objGrid); 372 } 373 374 375 //get closest by offset 376 377 if(objGrid && objGrid.length > 1) 378 objGrids = objGrid; 379 380 var objSingleGrid = getClosestByOffset(objGrids, objSource, true); 381 382 if(objSingleGrid && objSingleGrid.length == 1) 383 return(objSingleGrid); 384 385 //return first grid in the list 386 387 var objFirstGrid = jQuery(objGrids[0]); 388 389 return(objFirstGrid); 390 } 391 392 393 394 /** 395 * add filter object to grid 396 */ 397 function bindFilterToGrid(objGrid, objFilter){ 398 399 var arrFilters = objGrid.data("filters"); 400 var objTypes = objGrid.data("filter_types"); 401 402 if(!arrFilters) 403 arrFilters = []; 404 405 if(!objTypes) 406 objTypes = {}; 407 408 var type = getFilterType(objFilter); 409 410 //validate double types 411 412 if(objTypes.hasOwnProperty(type)){ 413 414 switch(type){ 415 case g_types.LOADMORE: 416 417 trace("Double filter not allowed"); 418 trace("existing Filters:"); 419 trace(arrFilters); 420 421 trace("Second Filter"); 422 trace(objFilter); 423 424 trace("Grid:"); 425 trace(objGrid); 426 427 showElementError(objFilter, "Double load more button for one grid not allowed") 428 return(false); 429 break; 430 } 431 432 } 433 434 objTypes[type] = true; 435 436 var filterID = objFilter.attr("id"); 437 438 //handle sticky 439 440 var objElementorStickySpacer = objFilter.closest(".elementor-sticky__spacer"); 441 if(objElementorStickySpacer.length) 442 return(true); 443 444 445 //----- validate existing ----- 446 447 var objExistingFilter = arrFilters.filter(function(objFilterInArray){ 448 return objFilterInArray.attr("id") == filterID; 449 }); 450 451 if(objExistingFilter && objExistingFilter.length) 452 throw new Error("Can't bind filter to grid, it's already exists: " + filterID); 453 454 arrFilters.push(objFilter); 455 456 //add init after filters 457 var isInitAfter = objFilter.data("initafter"); 458 459 if(!isInitAfter) 460 isInitAfter = isSpecialFilterInitAfter(objFilter, objGrid); 461 462 if(isInitAfter === true) 463 addFilterToInitAfter(objFilter, objGrid); 464 465 objGrid.data("filters", arrFilters); 466 467 objGrid.data("filter_types", objTypes); 468 469 } 470 471 /** 472 * 473 * get element widget id from parent wrapper 474 */ 475 function getElementWidgetID(objElement){ 476 477 if (!objElement || objElement.length === 0) 478 throw new Error("Element not found"); 479 480 var objWidget = objElement.closest("."+g_vars.class_widget_wrapper); 481 482 if (objWidget.length === 0) 483 throw new Error("Element parent not found with class: "+g_vars.class_widget_wrapper); 484 485 var widgetID = objWidget.data("id"); 486 487 if (!widgetID) 488 throw new Error("widget id not found"); 489 490 return widgetID; 491 } 492 493 494 /** 495 * get the grid widget object from elementor element id 496 */ 497 function getGridFromElementorElementID(elementID){ 498 499 var selector = "."+g_vars.class_widget_wrapper+"[data-id='"+elementID+"']"; 500 501 var objElement = g_objBody.find(selector); 502 503 if(objElement.length == 0) 504 return(null); 505 506 var objGrid = objElement.find("."+g_vars.CLASS_GRID); 507 508 if(objGrid.length != 1) 509 return(null); 510 511 return(objGrid); 512 } 513 514 /** 515 * get another group widgets 516 */ 517 function getGroupWidgets(arrSyncedGrids, objElement){ 518 519 var group = objElement.data("filtergroup"); 520 521 if(!group) 522 return(arrSyncedGrids); 523 524 var objGrids = jQuery("."+ g_vars.CLASS_GRID); 525 526 if(objGrids.length < 2) 527 return(arrSyncedGrids); 528 529 var elementID = objElement.attr("id"); 530 531 var objDataGrids = objGrids.filter("[data-filtergroup='"+group+"']:not(#" + elementID + ")"); 532 533 if(objDataGrids.length == 0) 534 return(arrSyncedGrids); 535 536 jQuery.each(objDataGrids, function(index, grid){ 537 538 var objGrid = jQuery(grid); 539 540 arrSyncedGrids.push(objGrid); 541 }); 542 543 544 545 return(arrSyncedGrids); 546 } 547 548 /** 549 * get synced widget IDs 550 */ 551 function getSyncedWidgetData(objElement){ 552 553 var arrSyncedGrids = []; 554 555 if(g_remote) 556 arrSyncedGrids = g_remote.getSyncedElements(objElement); 557 558 if(!arrSyncedGrids) 559 arrSyncedGrids = []; 560 561 arrSyncedGrids = getGroupWidgets(arrSyncedGrids, objElement); 562 563 if(!arrSyncedGrids || arrSyncedGrids.length == 0) 564 return(false); 565 566 var arrWidgetIDs = []; 567 568 var objGrids = null; 569 570 for(var index in arrSyncedGrids){ 571 572 var objGrid = arrSyncedGrids[index]; 573 574 if(objGrid.hasClass(g_vars.CLASS_GRID) == false){ 575 576 var message = "Please enable ajax on all synced widgets"; 577 var message2 = "Please enable ajax on this synced widget, it's missing class: "+g_vars.CLASS_GRID; 578 579 showElementError(objGrid, message2); 580 581 showAjaxError(message); 582 throw new Error(message); 583 return(false); 584 } 585 586 var objWidgetID = getElementWidgetID(objGrid); 587 588 //add to jquery collection 589 590 if(!objGrids) 591 objGrids = objGrid; 592 else 593 objGrids = objGrids.add(objGrid); 594 595 arrWidgetIDs.push(objWidgetID); 596 } 597 598 var strWidgetIDs = arrWidgetIDs.toString(); 599 600 var objOutput = {}; 601 objOutput["ids"] = strWidgetIDs; 602 objOutput["grids"] = objGrids; 603 604 return(objOutput); 605 } 606 607 608 /** 609 * get element layout data 610 */ 611 function getElementLayoutData(objElement, addSyncedGrids){ 612 613 //get widget id 614 var widgetID = getElementWidgetID(objElement); 615 var objWidget = objElement.parents("."+g_vars.class_widget_wrapper); 616 617 //get synced grids 618 var objSyncedData = null; 619 620 //add sync if allowed and available 621 622 if(addSyncedGrids){ 623 624 var objSyncedData = getSyncedWidgetData(objElement); 625 626 if(g_showDebug && objSyncedData){ 627 628 trace("sync data"); 629 trace(objSyncedData); 630 } 631 }else{ 632 633 if(g_showDebug) 634 trace("skip sync grid"); 635 636 } 637 638 //get layout id 639 640 if(g_isGutenberg == false){ 641 642 var objLayout = objWidget.parents(".elementor"); 643 644 if(objLayout.length == 0) 645 throw new Error("layout not found"); 646 647 var layoutID = objLayout.data("elementor-id"); 648 649 if(!layoutID) 650 layoutID = objLayout.data("id"); 651 652 }else{ //gutenberg 653 654 var layoutID = g_vars.current_postid; 655 } 656 657 658 var output = {}; 659 660 output["widgetid"] = widgetID; 661 output["layoutid"] = layoutID; 662 663 if(objSyncedData){ 664 output["synced_widgetids"] = objSyncedData["ids"]; 665 output["synced_grids"] = objSyncedData["grids"]; 666 } 667 668 return(output); 669 } 670 671 /** 672 * show element error above it 673 */ 674 function showElementError(objElement, error){ 675 676 var objParent = objElement.parent(); 677 678 var objError = objParent.find(".uc-filers-error-message"); 679 if(objError.length == 0){ 680 objParent.append("<div class='uc-filers-error-message' style='color:red;position:absolute;top:-24px;left:0px;background-color:rgba(230, 230, 230, 0.8);padding:3px;font-size:12px;'></div>"); 681 var objError = objParent.find(".uc-filers-error-message");
682 objParent.css("border","1px solid red !important"); 683 } 684 685 objError.append(error); 686 687 objError.css("top",-objError.height()-5); 688 689 } 690 691 /** 692 * get grid empty message 693 */ 694 function getGridEmptyMessage(objGrid){ 695 696 var gridID = objGrid.attr("id"); 697 698 if(!gridID) 699 return(null); 700 701 var objEmptyMessage = jQuery("#"+gridID+"_empty_message"); 702 703 if(objEmptyMessage.length == 0) 704 return(null); 705 706 return(objEmptyMessage); 707 } 708 709 /** 710 * get active filter items, if no items - return 0 711 */ 712 function getGridActiveFilterItems(objGrid){ 713 714 var arrActiveItems = objGrid.data("active_filters_items"); 715 716 if(!arrActiveItems) 717 return(null); 718 719 if(arrActiveItems.length == 0) 720 return(null); 721 722 return(arrActiveItems); 723 } 724 725 726 /** 727 * get filters that are selected 728 */ 729 function getSelectedFilters(objFilters, roleArg){ 730 731 if(!objFilters) 732 var objFilters = objGrid.data("filters"); 733 734 if(!objFilters) 735 return(false); 736 737 var arrSelectedFilters = []; 738 739 jQuery.each(objFilters, function(index, filter){ 740 741 var objFilter = jQuery(filter); 742 var isSelected = objFilter.hasClass("uc-has-selected"); 743 744 if(!roleArg && isSelected == true){ 745 arrSelectedFilters.push(objFilter); 746 return(true); 747 } 748 749 var role = objFilter.data("role"); 750 751 if(role == roleArg){ 752 var isSelected = objFilter.hasClass("uc-has-selected"); 753 if(isSelected) 754 arrSelectedFilters.push(objFilter); 755 } 756 757 }); 758 759 return(arrSelectedFilters); 760 } 761 762 763 function ________FILTERS_______________(){} 764 765 766 /** 767 * get the parent 768 */ 769 function getFiltersParent(objFilters){ 770 771 //init the events 772 var objParent = objFilters.parents(".elementor"); 773 774 if(objFilters.length > 1 && objParent.length > 1) 775 objParent = objFilters.parents("body"); 776 777 if(objParent.length > 1){ 778 objParent = jQuery(objParent[0]); 779 } 780 781 if(objParent.length == 0) 782 objParent = objFilters.parents("body"); 783 784 return(objParent); 785 } 786 787 /** 788 * get filter wrapper 789 */ 790 function getFilterWrapper(objFilter){ 791 792 var objParent = objFilter.parent(); 793 794 var objElementorParent = objParent.parents(".elementor-widget-container"); 795 if(objElementorParent.length == 1) 796 return(objElementorParent); 797 798 if(objParent.hasClass("uc-checkbox-filter-accordion-container")) 799 objParent = objParent.parent(); 800 801 return(objParent); 802 } 803 804 /** 805 * get filter type 806 */ 807 function getFilterType(objFilter, getGeneralType){ 808 809 if(objFilter.hasClass("uc-filter-pagination")) 810 return(g_types.PAGINATION); 811 812 if(objFilter.hasClass("uc-filter-load-more")) 813 return(g_types.LOADMORE); 814 815 var filterType = objFilter.data("filtertype") 816 817 if(filterType == g_types.GENERAL && getGeneralType === true){ 818 819 var generalType = objFilter.data("generaltype"); 820 return(generalType); 821 } 822 823 if(filterType) 824 return(filterType); 825 826 //if not found - throw error 827 828 trace("Filter type not found: "); 829 trace(objFilter); 830 831 throw new Error("wrong filter type"); 832 833 } 834 835 836 /** 837 * clear all filters 838 */ 839 function clearAllFilters(objGrid){ 840 841 clearChildFilters(objGrid, null, true, null, true); 842 } 843 844 /** 845 * get grid filters or null 846 */ 847 function getGridFilters(objGrid){ 848 849 var objFilters = objGrid.data("filters"); 850 851 if(!objFilters) 852 return(null); 853 854 if(objFilters.length == 0) 855 return(null); 856 857 return(objFilters); 858 } 859 860 861 /** 862 * clear non main grid filters 863 * hide children and just clear the main filters 864 */ 865 function clearChildFilters(objGrid, objCurrentFilter, isHideChildren, termID, isClearAll){ 866 867 var objFilters = getGridFilters(objGrid); 868 869 if(!objFilters) 870 return(false); 871 872 var currentFilterID = null; 873 874 if(objCurrentFilter) 875 var currentFilterID = objCurrentFilter.attr("id"); 876 877 jQuery.each(objFilters, function(index, filter){ 878 879 var objFilter = jQuery(filter); 880 var filterID = objFilter.attr("id"); 881 882 if(filterID == currentFilterID) 883 return(true); 884 885 var role = objFilter.data("role"); 886 887 //clear all others if that option selected 888 889 if(role != "child" && role != "main" && role != "term_child"){ 890 891 if(isClearAll == true){ 892 clearFilter(objFilter); 893 } 894 895 return(true); 896 } 897 898 var isHide = false; 899 var isShow = false; 900 901 switch(role){ 902 case "term_child": 903 if(isHideChildren == true) 904 isHide = true; 905 906 var linkedTermID = objFilter.data("childterm"); 907 908 if(linkedTermID == termID){ //show the filter 909 910 objFilter.removeClass(g_vars.CLASS_HIDDEN); 911 objFilter.removeClass(g_vars.CLASS_INITING); 912 objFilter.removeClass(g_vars.CLASS_INITING_HIDDEN); 913 }else{ 914 isHide = true; 915 } 916 917 break; 918 case "child": 919 920 if(isHideChildren == true) 921 isHide = true; 922 else{ 923 //hide the filters and refresh 924 925 objFilter.removeClass(g_vars.CLASS_HIDDEN); 926 927 objFilter.addClass(g_vars.CLASS_INITING); 928 objFilter.addClass(g_vars.CLASS_INITING_HIDDEN); 929 930 } 931 932 break; 933 default: 934 935 if(isClearAll == true){ 936 clearFilter(objFilter); 937 } 938 939 return(true); 940 break; 941 } 942 943 //hide the child filters and not refresh 944 945 if(isHide == true) 946 objFilter.addClass(g_vars.CLASS_HIDDEN); 947 948 clearFilter(objFilter); 949 950 }); 951 952 } 953 954 /** 955 * clear some filter 956 */ 957 function clearFilter(objFilter){ 958 959 var type = getFilterType(objFilter); 960 961 switch(type){ 962 case g_types.TERMS_LIST: 963 var objSelectedItems = objFilter.find(".ue_taxonomy_item.uc-selected"); 964 objSelectedItems.removeClass("uc-selected"); 965 966 var objAll = objFilter.find(".ue_taxonomy_item.uc-item-all"); 967 objAll.addClass("uc-selected"); 968 969 break; 970 case g_types.SELECT: 971 972 var objSelect = objFilter.find("select"); 973 objSelect.val(""); 974 975 //must leave one selected 976 var objSelected = objFilter.find("option:selected"); 977 978 if(objSelected.length == 0) 979 objFilter.find("option:first-child").prop("selected","selected"); 980 981 break; 982 default: 983 case g_types.SEARCH: 984 case g_types.GENERAL: 985 objFilter.trigger("clear_filter"); 986 break; 987 } 988 989 } 990 991 /** 992 * unselect filter item 993 */ 994 function unselectFilterItem(objGrid, key){ 995 996 var objFilters = getGridFilters(objGrid); 997 998 if(!objFilters) 999 return(false); 1000 1001 jQuery.each(objFilters, function(index, filter){ 1002 1003 var objFilter = jQuery(filter); 1004 1005 objFilter.trigger(g_vars.ACTION_FILTER_UNSELECT_BY_KEY, [key]); 1006 1007 }); 1008 1009 } 1010 1011 /** 1012 * return true if the filter skip's it's action - like under mobile drawer 1013 */ 1014 function isFilterSkipAction(objFilter){ 1015 1016 var objParentSkipRefresh = objFilter.parents("." + g_vars.CLASS_SKIP_REFRESH); 1017 1018 if(objParentSkipRefresh.length) 1019 return(true); 1020 1021 return(false); 1022 } 1023 1024 /** 1025 * return if the grid has some child filters 1026 */ 1027 function hasChildFilters(objGrid){ 1028 1029 var objFilters = getGridFilters(objGrid); 1030 1031 if(!objFilters) 1032 return(false); 1033 1034 for(var index in objFilters){ 1035 1036 var objFilter = objFilters[index]; 1037 var role = objFilter.data("role"); 1038 if(role == "child") 1039 return(true); 1040 } 1041 1042 return(false); 1043 } 1044 1045 /** 1046 * check and trigger skip action to the grid if needed 1047 * run before the refresh on some filter click 1048 * for the mobile drawer (off canvas) 1049 */
1050 function checkTriggerSkipAction(objFilter, objGrid){ 1051 1052 var isSkipAction = isFilterSkipAction(objFilter); 1053 if(isSkipAction == false) 1054 return(false); 1055 1056 if(g_showDebug == true) 1057 trace("skip refresh - silent change triggered"); 1058 1059 var filterRole = objFilter.data("role"); 1060 1061 objGrid.trigger(g_vars.EVENT_SILENT_FILTER_CHANGE); 1062 1063 initGrid_setActiveFiltersData(objGrid); 1064 1065 //refresh children only main / children available 1066 if(filterRole == "main" && hasChildFilters(objGrid)){ 1067 1068 if(g_showDebug == true) 1069 trace("refresh children only"); 1070 1071 objGrid.data(g_vars.GRID_DATA_SKIP_HTML, true); 1072 refreshAjaxGrid(objGrid); 1073 } 1074 1075 1076 return(true); 1077 } 1078 1079 function ________PAGINATION_FILTER______(){} 1080 1081 1082 /** 1083 * get pagination selected url or null if is current 1084 */ 1085 function getPaginationSelectedData(objPagination){ 1086 1087 var objCurrentLink = objPagination.find("a.current,span.current"); 1088 1089 if(objCurrentLink.length == 0) 1090 return(null); 1091 1092 var url = objCurrentLink.attr("href"); 1093 1094 var numPage = objCurrentLink.text(); 1095 1096 if(jQuery.isNumeric(numPage) == false) 1097 numPage = null; 1098 1099 numPage = Number(numPage); 1100 1101 if(numPage === 1) 1102 numPage = null; 1103 1104 var output = {}; 1105 output["url"] = url; 1106 output["page"] = numPage; 1107 1108 return(output); 1109 } 1110 1111 1112 /** 1113 * on ajax pagination click 1114 */ 1115 function onAjaxPaginationLinkClick(event){ 1116 1117 var objLink = jQuery(this); 1118 1119 //if no grid attached - act like a regular link 1120 1121 var objPagination = objLink.parents(".uc-filter-pagination"); 1122 1123 var objGrid = objPagination.data("grid"); 1124 1125 if(!objGrid || objGrid.length == 0 || objPagination.hasClass("uc-no-ajax")){ 1126 1127 return(true); 1128 } 1129 1130 //run the ajax, prevent default 1131 event.preventDefault(); 1132 1133 var objLinkCurrent = objPagination.find(".current"); 1134 1135 1136 //on next button click 1137 1138 if(objLink.hasClass("next")){ 1139 1140 var nextLink = objLinkCurrent.next(); 1141 1142 var objNextLink = jQuery(nextLink); 1143 1144 objNextLink.trigger("click"); 1145 1146 return(false); 1147 } 1148 1149 1150 //on prev button click 1151 1152 if(objLink.hasClass("prev")){ 1153 1154 var prevLink = objLinkCurrent.prev(); 1155 1156 var objPrevLink = jQuery(prevLink); 1157 1158 objPrevLink.trigger("click"); 1159 1160 return(false); 1161 } 1162 1163 objLinkCurrent.removeClass("current"); 1164 1165 objLink.addClass("current"); 1166 1167 var objGrid = objPagination.data("grid"); 1168 1169 objPagination.addClass(g_vars.CLASS_CLICKED); 1170 1171 if(g_showDebug == true){ 1172 1173 trace("click on pagination!!!, no grid refresh"); 1174 trace(objLink); 1175 1176 }else{ 1177 1178 refreshAjaxGrid(objGrid, g_vars.REFRESH_MODE_PAGINATION); 1179 1180 } 1181 1182 return(false); 1183 } 1184 1185 1186 function ________LOAD_MORE_______________(){} 1187 1188 1189 /** 1190 * get current load more page 1191 */ 1192 function getLoadMoreUrlData(objFilter){ 1193 1194 var objData = objFilter.find(".uc-filter-load-more__data"); 1195 1196 var nextOffset = objData.data("nextoffset"); 1197 if(!nextOffset) 1198 nextOffset = null; 1199 1200 var numItems = objFilter.data("numitems"); 1201 1202 if(!numItems) 1203 numItems = null; 1204 1205 //affect only single grids 1206 1207 var isSingleGridOnly = objFilter.data("affect_single_grid"); 1208 1209 1210 var data = {}; 1211 data.offset = nextOffset; 1212 data.numItems = numItems; 1213 data.singlegrid = isSingleGridOnly; 1214 1215 return(data); 1216 } 1217 1218 1219 /** 1220 * do the load more operation 1221 */ 1222 function onLoadMoreClick(){ 1223 1224 var objLink = jQuery(this); 1225 1226 var objLoadMore = objLink.parents(".uc-filter-load-more"); 1227 1228 var objData = objLoadMore.find(".uc-filter-load-more__data"); 1229 1230 var isMore = objData.data("more"); 1231 1232 if(isMore == false) 1233 return(false); 1234 1235 var objGrid = objLoadMore.data("grid"); 1236 1237 if(!objGrid || objGrid.length == 0) 1238 throw new Error("Grid not found!"); 1239 1240 //run the ajax, prevent default 1241 1242 objLoadMore.addClass(g_vars.CLASS_CLICKED); 1243 1244 refreshAjaxGrid(objGrid, g_vars.REFRESH_MODE_LOADMORE); 1245 1246 } 1247 1248 function ________SELECT_______________(){} 1249 1250 /** 1251 * init select filter, select the selected item (avoid cache) 1252 */ 1253 function initSelectFilter(objFilter){ 1254 1255 var objSelected = objFilter.find(".uc-selected"); 1256 1257 if(objSelected.length == 0) 1258 return(false); 1259 1260 var value = objSelected.attr("value"); 1261 1262 var objSelect = objFilter.find("select"); 1263 1264 objSelect.val(value); 1265 1266 } 1267 1268 1269 function ________TERMS_LIST_______________(){} 1270 1271 /** 1272 * unselect by key terms list and select 1273 */ 1274 function termsFilterUnselectByKey(event,key){ 1275 1276 var objFilter = jQuery(this); 1277 1278 var selectedTerm = getTermsListSelectedTerm(objFilter); 1279 1280 if(!selectedTerm) 1281 return(false); 1282 1283 var selectedKey = getVal(selectedTerm,"key"); 1284 1285 if(selectedKey != key) 1286 return(false); 1287 1288 //if key match - clear filter and set no refresh. 1289 1290 clearFilter(objFilter); 1291 1292 setNoRefreshFilter(objFilter); 1293 } 1294 1295 1296 /** 1297 * on terms list click 1298 */ 1299 function onTermsLinkClick(event){ 1300 1301 var className = "uc-selected"; 1302 1303 event.preventDefault(); 1304 1305 var objLink = jQuery(this); 1306 1307 if(objLink.hasClass("uc-grid-filter")){ 1308 1309 var objTermsFilter = objLink; 1310 1311 }else{ 1312 1313 var objTermsFilter = objLink.parents(".uc-grid-filter"); 1314 } 1315 1316 var filterType = getFilterType(objTermsFilter); 1317 1318 if(filterType == g_types.SELECT){ 1319 1320 var objLink = objTermsFilter.find("option:selected"); 1321 } 1322 1323 if(filterType == g_types.TERMS_LIST){ 1324 1325 var objActiveLinks = objLink.siblings("."+className).not(objLink); 1326 1327 objActiveLinks.removeClass(className); 1328 objLink.addClass(className); 1329 1330 } 1331 1332 var objGrid = objTermsFilter.data("grid"); 1333 1334 if(!objGrid || objGrid.length == 0) 1335 throw new Error("Grid not found"); 1336 1337 //if main filter - clear other filters 1338 1339 var filterRole = objTermsFilter.data("role"); 1340 1341 var termID = objLink.data("id"); 1342 1343 //set refresh - if all and there are hidden items - refresh 1344 var isRefresh = false; 1345 1346 if(!termID){ 1347 var objHiddenItems = objTermsFilter.find(".uc-item-hidden"); 1348 if(objHiddenItems.length) 1349 isRefresh = true; 1350 } 1351 1352 var isHideChildren = false; 1353 if(!termID) 1354 isHideChildren = true; 1355 1356 //set not refresh next iteration, because of the clicked 1357 if(isRefresh == false) 1358 setNoRefreshFilter(objTermsFilter); 1359 1360 if(filterRole == "main") 1361 clearChildFilters(objGrid, objTermsFilter, isHideChildren, termID); 1362 1363 //skip action 1364
1365 var isSkipAction = checkTriggerSkipAction(objTermsFilter, objGrid); 1366 1367 if(isSkipAction == true) 1368 return(false); 1369 1370 1371 if(g_showDebug == true){ 1372 trace("refresh grid - on term click"); 1373 } 1374 1375 //refresh grid 1376 refreshAjaxGrid(objGrid); 1377 1378 } 1379 1380 1381 /** 1382 * get terms list term id 1383 */ 1384 function getTermsListSelectedTerm(objFilter){ 1385 1386 if(!objFilter) 1387 return(null); 1388 1389 var filterType = getFilterType(objFilter); 1390 1391 var objSelected = objFilter.find(".uc-selected"); 1392 1393 if(filterType == g_types.SELECT){ 1394 1395 var objSelected = objFilter.find("option:selected"); 1396 1397 }else{ 1398 1399 var objSelected = objFilter.find(".uc-selected"); 1400 } 1401 1402 if(objSelected.length == 0){ 1403 1404 if(g_showDebug == true){ 1405 trace("no selected found, skipping..."); 1406 } 1407 1408 return(null); 1409 } 1410 1411 //check for hidden 1412 1413 if(filterType == g_types.TERMS_LIST && objSelected.hasClass("uc-item-hidden") == true){ 1414 1415 if(g_showDebug == true){ 1416 1417 trace("the selected object"); 1418 trace(objSelected); 1419 trace("the term is hidden, skipping..."); 1420 1421 } 1422 1423 return(null); 1424 } 1425 1426 if(objSelected.length > 1) 1427 objSelected = jQuery(objSelected[0]); 1428 1429 var objTerm = getFilterElementData(objSelected); 1430 1431 return(objTerm); 1432 } 1433 1434 /** 1435 * select items in terms list by terms 1436 */ 1437 function termListSelectItems(objFilter, arrTerms){ 1438 1439 //deselect 1440 var objSelected = objFilter.find(".uc-selected"); 1441 1442 objSelected.removeClass("uc-selected"); 1443 1444 //select by term 1445 1446 jQuery.each(arrTerms, function(index, term){ 1447 1448 var termID = getVal(term,"id"); 1449 var objItem = objFilter.find("a.ue_taxonomy_item[data-id='"+termID+"']"); 1450 1451 if(objItem.length == 0) 1452 return(true); 1453 1454 objItem.addClass("uc-selected"); 1455 }); 1456 1457 1458 } 1459 1460 function ________GENERAL_FILTER_______________(){} 1461 1462 /** 1463 * init general filter 1464 */ 1465 function initGeneralFilter(objFilter){ 1466 1467 objFilter.on(g_vars.ACTION_FILTER_CHANGE, onGeneralFilterChange); 1468 1469 } 1470 1471 1472 1473 /** 1474 * on general filter change 1475 */ 1476 function onGeneralFilterChange(event, params){ 1477 1478 event.stopPropagation(); 1479 1480 var isRefresh = getVal(params, "refresh"); 1481 1482 var objFilter = jQuery(this); 1483 1484 var filterType = objFilter.data("filtertype"); 1485 1486 if(filterType != "general"){ 1487 1488 trace(objFilter); 1489 1490 throw new Error("Not a general filter on action: " + g_vars.ACTION_FILTER_CHANGE); 1491 return(false); 1492 } 1493 1494 if(isRefresh !== true) 1495 setNoRefreshFilter(objFilter); 1496 1497 var objGrid = objFilter.data("grid"); 1498 1499 if(!objGrid || objGrid.length == 0){ 1500 1501 trace(objGrid); 1502 1503 throw new Error("Wrong filter change"); 1504 return(false); 1505 } 1506 1507 var filterRole = objFilter.data("role"); 1508 1509 if(filterRole == "main"){ 1510 1511 var isHideChildren = false; 1512 1513 //if no items selected - hide all children 1514 var objData = getGeneralFilterData(objFilter); 1515 if(!objData) 1516 isHideChildren = true; 1517 1518 clearChildFilters(objGrid, objFilter, isHideChildren); 1519 } 1520 1521 //check for skip action 1522 1523 var isSkipAction = checkTriggerSkipAction(objFilter, objGrid); 1524 1525 if(isSkipAction == true) 1526 return(false); 1527 1528 1529 if(g_showDebug == true){ 1530 1531 trace("refresh grid - on general filter change"); 1532 trace(objFilter); 1533 1534 } 1535 1536 refreshAjaxGrid(objGrid); 1537 1538 return(false); 1539 } 1540 1541 1542 /** 1543 * select filter items by terms, without refresh, just set selected 1544 */ 1545 function selectFilterItemsByTerms(objFilters, arrTerms){ 1546 1547 if(!objFilters || objFilters.length == 0) 1548 return(false); 1549 1550 if(!arrTerms || arrTerms.length == 0) 1551 return(false); 1552 1553 jQuery.each(objFilters,function(index, filter){ 1554 1555 var objFilter = jQuery(filter); 1556 1557 selectFilterItems(objFilter, arrTerms); 1558 1559 }); 1560 1561 } 1562 1563 /** 1564 * select filter items 1565 */ 1566 function selectFilterItems(objFilter, arrTerms){ 1567 1568 var type = getFilterType(objFilter); 1569 1570 switch(type){ 1571 //case g_types.SELECT: 1572 case g_types.TERMS_LIST: 1573 1574 termListSelectItems(objFilter, arrTerms); 1575 1576 break; 1577 case g_types.GENERAL: 1578 1579 objFilter.trigger("uc_select_items", arrTerms); 1580 1581 break; 1582 } 1583 1584 } 1585 1586 /** 1587 * get filter data 1588 */ 1589 function getGeneralFilterData(objFilter){ 1590 1591 var filterDataObj = {}; 1592 objFilter.trigger(g_vars.EVENT_GET_FILTER_DATA, filterDataObj); 1593 1594 var filterData = getVal(filterDataObj, "output"); 1595 1596 return(filterData); 1597 } 1598 1599 1600 function ________INIT_FILTERS_______________(){} 1601 1602 /** 1603 * init terms related filer (terms list and select) 1604 */ 1605 function initTermsRelatedFilter(objFilter){ 1606 1607 objFilter.on(g_vars.ACTION_FILTER_UNSELECT_BY_KEY, termsFilterUnselectByKey
1607); 1608 1609 } 1610 1611 1612 /** 1613 * get filter taxonomy id's 1614 */ 1615 function getFilterTaxIDs(objFilter, objIDs){ 1616 1617 var type = getFilterType(objFilter); 1618 1619 //skip the if 1620 if(type == g_types.SELECT) 1621 var objItems = objFilter.find(".uc-select-filter__option"); 1622 else 1623 var objItems = objFilter.find(".ue_taxonomy_item"); 1624 1625 if(objItems.length == 0) 1626 return(objIDs); 1627 1628 jQuery.each(objItems, function(index, item){ 1629 1630 var objItem = jQuery(item); 1631 var taxID = objItem.data("id"); 1632 1633 if(!taxID) 1634 return(true); 1635 1636 objIDs[taxID] = true; 1637 }); 1638 1639 1640 return(objIDs); 1641 } 1642 1643 /** 1644 * get tax id's list string from assoc object 1645 */ 1646 function getTermDsList(objIDs){ 1647 1648 var strIDs = ""; 1649 for(var id in objIDs){ 1650 1651 if(jQuery.isNumeric(id) == false) 1652 continue; 1653 1654 if(strIDs) 1655 strIDs += ","; 1656 1657 strIDs += id; 1658 } 1659 1660 return(strIDs); 1661 } 1662 1663 1664 function ________DATA_______________(){} 1665 1666 1667 /** 1668 * handle term, add to taxonomy array 1669 */ 1670 function buildTermsQuery_handleTerm(objTerm, arrTax1){ 1671 1672 var taxonomy = objTerm["taxonomy"]; 1673 var slug = objTerm["slug"]; 1674 1675 var objTax = getVal(arrTax1, taxonomy); 1676 if(!objTax) 1677 objTax = {}; 1678 1679 objTax[slug] = true; 1680 arrTax1[taxonomy] = objTax; 1681 1682 return(arrTax1); 1683 } 1684 1685 /** 1686 * get slugs string 1687 */ 1688 function buildTermsQuery_getStrSlugs(objSlugs, isGroup){ 1689 1690 var strSlugs = ""; 1691 1692 var moreThenOne = false; 1693 var isEndSlugFound = false; 1694 1695 for (var slug in objSlugs){ 1696 1697 if(slug === "__ucand__"){ 1698 isEndSlugFound = true; 1699 continue 1700 } 1701 1702 if(strSlugs){ 1703 moreThenOne = true; 1704 strSlugs += "."; 1705 } 1706 1707 strSlugs += slug; 1708 } 1709 1710 //add "and" 1711 1712 var addAnd = (moreThenOne == true && isGroup !== true || isEndSlugFound); 1713 1714 if(addAnd) 1715 strSlugs += ".*"; 1716 1717 return(strSlugs); 1718 } 1719 1720 1721 /** 1722 * build terms query 1723 * ucterms=product_cat~shoes.dress;cat~123.43; 1724 */ 1725 function buildTermsQuery(arrTerms){ 1726 1727 var isDebug = false; 1728 1729 var query = ""; 1730 1731 //break by taxonomy 1732 1733 var arrTax = {}; 1734 var arrGroupTax = {}; 1735 1736 if(isDebug == true){ 1737 trace("arr terms"); 1738 trace(arrTerms); 1739 } 1740 1741 jQuery.each(arrTerms, function(index, objTerm){ 1742 1743 //group term 1744 if(jQuery.isArray(objTerm) && objTerm.length != 0){ 1745 1746 jQuery.each(objTerm, function(index, groupTerm){ 1747 1748 arrGroupTax = buildTermsQuery_handleTerm(groupTerm, arrGroupTax); 1749 1750 }); 1751 1752 }else{ //single term 1753 1754 arrTax = buildTermsQuery_handleTerm(objTerm, arrTax); 1755 } 1756 1757 }); 1758 1759 if(isDebug == true){ 1760 trace("first arr tax"); 1761 trace(arrTax); 1762 } 1763 1764 //combine the query 1765 1766 if(jQuery.isEmptyObject(arrTax) && jQuery.isEmptyObject(arrGroupTax)) 1767 return(null); 1768 1769 if(isDebug == true){ 1770 trace("build group"); 1771 trace(arrGroupTax); 1772 } 1773 1774 //build group slugs 1775 jQuery.each(arrGroupTax,function(taxonomy, objSlugs){ 1776 1777 var strSlugs = buildTermsQuery_getStrSlugs(objSlugs, true); 1778 1779 var strAdd = "|"+strSlugs+"|"; 1780 1781 var objTax = getVal(arrTax, taxonomy); 1782 if(!objTax){ 1783 objTax = {}; 1784 1785 strAdd = strSlugs; 1786 } 1787 1788 objTax[strAdd] = true; 1789 1790 arrTax[taxonomy] = objTax; 1791 }); 1792 1793 1794 if(isDebug == true){ 1795 trace("group built"); 1796 trace(arrTax); 1797 } 1798 1799 //add group to tax 1800 1801 jQuery.each(arrTax, function(taxonomy, objSlugs){ 1802 1803 var strSlugs = buildTermsQuery_getStrSlugs(objSlugs); 1804 1805 var strTax = taxonomy + g_options.urlkey_taxsap + strSlugs; 1806 1807 if(query) 1808 query += ";"; 1809 1810 query += strTax; 1811 1812 }); 1813 1814 if(isDebug == true){ 1815 trace("query"); 1816 trace(query); 1817 } 1818 1819 return(query); 1820 } 1821 1822 /** 1823 * get selected filter element data 1824 */ 1825 function getFilterElementData(objElement){ 1826 1827 var id = objElement.data("id"); 1828 var slug = objElement.data("slug"); 1829 var taxonomy = objElement.data("taxonomy"); 1830 var title = objElement.data("title"); 1831 var key = objElement.data("key"); 1832 var type = objElement.data("type"); 1833 1834 if(!taxonomy) 1835 return(null); 1836 1837 var objTerm = { 1838 "type": type, 1839 "id": id, 1840 "slug": slug, 1841 "taxonomy": taxonomy, 1842 "title": title, 1843 "key": key 1844 }; 1845 1846 return(objTerm); 1847 } 1848 1849 1850 function ________AJAX_CACHE_________(){} 1851 1852 /** 1853 * get ajax url 1854 */ 1855 function getAjaxCacheKeyFromUrl(ajaxUrl){ 1856 1857 var key = ajaxUrl; 1858 1859 key = key.replace(g_urlAjax, ""); 1860 key = key.replace(g_urlBase, ""); 1861 1862 //replace special signs 1863 key = replaceAll(key, "/",""); 1864 key = replaceAll(key, "?","_"); 1865 key = replaceAll(key, "&","_"); 1866 key = replaceAll(key, "=","_"); 1867 1868 return(key); 1869 } 1870 1871 /**
1872 * get ajax cache key 1873 */ 1874 function getAjaxCacheKey(ajaxUrl, action, objData){ 1875 1876 if(g_options.is_cache_enabled == false) 1877 return(false); 1878 1879 //cache only by url meanwhile 1880 1881 if(jQuery.isEmptyObject(objData) == false) 1882 return(false); 1883 1884 if(action) 1885 return(false); 1886 1887 var cacheKey = getAjaxCacheKeyFromUrl(ajaxUrl); 1888 1889 if(!cacheKey) 1890 return(false); 1891 1892 return(cacheKey); 1893 } 1894 1895 1896 /** 1897 * cache ajax response 1898 */ 1899 function cacheAjaxResponse(ajaxUrl, action, objData, response){ 1900 1901 var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData); 1902 1903 if(!cacheKey) 1904 return(false); 1905 1906 //some precoutions for overload 1907 if(g_cache.length > 100) 1908 return(false); 1909 1910 g_cache[cacheKey] = response; 1911 1912 } 1913 1914 1915 function ________AJAX_RESPONSE_______________(){} 1916 1917 /** 1918 * replace the grid debug 1919 */ 1920 function operateAjax_setHtmlDebug(response, objGrid){ 1921 1922 //replace the debug 1923 var htmlDebug = getVal(response, "html_debug"); 1924 1925 if(!htmlDebug) 1926 return(false); 1927 1928 var gridParent = objGrid.parents("." + g_vars.class_widget_container); 1929 1930 var objDebug = gridParent.find(".uc-debug-query-wrapper"); 1931 1932 if(objDebug.length == 0) 1933 return(false); 1934 1935 objDebug.replaceWith(htmlDebug); 1936 } 1937 1938 1939 /** 1940 * set html grid from ajax response 1941 */ 1942 function operateAjax_setHtmlGrid(response, objGrid, isLoadMore){ 1943 1944 if(g_showDebug == true){ 1945 trace("set html grid, response: "); 1946 trace(response); 1947 1948 trace("obj grid:"); 1949 trace(objGrid); 1950 } 1951 1952 if(objGrid.length == 0) 1953 return(false); 1954 1955 //skip set html if exists 1956 if(objGrid.data(g_vars.GRID_DATA_SKIP_HTML) === true){ 1957 1958 if(g_showDebug == true) 1959 trace("skip set html"); 1960 1961 objGrid.data(g_vars.GRID_DATA_SKIP_HTML,false); 1962 return(false); 1963 } 1964 1965 var objItemsWrapper = getGridItemsWrapper(objGrid); 1966 var objItemsWrapper2 = getGridItemsWrapper(objGrid, true); 1967 1968 if(g_showDebug == true){ 1969 trace("items wrapper 1: "); 1970 trace(objItemsWrapper); 1971 1972 trace("items wrapper 2:"); 1973 trace(objItemsWrapper2); 1974 } 1975 1976 1977 if(!objItemsWrapper || objItemsWrapper.length == 0) 1978 throw new Error("Missing items wrapper: .uc-items-wrapper"); 1979 1980 operateAjax_setHtmlDebug(response, objGrid); 1981 1982 //set grid items 1983 1984 //if init filters mode, and no items response - don't set 1985 if(response.hasOwnProperty("html_items") == false) 1986 return(false); 1987 1988 var htmlItems = getVal(response, "html_items"); 1989 1990 var htmlItems2 = null; 1991 1992 if(objItemsWrapper2) 1993 htmlItems2 = getVal(response, "html_items2"); 1994 1995 //replace widget id 1996 var gridID = objGrid.attr("id"); 1997 1998 htmlItems = replaceAll(htmlItems, "%uc_widget_id%", gridID); 1999 2000 if(htmlItems2) 2001 htmlItems2 = replaceAll(htmlItems2, "%uc_widget_id%", gridID); 2002 2003 var isCustomRefresh = objGrid.data("custom-sethtml"); 2004 2005 //show / hide empty message if available and empty response 2006 var objEmptyMessage = getGridEmptyMessage(objGrid); 2007 2008 if(objEmptyMessage){ 2009 if(htmlItems == "") 2010 objEmptyMessage.show(); 2011 else 2012 objEmptyMessage.hide(); 2013 } 2014 2015 //set the query data 2016 var queryDataOriginal = getVal(response, "query_data"); 2017 var queryIDs = getVal(response,"query_ids"); 2018 2019 var queryData = jQuery.extend({}, queryDataOriginal); 2020 2021 //add to old data 2022 2023 if(isLoadMore == true){ 2024 2025 var currentQueryData = objGrid.attr("querydata"); 2026 2027 var objCurrentData = jQuery.parseJSON(currentQueryData); 2028 var currentNumPosts = getVal(objCurrentData, "count_posts"); 2029 2030 queryData.count_posts += currentNumPosts; 2031 2032 var currentQueryIDs = objGrid.data("postids"); 2033 2034 if(queryIDs && currentQueryIDs) 2035 queryIDs = currentQueryIDs + "," + queryIDs; 2036 } 2037 2038 //query data replace 2039 2040 if(queryData){ 2041 2042 objGrid.removeAttr("querydata"); 2043 2044 var jsonData = JSON.stringify(queryData); 2045 objGrid.attr("querydata", jsonData); 2046 2047 objGrid.data("querydata", queryData); 2048 } 2049 2050 //post id's replace 2051 2052 objGrid.removeAttr("data-postids"); 2053 objGrid.attr("data-postids", queryIDs); 2054 objGrid.data("postids", queryIDs); 2055 2056 2057 //if custom refresh - just save the new html in data 2058 if(isCustomRefresh == true){ 2059 2060 objGrid.trigger(g_vars.EVENT_SET_HTML_ITEMS,[htmlItems, isLoadMore, htmlItems2]); 2061 return(false); 2062 } 2063 2064 2065 if(!htmlItems2) 2066 htmlItems2 = ""; 2067 2068 if(isLoadMore === true){ 2069 2070 if(g_showDebug == true){ 2071 trace("append load more"); 2072 } 2073 2074 objItemsWrapper.append(htmlItems); 2075 2076 if(objItemsWrapper) 2077 objItemsWrapper.append(htmlItems2); 2078 2079 }else{ 2080 2081 objItemsWrapper.html(htmlItems); 2082 2083 if(objItemsWrapper2 && objItemsWrapper2.length) 2084 objItemsWrapper2.html(htmlItems2); 2085 2086 } 2087 2088 2089 return(true); 2090 } 2091 2092 2093 /** 2094 * refresh synced grids 2095 */ 2096 function operateAjax_setHtmlSyngGrids(response, objGrid, isLoadMore){ 2097 2098 var objSyncWidgetsResponse = getVal(response, "html_sync_widgets"); 2099 2100 if(g_showDebug == true){ 2101 trace("set html sync grids"); 2102 trace(objSyncWidgetsResponse); 2103 } 2104
2105 var queryData = getVal(response,"query_data"); 2106 2107 if(!objSyncWidgetsResponse) 2108 return(false); 2109 2110 jQuery.each(objSyncWidgetsResponse, function(elementID, childResponse){ 2111 2112 var objGridWidget = getGridFromElementorElementID(elementID); 2113 2114 if(!objGridWidget) 2115 return(true); 2116 2117 objGridWidget.removeClass(g_vars.CLASS_REFRESH_SOON); 2118 2119 childResponse.query_data = queryData; 2120 2121 operateAjax_setHtmlGrid(childResponse, objGridWidget, isLoadMore); 2122 2123 objGridWidget.trigger(g_vars.EVENT_AJAX_REFRESHED); 2124 g_objBody.trigger(g_vars.EVENT_AJAX_REFRESHED_BODY, [objGridWidget]); 2125 2126 }); 2127 2128 } 2129 2130 2131 /** 2132 * replace filters html 2133 */ 2134 function operateAjax_setHtmlWidgets(response, objFilters){ 2135 2136 if(!objFilters) 2137 return(false); 2138 2139 if(objFilters.length == 0) 2140 return(false); 2141 2142 var objHtmlWidgets = getVal(response, "html_widgets"); 2143 2144 if(!objHtmlWidgets) 2145 return(false); 2146 2147 if(objHtmlWidgets.length == 0) 2148 return(false); 2149 2150 var objHtmlDebug = getVal(response, "html_widgets_debug"); 2151 2152 jQuery.each(objFilters, function(index, objFilter){ 2153 2154 var widgetID = getElementWidgetID(objFilter); 2155 2156 if(!widgetID) 2157 return(true); 2158 2159 var html = getVal(objHtmlWidgets, widgetID); 2160 2161 if(!html) 2162 return(true); 2163 2164 var objHtml = jQuery(html); 2165 2166 var htmlInner = objHtml.html(); 2167 2168 //set the class 2169 2170 var filterClassName = objHtml.attr("class"); 2171 2172 filterClassName += " "+g_vars.CLASS_FILTER_INITED; 2173 2174 objFilter.attr("class", filterClassName); 2175 2176 objFilter.removeClass(g_vars.CLASS_INITING); 2177 objFilter.removeClass(g_vars.CLASS_REFRESH_SOON); 2178 2179 objFilter.html(htmlInner); 2180 2181 2182 //---- put the debug if exists 2183 2184 var htmlDebug = null; 2185 2186 if(objHtmlDebug) 2187 var htmlDebug = getVal(objHtmlDebug, widgetID); 2188 2189 if(htmlDebug){ 2190 var objParent = objFilter.parents("." + g_vars.class_widget_container); 2191 var objDebug = objParent.find(".uc-div-ajax-debug"); 2192 2193 if(objDebug.length) 2194 objDebug.replaceWith(htmlDebug); 2195 } 2196 2197 2198 objFilter.trigger(g_vars.EVENT_FILTER_RELOADED); 2199 2200 }); 2201 2202 } 2203 2204 /** 2205 * scroll to grid top 2206 */ 2207 function scrollToGridTop(objGrid){ 2208 2209 var gapTop = 150; 2210 2211 var gridOffset = objGrid.offset().top; 2212 2213 var gridTop = gridOffset - gapTop; 2214 2215 if(gridTop < 0) 2216 gridTop = 0; 2217 2218 //check if the grid top is visible 2219 2220 var currentPos = jQuery(window).scrollTop(); 2221 2222 if(currentPos <= gridOffset) 2223 return(false); 2224 2225 window.scrollTo({ top: gridTop, behavior: 'smooth' }); 2226 2227 } 2228 2229 2230 /** 2231 * operate the response 2232 */ 2233 function operateAjaxRefreshResponse(response, objGrid, objFilters, isLoadMore, isNoScroll){ 2234 2235 var isGridRefreshed = operateAjax_setHtmlGrid(response, objGrid, isLoadMore); 2236 2237 operateAjax_setHtmlWidgets(response, objFilters); 2238 2239 operateAjax_setHtmlSyngGrids(response, objGrid, isLoadMore); 2240 2241 objGrid.trigger(g_vars.EVENT_AJAX_REFRESHED); 2242 g_objBody.trigger(g_vars.EVENT_AJAX_REFRESHED_BODY, [objGrid]); 2243 2244 //trigger body as well 2245 2246 //scroll to grid top 2247 if(isLoadMore == false && isGridRefreshed == true && isNoScroll !== true){ 2248 2249 setTimeout(function(){ 2250 2251 scrollToGridTop(objGrid); 2252 2253 },200); 2254 2255 } 2256 2257 } 2258 2259 2260 /** 2261 * replace all occurances 2262 */ 2263 function replaceAll(text, from, to){ 2264 2265 return text.split(from).join(to); 2266 }; 2267 2268 2269 2270 2271 /** 2272 * get response from ajax cache 2273 */ 2274 function getResponseFromAjaxCache(ajaxUrl, action, objData){ 2275 2276 var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData); 2277 2278 if(!cacheKey) 2279 return(false); 2280 2281 var response = getVal(g_cache, cacheKey); 2282 2283 return(response); 2284 } 2285 2286 2287 function ________AJAX_______________(){} 2288 2289 /** 2290 * set this filter not to refresh next time 2291 */ 2292 function setNoRefreshFilter(objFilter){ 2293 2294 objFilter.data("uc_norefresh",true); 2295 2296 } 2297 2298 /** 2299 * show ajax error, should be something visible 2300 */ 2301 function showAjaxError(message){ 2302 2303 alert(message); 2304 2305 } 2306 2307 /** 2308 * get the debug object 2309 */ 2310 function getDebugObject(){ 2311 2312 var objGrid = g_lastGridAjaxCall; 2313 2314 if(!objGrid) 2315 return(null); 2316 2317 var objDebug = objGrid.find("."+g_vars.CLASS_DIV_DEBUG); 2318 2319 if(objDebug.length) 2320 return(objDebug); 2321 2322 //insert if not exists 2323 2324 objGrid.after("<div class='"+g_vars.CLASS_DIV_DEBUG+"' style='padding:10px;display:none;background-color:#D8FCC6'></div>"); 2325 2326 var objDebug = jQuery("body").find("."+g_vars.CLASS_DIV_DEBUG); 2327 2328 return(objDebug); 2329 } 2330 2331 2332 /** 2333 * show ajax debug 2334 */ 2335 function showAjaxDebug(str){ 2336 2337 trace("Ajax Error! - Check the debug"); 2338 2339 str = jQuery.trim(str); 2340 2341 if(!str || str.length == 0) 2342 return(false); 2343 2344 var objStr = jQuery(str); 2345 2346 if(objStr.find("header").length || objStr.find("body").length){ 2347 str = "Wrong ajax response!"; 2348 } 2349 2350 var objDebug = getDebugObject(); 2351 2352 if(!objDebug || objDebug.length == 0){ 2353 2354 alert(str); 2355 2356 throw new Error("debug not found"); 2357 } 2358 2359 objDebug.show(); 2360 objDebug.html(str); 2361 2362 } 2363 2364 2365 /** 2366 * small ajax request 2367 */ 2368 function ajaxRequest(ajaxUrl, action, objData, onSuccess){ 2369 2370 if(g_debugInitMode === true){ 2371 2372 trace("debug init mode - skip request"); 2373 return(false); 2374 } 2375 2376 if(g_showDebug == true){ 2377 trace("ajax request"); 2378 trace(ajaxUrl); 2379 } 2380 2381 if(!objData) 2382 var objData = {}; 2383 2384 if(typeof objData != "object") 2385 throw new Error("wrong ajax param"); 2386 2387 //check response from cache 2388 var responseFromCache = getResponseFromAjaxCache(ajaxUrl, action, objData); 2389 2390 if(responseFromCache){ 2391 2392 //simulate ajax request 2393 setTimeout(function(){ 2394 onSuccess(responseFromCache); 2395 }, 300); 2396 2397 return(false); 2398 } 2399 2400 var ajaxData = {}; 2401 ajaxData["action"] = "unlimitedelements_ajax_action"; 2402 ajaxData["client_action"] = action; 2403 2404 var ajaxtype = "get"; 2405 2406 if(jQuery.isEmptyObject(objData) == false){ 2407 ajaxData["data"] = objData; 2408 ajaxtype = "post"; 2409 } 2410 2411 2412 var ajaxOptions = { 2413 type:ajaxtype, 2414 url:ajaxUrl, 2415 success:function(response){ 2416 2417 if(!response){ 2418 showAjaxError("Empty ajax response!"); 2419 return(false); 2420 } 2421 2422 if(typeof response != "object"){ 2423 2424 try{ 2425 2426 response = jQuery.parseJSON(response); 2427 2428 }catch(e){ 2429 2430 showAjaxDebug(response); 2431 2432 showAjaxError("Ajax Error!!! not ajax response"); 2433 return(false); 2434 } 2435 } 2436 2437 if(response == -1){ 2438 showAjaxError("ajax error!!!"); 2439 return(false); 2440 } 2441 2442 if(response == 0){ 2443 showAjaxError("ajax error, action: <b>"+action+"</b> not found"); 2444 return(false); 2445 } 2446 2447 if(response.success == undefined){ 2448 showAjaxError("The 'success' param is a must!"); 2449 return(false); 2450 } 2451 2452 2453 if(response.success == false){ 2454 showAjaxError(response.message); 2455 return(false); 2456 } 2457 2458 cacheAjaxResponse(ajaxUrl, action, objData, response); 2459 2460 if(typeof onSuccess == "function"){ 2461 2462 onSuccess(response); 2463 } 2464 2465 }, 2466 error:function(jqXHR, textStatus, errorThrown){ 2467 2468 switch(textStatus){ 2469 case "parsererror": 2470 case "error": 2471 2472 //showAjaxError("parse error"); 2473 2474 showAjaxDebug(jqXHR.responseText); 2475 2476 break; 2477 } 2478 } 2479 } 2480 2481 if(ajaxtype == "post"){ 2482 ajaxOptions.dataType = 'json'; 2483 ajaxOptions.data = ajaxData 2484 } 2485 2486 var handle = jQuery.ajax(ajaxOptions); 2487 2488 return(handle); 2489 } 2490 2491 2492 2493 /** 2494 * get grid items wrapper 2495 */ 2496 function getGridItemsWrapper(objGrid, isSecond){ 2497 2498 var classItems = "uc-items-wrapper"; 2499 2500 if(isSecond == true) 2501 classItems = "uc-items-wrapper2"; 2502 2503 if(objGrid.hasClass(classItems)) 2504 return(objGrid); 2505 2506 var objItemsWrapper = objGrid.find("."+classItems); 2507 2508 if(objItemsWrapper.length == 0 && isSecond == false) 2509 throw new Error("Missing items wrapper - with class: uc-items-wrapper"); 2510 2511 if(objItemsWrapper.length == 0) 2512 return(null); 2513 2514 return(objItemsWrapper); 2515 } 2516 2517 2518 /** 2519 * set ajax loader
2520 */ 2521 function showAjaxLoader(objElement){ 2522 2523 objElement.addClass("uc-ajax-loading"); 2524 } 2525 2526 /** 2527 * hide ajax loader 2528 */ 2529 function hideAjaxLoader(objElement){ 2530 2531 objElement.removeClass("uc-ajax-loading"); 2532 } 2533 2534 2535 /** 2536 * show multiple ajax loader 2537 */ 2538 function showMultipleAjaxLoaders(objElements, isShow){ 2539 2540 if(!objElements) 2541 return(false); 2542 2543 if(objElements.length == 0) 2544 return(false); 2545 2546 jQuery.each(objElements,function(index, objElement){ 2547 2548 objElement = jQuery(objElement); 2549 2550 if(isShow == true){ 2551 2552 showAjaxLoader(objElement); 2553 } 2554 else 2555 hideAjaxLoader(objElement); 2556 }); 2557 2558 } 2559 2560 2561 /** 2562 * refresh ajax grid 2563 */ 2564 function refreshAjaxGrid(objGrid, refreshType){ 2565 2566 var isLoadMore = (refreshType == g_vars.REFRESH_MODE_LOADMORE); //for the output 2567 var isFiltersInit = (refreshType == "filters" || refreshType == "filters_children"); 2568 2569 //for the options - not refresh other filters 2570 var isLoadMoreMode = (refreshType == g_vars.REFRESH_MODE_LOADMORE || refreshType == g_vars.REFRESH_MODE_PAGINATION); 2571 2572 //get all grid filters 2573 var objFilters = objGrid.data("filters"); 2574 2575 if(!objFilters) 2576 return(false); 2577 2578 if(objFilters.length == 0) 2579 return(false); 2580 2581 if(objGrid.hasClass(g_vars.CLASS_GRID_NOREFRESH)) 2582 return(false); 2583 2584 var params = {}; 2585 if(refreshType == "filters_children") 2586 params["filters_init_type"] = "children"; 2587 2588 var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid, isFiltersInit, isLoadMoreMode, params); 2589 2590 if(!objAjaxOptions){ 2591 2592 trace("ajax options are null"); 2593 return(false); 2594 } 2595 2596 var ajaxUrl = objAjaxOptions["ajax_url"]; 2597 var urlReplace = objAjaxOptions["url_replace"]; 2598 var arrTerms = objAjaxOptions["terms"]; 2599 2600 if(g_vars.DEBUG_AJAX_OPTIONS == true){ 2601 2602 trace("DEBUG AJAX OPTIONS"); 2603 trace(objAjaxOptions); 2604 return(false); 2605 } 2606 2607 //set the url params 2608 var behave = objGrid.data("filterbehave"); 2609 2610 var isSetUrl = (behave == "mixed" || behave == "mixed_back"); 2611 2612 if(isFiltersInit == false && isSetUrl === true){ 2613 2614 try{ 2615 2616 if(behave == "mixed_back"){ 2617 2618 //save state for back button 2619 2620 var gridID = objGrid.attr("id"); 2621 2622 //save initial state 2623 var isStateEmpty = jQuery.isEmptyObject(history.state); 2624 2625 var objState = {"ucaction":"change", "ajaxurl":ajaxUrl, "gridid":gridID, selected_terms:arrTerms}; 2626 2627 if(isStateEmpty){ 2628 2629 var ajaxUrlInitial = objGrid.data("initajaxurl"); 2630 2631 objState["ajaxurl"] = ajaxUrlInitial; 2632 2633 history.replaceState(objState, null, urlReplace); 2634 } 2635 2636 history.pushState(objState, null, urlReplace); //with back 2637 2638 } 2639 else 2640 history.replaceState({}, null, urlReplace); //without back 2641 2642 }catch(error){ 2643 trace("history push state error"); 2644 trace(error); 2645 } 2646 } 2647 2648 2649 initGrid_setActiveFiltersData(objGrid, objAjaxOptions); 2650 2651 doGridAjaxRequest(ajaxUrl, objGrid, objFilters, isLoadMore, isFiltersInit); 2652 2653 } 2654 2655 2656 /** 2657 * do the actual grid ajax request 2658 */ 2659 function doGridAjaxRequest(ajaxUrl, objGrid, objFilters, isLoadMore, isFiltersInit){ 2660 2661 var objEmptyMessage = getGridEmptyMessage(objGrid); 2662 2663 //set the loaders 2664 2665 if(isLoadMore !== true && isFiltersInit !== true){ 2666 2667 showAjaxLoader(objGrid); 2668 2669 if(objEmptyMessage) 2670 showAjaxLoader(objEmptyMessage); 2671 } 2672 2673 var objFiltersToReload = objFilters.filter(function(objFilter){ 2674 2675 return objFilter.hasClass(g_vars.CLASS_REFRESH_SOON); 2676 }); 2677 2678 showMultipleAjaxLoaders(objFiltersToReload, true); 2679 2680 if(g_lastSyncGrids && isLoadMore !== true){ 2681 2682 showMultipleAjaxLoaders(g_lastSyncGrids, true); 2683 } 2684 2685 //ajax reload 2686 g_lastGridAjaxCall = objGrid; 2687 2688 objGrid.trigger(g_vars.EVENT_BEFORE_REFRESH); 2689 2690 var lastAjaxHandle = objGrid.data("last_ajax_refresh_handle"); 2691 2692 if(lastAjaxHandle){ 2693 lastAjaxHandle.abort(); 2694 } 2695 2696 //--- debug before refresh 2697 2698 if(g_debugBeforeRefreshMode == true){ 2699 2700 alert("Debug before refresh - please turn if off"); 2701 return(false); 2702 } 2703 2704 var ajaxHandle = ajaxRequest(ajaxUrl,null,null, function(response){ 2705 2706 if(isLoadMore !== true){ 2707 hideAjaxLoader(objGrid); 2708 2709 if(objEmptyMessage) 2710 hideAjaxLoader(objEmptyMessage); 2711 } 2712 2713 showMultipleAjaxLoaders(objFilters, false); 2714 2715 if(g_lastSyncGrids) 2716 showMultipleAjaxLoaders(g_lastSyncGrids, false); 2717 2718 operateAjaxRefreshResponse(response, objGrid, objFilters, isLoadMore); 2719 2720 onAfterGridRefresh(objGrid); 2721 2722 }); 2723 2724 objGrid.data("last_ajax_refresh_handle", ajaxHandle); 2725 2726 } 2727 2728 /** 2729 * do some actions after grid refresh, if needed 2730 */ 2731 function onAfterGridRefresh(objGrid){ 2732 2733 //refresh child grids 2734 2735 var isInitRefesh = objGrid.data("init_refresh_child_filters"); 2736 2737 if(isInitRefesh === true){ 2738 2739 objGrid.removeData("init_refresh_child_filters"); 2740 2741 //refresh child filters if there are selected main after init 2742 2743 var objFilters = objGrid.data("filters"); 2744 2745 var arrSelectedMain = getSelectedFilters(objFilters, "main"); 2746 2747 if(arrSelectedMain.length) 2748 refreshAjaxGrid(objGrid, "filters_children"); 2749 } 2750 2751 } 2752 2753 2754 function ________STATE_RELATED_______________(){} 2755 2756 2757 /** 2758 * do history 2759 */ 2760 function changeToHistoryState(state){ 2761 2762 if(g_showDebug == true){ 2763 trace("change to history"); 2764 trace(state); 2765 } 2766 2767 var ajaxUrl = getVal(state, "ajaxurl"); 2768 2769 var gridID = getVal(state, "gridid"); 2770 2771 var arrTerms = getVal(state, "selected_terms"); 2772 2773 if(!gridID) 2774 return(false); 2775 2776 if(!ajaxUrl) 2777 return(false); 2778 2779 var objGrid = jQuery("#"+gridID); 2780 2781 var objFilters = objGrid.data("filters"); 2782 2783 if(!objFilters) 2784 return(false); 2785 2786 //select by terms 2787 2788 selectFilterItemsByTerms(objFilters, arrTerms); 2789 2790 var responseFromCache = getResponseFromAjaxCache(ajaxUrl); 2791 2792 if(!responseFromCache){ 2793 2794 //do ajax request 2795 2796 doGridAjaxRequest(ajaxUrl, objGrid, objFilters); 2797 2798 return(false); 2799 } 2800 2801 //get data from cache 2802 2803 //trace("restore"); 2804 //trace(responseFromCache); 2805 2806 operateAjaxRefreshResponse(responseFromCache, objGrid, objFilters, false, true); 2807 2808 } 2809 2810 /** 2811 * on pop state, if it's a grid state, set the grid 2812 */ 2813 function onPopState(){ 2814 2815 if(!history.state) 2816 return(true); 2817 2818 var action = getVal(history.state, "ucaction"); 2819 2820 if(!action) 2821 return(true); 2822 2823 switch(action){ 2824 case "change": 2825 2826 changeToHistoryState(history.state); 2827 2828 break; 2829 default: 2830 throw new Error("Wrong history action: " + action); 2831 break; 2832 } 2833 2834 } 2835 2836 2837 function ________RUN_______________(){} 2838 2839 2840 /** 2841 * get url filters string 2842 */ 2843 function getGridUrlFiltersString(objGrid){ 2844 2845 var objAjaxOptions = getGridAjaxOptions_simple(objGrid); 2846 2847 if(!objAjaxOptions) 2848 return(""); 2849 2850 var strFilters = getVal(objAjaxOptions, "filters_string"); 2851 2852 return(strFilters); 2853 } 2854 2855 2856 /** 2857 * get simply the grid ajax options 2858 */ 2859 function getGridAjaxOptions_simple(objGrid){ 2860 2861 var objFilters = objGrid.data("filters"); 2862 2863 if(!objFilters) 2864 return(null); 2865 2866 var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid, false,false,{getonly:true}); 2867 2868 if(!objAjaxOptions) 2869 return(null); 2870 2871 return(objAjaxOptions); 2872 } 2873 2874 /** 2875 * check that element is hidden only by display:none. ":hidden" checks width and height as well 2876 */ 2877 function isElementHiddenByDisplayNone(objElement) { 2878 2879 var element = objElement[0]; 2880 2881 var hidden = window.getComputedStyle(element).display == "none"; 2882 2883 return hidden; 2884 }; 2885 2886 /** 2887 * get grid ajax options 2888 */ 2889 function getGridAjaxOptions(objFilters, objGrid, isFiltersInitMode, isLoadMoreMode, params){ 2890 2891 if(!isLoadMoreMode) 2892 var isLoadMoreMode = false; 2893 2894 if(g_showDebug){ 2895 trace("getGridAjaxOptions"); 2896 2897 trace("Filters:"); 2898 trace(objFilters); 2899 2900 trace("grid:"); 2901 trace(objGrid);
2902 trace("is init: " + isFiltersInitMode); 2903 2904 trace("params: "); 2905 trace(params); 2906 2907 } 2908 2909 //filter only visible elements (by it's parents) 2910 2911 var objVisibleFilters = objFilters.filter(function(objFilter){ 2912 2913 var objParent = getFilterWrapper(objFilter); 2914 2915 var isHidden = isElementHiddenByDisplayNone(objParent); 2916 2917 return(!isHidden); 2918 }); 2919 2920 2921 if(objVisibleFilters.length < objFilters.length){ 2922 2923 if(objVisibleFilters.length == 0){ 2924 2925 if(g_showDebug) 2926 trace("no visible filters"); 2927 2928 var objFilters = []; 2929 } 2930 else{ //test for mobile drawer 2931 2932 var objFirstFilter = jQuery(objVisibleFilters[0]); 2933 var visibleFilterType = getFilterType(objFirstFilter, true); 2934 2935 //exception for mobile drawer 2936 if(visibleFilterType != g_types.GENERAL_MOBILE_DRAWER){ 2937 2938 var objFilters = objVisibleFilters; 2939 2940 if(g_showDebug){ 2941 trace("Visible Filters: "); 2942 trace(objFilters); 2943 } 2944 } 2945 2946 }//end else 2947 2948 2949 } //end visible filters test 2950 2951 2952 if(!objFilters || objFilters.length == 0) 2953 return(null); 2954 2955 var urlReplace = g_urlBase; 2956 2957 var urlAjax = g_urlBase; 2958 2959 var strRefreshIDs = ""; 2960 2961 var isReplaceMode = false; 2962 var page = null; 2963 var offset = null; 2964 var numItems = null; 2965 var arrTerms = []; 2966 var objTaxIDs = {}; 2967 var strSelectedTerms = ""; 2968 var search = ""; 2969 var price_from, price_to; 2970 var orderby = null; 2971 var orderby_metaname = null; 2972 var orderby_metatype = null; 2973 var orderdir = null; 2974 var title_start = null; 2975 var addSyncedGrids = true; 2976 var arrAllFiltersData; //all data gethered for the active filters 2977 var arrFiltersForInit = []; 2978 var urlAddFromFilters = ""; 2979 2980 var isGetUrlOnly = getVal(params,"getonly"); 2981 2982 var initModeType = getVal(params,"filters_init_type"); 2983 2984 var initModeChildrens = false; 2985 if(isFiltersInitMode == true && initModeType == "children") 2986 initModeChildrens = true; 2987 2988 var wasInitMode = objGrid.data("was_init_mode"); 2989 2990 var arrFilterIDs = {}; 2991 2992 var advancedSearchFilterID; 2993 2994 2995 //get ajax options 2996 jQuery.each(objFilters, function(index, objFilter){ 2997 2998 //protection against duplicate id's 2999 var id = objFilter.attr("id"); 3000 3001 if(arrFilterIDs.hasOwnProperty(id) == true){ 3002 3003 trace("problematic filter: "); 3004 trace(objFilter); 3005 3006 trace("original filter found: "); 3007 trace(arrFilterIDs[id]); 3008 3009 trace("filters list: "); 3010 trace(objFilters); 3011 3012 throw new Error("Duplicate Filter ID found: " + id); 3013 } 3014 3015 arrFilterIDs[id] = objFilter; 3016 3017 var isNoRefresh = objFilter.data("uc_norefresh"); 3018 var filterRole = objFilter.data("role"); 3019 3020 var type = getFilterType(objFilter); 3021 3022 if(g_showDebug == true){ 3023 3024 trace("filter: "+type+", role: "+filterRole); 3025 trace(objFilter); 3026 } 3027 3028 var urlAdd = objFilter.attr(g_vars.ATTRIBUTE_URLADD); 3029 3030 if(urlAdd) 3031 urlAddFromFilters = addUrlParam(urlAddFromFilters, urlAdd); 3032 3033 switch(type){ 3034 case g_types.PAGINATION: 3035 3036 //run pagination only if it's clicked, unless reset pagination 3037 var isClicked = objFilter.hasClass(g_vars.CLASS_CLICKED); 3038 if(isClicked == true || isFiltersInitMode == true){ 3039 3040 var paginationData = getPaginationSelectedData(objFilter); 3041 3042 var paginationPage = getVal(paginationData, "page"); 3043 3044 if(paginationPage) 3045 page = paginationPage; //never set the url 3046 3047 //set page from url 3048 if(isFiltersInitMode == true && !page && g_vars.ucpage_url) 3049 page = g_vars.ucpage_url; 3050 3051 if(g_showDebug){ 3052 trace("pagination data"); 3053 trace(paginationData); 3054 } 3055 3056 objFilter.removeClass(g_vars.CLASS_CLICKED); 3057 } 3058 3059 3060 break; 3061 case g_types.LOADMORE: 3062 3063 if(isFiltersInitMode == true) 3064 return(true); 3065 3066 //run load more only if it's clicked, unless reset load more 3067 var isClicked = objFilter.hasClass(g_vars.CLASS_CLICKED); 3068 if(isClicked == true){ 3069 3070 var loadMoreData = getLoadMoreUrlData(objFilter); 3071 offset = loadMoreData.offset; 3072 numItems = loadMoreData.numItems; 3073 3074 var isSingleGrid = loadMoreData.singlegrid; 3075 3076 if(isSingleGrid == true) 3077 addSyncedGrids = false; 3078 3079 if(!offset) 3080 urlAjax = null; 3081 3082 objFilter.removeClass(g_vars.CLASS_CLICKED); 3083 } 3084 3085 break; 3086 case g_types.TERMS_LIST: 3087 case g_types.SELECT: 3088 3089 //if not init mode - take first item 3090 var objTerm = getTermsListSelectedTerm(objFilter); 3091 3092 if(objTerm){ 3093 3094 if(isFiltersInitMode == false){ 3095 3096 arrTerms.push(objTerm); 3097 } 3098 else{ 3099 3100 //INIT MODE 3101 3102 //add terms, if only children mode and the filter not child 3103 if(initModeChildrens == true && filterRole != "child") 3104 arrTerms.push(objTerm); 3105 3106 //set selected terms string 3107 3108 var termID = objTerm.id; 3109 if(strSelectedTerms) 3110 strSelectedTerms +=","; 3111 3112 strSelectedTerms += termID; 3113 } 3114 3115 } 3116 3117 //replace mode 3118 3119 var modeReplace = objFilter.data("replace-mode"); 3120 if(modeReplace === true) 3121 isReplaceMode = true; 3122 3123 if(isLoadMoreMode == true) 3124 isNoRefresh = true; 3125 3126 //debug 3127 if(g_showDebug == true){ 3128 3129 trace("Selected Term: "); 3130 trace(objTerm); 3131 } 3132 3133 break; 3134 case g_types.SUMMARY: 3135 3136 isNoRefresh = true; 3137 3138 //take nothing 3139 break; 3140 case g_types.SEARCH: 3141 3142 isNoRefresh = true; 3143 3144 var objInput = objFilter.find("input"); 3145 3146 search = objInput.val(); 3147 search = search.trim(); 3148 3149 //add id 3150 var isAdvancedSearch = objFilter.data("advancedsearch"); 3151 3152 if(isAdvancedSearch == true) 3153 advancedSearchFilterID = getElementWidgetID(objFilter); 3154 3155 break; 3156 case g_types.GENERAL: 3157 3158 var generalType = objFilter.data("generaltype"); 3159 3160 if(generalType == g_types.GENERAL_MOBILE_DRAWER) 3161 return(true); 3162 3163 var generalIsNoRefresh = objFilter.data("norefresh"); 3164 3165 if(generalIsNoRefresh === true) 3166 isNoRefresh = true; 3167 3168 var filterData = getGeneralFilterData(objFilter); 3169 3170 //add terms 3171 3172 var dataTerms = getVal(filterData,"terms"); 3173 3174 if(dataTerms && dataTerms.length){ 3175 3176 if(dataTerms.length == 1) //single term 3177 arrTerms.push(dataTerms[0]); 3178 else{ 3179 3180 var operator = getVal(filterData,"operator"); 3181 3182 if(operator == "and"){ 3183 3184 var firstTerm = dataTerms[0]; 3185 3186 var objOperatorTerm = { 3187 taxonomy: firstTerm.taxonomy, 3188 slug: "__ucand__",
3189 id:null 3190 }; 3191 3192 dataTerms.push(objOperatorTerm); 3193 } 3194 3195 arrTerms.push(dataTerms); //multiple (grouping) 3196 } 3197 3198 //set selected terms string if init mode 3199 3200 if(isFiltersInitMode == true && dataTerms && dataTerms.length){ 3201 3202 var arrTermsForSelect = []; 3203 3204 if(jQuery.isArray(arrTerms)) 3205 arrTermsForSelect = arrTerms.flat(); 3206 3207 jQuery.each(arrTermsForSelect, function(index, term){ 3208 3209 var termID = getVal(term,"id"); 3210 3211 if(!termID) 3212 return(true); 3213 3214 if(strSelectedTerms) 3215 strSelectedTerms +=","; 3216 3217 strSelectedTerms += termID; 3218 }); 3219 3220 } 3221 } 3222 3223 3224 if(g_showDebug == true){ 3225 trace("Filter Data:"); 3226 trace(filterData); 3227 } 3228 3229 if(generalType == "price" && isFiltersInitMode == false){ 3230 3231 var priceFromArg = getVal(filterData,"price_from"); 3232 var priceToArg = getVal(filterData,"price_to"); 3233 3234 if(priceFromArg) 3235 price_from = roundToOneDecimal(priceFromArg); 3236 3237 if(priceToArg) 3238 price_to = roundToOneDecimal(priceToArg); 3239 } 3240 3241 3242 //add title start 3243 3244 var titleStartArg = getVal(filterData, "title_start"); 3245 if(titleStartArg) 3246 title_start = titleStartArg; 3247 3248 //handle sort 3249 var argOrderby = getVal(filterData,"orderby"); 3250 if(argOrderby && argOrderby != "default"){ 3251 orderby = argOrderby; 3252 3253 orderby_metaname = getVal(filterData,"metaname"); 3254 orderby_metatype = getVal(filterData,"metatype"); 3255 } 3256 3257 var argOrderDir = getVal(filterData,"orderdir"); 3258 if(argOrderDir && argOrderDir != "default") 3259 orderdir = argOrderDir; 3260 3261 if(isLoadMoreMode == true) 3262 isNoRefresh = true; 3263 3264 break; 3265 default: 3266 throw new Error("Unknown filter type: "+type); 3267 break; 3268 } 3269 3270 //handle filters init mode 3271 3272 if(isFiltersInitMode == true){ 3273 3274 var isInit = objFilter.data("initafter"); 3275 3276 if(isInit != true){ 3277 isNoRefresh = true; 3278 } 3279 3280 //refresh parents only 3281 if(initModeChildrens == false && filterRole == "child") 3282 isNoRefresh = true; 3283 3284 //refresh children only 3285 if(initModeChildrens == true && filterRole != "child") 3286 isNoRefresh = true; 3287 3288 if(isNoRefresh == false) 3289 arrFiltersForInit.push(objFilter); 3290 } 3291 3292 3293 //if hidden - no refresh 3294 3295 var isFilterHidden = objFilter.hasClass(g_vars.CLASS_HIDDEN); 3296 if(isFilterHidden == true) 3297 isNoRefresh = true; 3298 3299 objFilter.data("uc_norefresh",false); 3300 3301 var isMainFilter = (filterRole == "main"); 3302 var isTermChild = (filterRole == "term_child"); 3303 3304 //add to refresh filter if it's qualify 3305 3306 var isRefresh = true; 3307 3308 if(isFiltersInitMode == false && (isMainFilter === true || isTermChild == true)) 3309 isRefresh = false; 3310 3311 if(isNoRefresh === true) 3312 isRefresh = false; 3313 3314 if(g_showDebug == true){ 3315 trace("Filter Refresh: "+isRefresh); 3316 } 3317 3318 if(isRefresh == true){ 3319 3320 var filterWidgetID = getElementWidgetID(objFilter); 3321 3322 //add test tax id's for init mode 3323 objTaxIDs = getFilterTaxIDs(objFilter, objTaxIDs); 3324 3325 if(strRefreshIDs) 3326 strRefreshIDs += ","; 3327 3328 strRefreshIDs += filterWidgetID; 3329 3330 if(!isGetUrlOnly) 3331 objFilter.addClass(g_vars.CLASS_REFRESH_SOON); 3332 } 3333 3334 3335 }); //end filters iteration 3336 3337 3338 //add init filters additions 3339 3340 var urlAddition_filtersTest = ""; 3341 var strTaxIDs = getTermDsList(objTaxIDs); 3342 3343 if(isFiltersInitMode == true){ 3344 3345 if(!strTaxIDs && arrFiltersForInit.length == 0) 3346 urlAjax = null; 3347 else{ 3348 3349 if(urlAddition_filtersTest) 3350 urlAddition_filtersTest += "&"; 3351 3352 urlAddition_filtersTest += "modeinit=true"; 3353 } 3354 } 3355 3356 //test terms - only if there are terms in query, or mode init 3357 3358 if(strTaxIDs && (search || arrTerms.length || isFiltersInitMode == true || wasInitMode === true) ){ 3359 3360 if(urlAddition_filtersTest) 3361 urlAddition_filtersTest += "&"; 3362 3363 urlAddition_filtersTest += "testtermids="+strTaxIDs; 3364 } 3365 3366 g_lastSyncGrids = null; 3367 3368 if(urlAjax == null) 3369 return(null); 3370 3371 var dataLayout = getElementLayoutData(objGrid, addSyncedGrids); 3372 3373 var widgetID = dataLayout["widgetid"]; 3374 var layoutID = dataLayout["layoutid"]; 3375 3376 //disable synced 3377 3378 if(addSyncedGrids == false){ 3379 3380 var syncedWidgetIDs = false; 3381 g_lastSyncGrids = null; 3382 3383 }else{ 3384 3385 var syncedWidgetIDs = getVal(dataLayout,"synced_widgetids"); 3386 g_lastSyncGrids = getVal(dataLayout,"synced_grids"); 3387 } 3388 3389 3390 var urlFilterString = ""; 3391 3392 var urlAddition = "ucfrontajaxaction=getfiltersdata&layoutid="+layoutID+"&elid="+widgetID; 3393 3394 urlAjax = addUrlParam(urlAjax, urlAddition); 3395 3396 if(g_isGutenberg == true) 3397 urlAjax = addUrlParam(urlAjax, "platform=gutenberg"); 3398 3399 if(syncedWidgetIDs) 3400 urlAjax += "&syncelids="+syncedWidgetIDs; 3401 3402 if(urlAddition_filtersTest) 3403 urlAjax = addUrlParam(urlAjax, urlAddition_filtersTest); 3404 3405 if(price_from){ 3406 urlAjax += "&ucpricefrom="+price_from; 3407 3408 if(g_showDebug == true){ 3409 trace("add price from"); 3410 trace(urlAjax); 3411 } 3412 } 3413 3414 if(price_to){ 3415 urlAjax += "&ucpriceto="+price_to; 3416 3417 if(g_showDebug == true){ 3418 trace("add price to"); 3419 trace(urlAjax); 3420 } 3421 } 3422 3423 if(title_start){ 3424 3425 if(g_showDebug == true) 3426 trace("add title start: "+title_start); 3427 3428 urlAjax += "&titlestart="+title_start; 3429 urlReplace = addUrlParam(urlReplace, "titlestart="+title_start); 3430 } 3431 3432 3433 if(page){ 3434 urlAjax += "&ucpage="+page; 3435 3436 urlReplace = addUrlParam(urlReplace, "ucpage="+page); 3437 } 3438 3439 if(numItems) 3440 urlAjax += "&uccount="+numItems; 3441 3442 if(arrTerms.length){ 3443 3444 var strTerms = buildTermsQuery(arrTerms); 3445 if(strTerms) 3446 urlAjax += "&ucterms="+strTerms; 3447 3448 //set the url params as well 3449 3450 urlReplace = addUrlParam(urlReplace, "ucterms="+strTerms); 3451 3452 urlFilterString = addUrlParam(urlFilterString, "ucterms="+strTerms); 3453 } 3454 3455 if(orderby){ 3456 3457 urlAjax += "&ucorderby="+orderby; 3458 urlReplace = addUrlParam(urlReplace, "ucorderby="+orderby); 3459 3460 if(orderby_metaname){ 3461 urlAjax += "&ucorderby_meta="+orderby_metaname; 3462 urlReplace = addUrlParam(urlReplace, "ucorderby_meta="+orderby_metaname); 3463 } 3464 3465 if(orderby_metatype){ 3466 urlAjax += "&ucorderby_metatype="+orderby_metatype; 3467 urlReplace = addUrlParam(urlReplace, "ucorderby_metatype="+orderby_metatype); 3468 } 3469 3470 } 3471 3472 if(orderdir){ 3473 urlAjax += "&ucorderdir="+orderdir; 3474 3475 urlReplace = addUrlParam(urlReplace, "ucorderdir="+orderdir); 3476 } 3477 3478 3479 if(isFiltersInitMode && strSelectedTerms) 3480 urlAjax += "&ucinitselectedterms="+strSelectedTerms; 3481 3482 //add refresh ids 3483 if(strRefreshIDs) 3484 urlAjax += "&addelids="+strRefreshIDs; 3485 3486 if(isReplaceMode == true) 3487 urlAjax += "&ucreplace=1"; 3488 3489 //search 3490 if(search){ 3491 search = encodeURIComponent(search); 3492 3493 //search = escape(search); 3494 urlAjax += "&ucs=" + search; 3495 3496 urlFilterString = addUrlParam(urlFilterString, "ucs=" + search); 3497 3498 urlReplace += "&ucs=" + search; 3499 3500 //add special search id 3501 if(advancedSearchFilterID) 3502 urlAjax += "&ucsid="+advancedSearchFilterID; 3503 3504 } 3505 3506 //avoid duplicates - exclude, disable the offset 3507 3508 if(objGrid.hasClass("uc-avoid-duplicates") && isLoadMoreMode == true){ 3509 3510 var strExcludePostIDs = getExcludePostIDs(); 3511 3512 if(strExcludePostIDs){ 3513 urlAjax += "&ucexclude="+strExcludePostIDs; 3514 offset = null; 3515 3516 urlFilterString = addUrlParam(urlFilterString, "ucexclude=" + strExcludePostIDs); 3517 } 3518 3519 } 3520 3521 if(offset){ 3522 urlAjax += "&ucoffset="+offset; 3523 3524 urlFilterString = addUrlParam(urlFilterString, "offset=" + offset); 3525 3526 } 3527 3528 //add custom additional attributes 3529 3530 if(urlAddFromFilters){ 3531 urlAjax += addUrlParam(urlAjax, urlAddFromFilters); 3532 urlFilterString = addUrlParam(urlFilterString, urlAddFromFilters); 3533 } 3534 3535 //remove the "?" from first 3536 if(urlFilterString) 3537 urlFilterString = urlFilterString.substring(1); 3538 3539 3540 //remember init mode 3541 if(isFiltersInitMode == true) 3542 objGrid.data("was_init_mode",true); 3543 3544 3545 if(g_showDebug == true){ 3546 3547 trace("url ajax: " + urlAjax); 3548 } 3549 3550 var output = {}; 3551 output["ajax_url"] = urlAjax; 3552 output["url_replace"] = urlReplace; 3553 output["terms"] = arrTerms; 3554 output["search"] = search; 3555 output["filters_string"] = urlFilterString; 3556 3557 if(g_showDebug == true){ 3558 3559 trace("output: "); 3560 trace(output); 3561 3562 trace("End getGridAjaxOptions function"); 3563 } 3564 3565 3566 3567 return(output); 3568 } 3569 3570 3571 /** 3572 * get all exclude post ids from all avoid duplicates grids
3573 * if it's a single avoid duplicates grid - don't get excludes 3574 */ 3575 function getExcludePostIDs(){ 3576 3577 //check if it's only one grid involved 3578 3579 var objGrids = jQuery(".uc-avoid-duplicates"); 3580 3581 if(objGrids.length == 0) 3582 return(""); 3583 3584 //check if rand of only grid, get id's, else not 3585 3586 if(objGrids.length == 1){ 3587 var queryData = objGrids.attr("querydata"); 3588 3589 var objQueryData = JSON.parse(queryData); 3590 var orderby = getVal(objQueryData,"orderby"); 3591 3592 if(orderby != "rand") 3593 return(""); 3594 } 3595 3596 3597 //get all the id's of all including the existing. 3598 3599 var strIDs = ""; 3600 3601 jQuery.each(objGrids, function(index, grid){ 3602 var objGrid = jQuery(grid); 3603 3604 var postIDs = objGrid.data("postids"); 3605 3606 if(!postIDs) 3607 return(true); 3608 3609 if(strIDs) 3610 strIDs += ","; 3611 3612 strIDs += postIDs; 3613 }); 3614 3615 3616 return(strIDs); 3617 } 3618 3619 3620 function ________INIT_______________(){} 3621 3622 3623 /** 3624 * init the globals 3625 */ 3626 function initGlobals(){ 3627 3628 if(typeof g_strFiltersData === "undefined") 3629 return(false); 3630 3631 g_filtersData = JSON.parse(g_strFiltersData); 3632 3633 if(jQuery.isEmptyObject(g_filtersData)){ 3634 3635 trace("filters error - filters data not found"); 3636 return(false); 3637 } 3638 3639 g_urlBase = getVal(g_filtersData, "urlbase"); 3640 g_urlAjax = getVal(g_filtersData, "urlajax"); 3641 3642 var platform = getVal(g_filtersData, "platform"); 3643 3644 //switch to gutenberg 3645 3646 if(platform == "gutenberg"){ 3647 g_isGutenberg = true; 3648 g_vars.class_widget_wrapper = "ue-widget-root"; 3649 g_vars.class_widget_container = "ue-widget-root"; 3650 g_vars.current_postid = getVal(g_filtersData, "postid"); 3651 } 3652 3653 //ucpage url 3654 var ucpage = getVal(g_filtersData,"ucpage"); 3655 if(jQuery.isNumeric(ucpage)) 3656 g_vars.ucpage_url = ucpage; 3657 3658 //url keys 3659 3660 var objUrlKeys = getVal(g_filtersData, "urlkeys"); 3661 var taxSap = getVal(objUrlKeys, "tax_sap"); 3662 if(taxSap) 3663 g_options.urlkey_taxsap = taxSap; 3664 3665 var isShowDebug = getVal(g_filtersData, "debug"); 3666 3667 if(isShowDebug == true) 3668 g_showDebug = true; 3669 3670 if(g_showDebug == true) 3671 trace("Show Filters Debug"); 3672 3673 if(!g_urlBase){ 3674 trace("ue filters error - base url not inited"); 3675 return(false); 3676 } 3677 3678 if(!g_urlAjax){ 3679 trace("ue filters error - ajax url not inited"); 3680 return(false); 3681 } 3682 3683 //trace(g_options); 3684 3685 return(true); 3686 } 3687 3688 3689 /** 3690 * init filter and bing to grid 3691 */ 3692 function initFilter(objFilter, type){ 3693 3694 var objGrid = getClosestGrid(objFilter); 3695 3696 var error = "Filter Parent not found! Please put the posts element on the page, and turn on 'Enable Post Filtering' option on it"; 3697 3698 if(!objGrid){ 3699 3700 3701 //pagination can work without parent as regular link 3702 3703 var type = getFilterType(objFilter); 3704 if(type == g_types.PAGINATION) 3705 return(false); 3706 3707 showElementError(objFilter, error); 3708 return(null); 3709 } 3710 3711 var isAjax = objGrid.data("ajax"); 3712 3713 if(isAjax == false){ 3714 showElementError(objFilter, error); 3715 return(false); 3716 } 3717 3718 //bind grid to filter 3719 objFilter.data("grid", objGrid); 3720 3721 //bind filter to grid 3722 bindFilterToGrid(objGrid, objFilter); 3723 3724 //set data var 3725 if(g_showDebug == true) 3726 objFilter.attr("data-showdebug", true); 3727 3728 3729 switch(type){ 3730 case g_types.TERMS_LIST: 3731 initTermsRelatedFilter(objFilter); 3732 break; 3733 case g_types.SELECT: 3734 initSelectFilter(objFilter); 3735 initTermsRelatedFilter(objFilter); 3736 break; 3737 case g_types.GENERAL: //general filter events 3738 initGeneralFilter(objFilter); 3739 break; 3740 } 3741 3742 3743 objFilter.trigger(g_vars.EVENT_INIT_FILTER); 3744 3745 } 3746 3747 3748 /** 3749 * init filter events by types 3750 */ 3751 function initFilterEventsByTypes(arrTypes, arrGeneralTypes, objFilters, objParent){ 3752 3753 if(!arrTypes || arrTypes.length == 0) 3754 return(false); 3755 3756 if(g_showDebug == true){ 3757 trace("Init filter events for parent"); 3758 trace(arrTypes); 3759 trace(objParent); 3760 } 3761 3762 for(var type in arrTypes){ 3763 3764 switch(type){ 3765 case g_types.PAGINATION: 3766 3767 objParent.on("click",".uc-filter-pagination a", onAjaxPaginationLinkClick); 3768 3769 break; 3770 case g_types.LOADMORE: 3771 3772 //load more 3773 objParent.on("click",".uc-filter-load-more__link", onLoadMoreClick); 3774 break; 3775 case g_types.TERMS_LIST: 3776 3777 objParent.on("click",".ue_taxonomy.uc-grid-filter a.ue_taxonomy_item", onTermsLinkClick); 3778 3779 break; 3780 case g_types.SEARCH: 3781 3782 //do nothing for init 3783 3784 break; 3785 case g_types.SELECT: 3786 3787 objParent.on("change", ".uc-select-filter__select", onTermsLinkClick); 3788 3789 break; 3790 case g_types.SUMMARY: 3791 //do nothing for now 3792 break; 3793 case g_types.GENERAL: 3794 //the init is from the general types 3795 break; 3796 default: 3797 trace("init by type - unrecognized type: "+type); 3798 break; 3799 } 3800 } 3801 3802 if(!arrGeneralTypes || arrGeneralTypes.length == 0) 3803 return(false); 3804 3805 3806 //init the general types 3807 3808 for(var generalType in arrGeneralTypes){ 3809 3810 var objFirstFilter = arrGeneralTypes[generalType]; 3811 3812 objFirstFilter.trigger(g_vars.EVENT_INIT_FILTER_TYPE,[objParent]);
3813 3814 } 3815 3816 } 3817 3818 3819 /** 3820 * check if there is a need to refresh child filters 3821 * grid related, other filters are set in the settings 3822 */ 3823 function initGrid_setInitFiltersAfterLoad(objGrid){ 3824 3825 //get all grid filters 3826 var objFilters = objGrid.data("filters"); 3827 3828 if(!objFilters) 3829 return(false); 3830 3831 if(objFilters.length == 0) 3832 return(false); 3833 3834 //check if there are mains with selected 3835 3836 var arrSelectedMain = getSelectedFilters(objFilters, "main"); 3837 3838 if(arrSelectedMain.length == 0) 3839 return(false); 3840 3841 //add to refresh child filters 3842 3843 jQuery.each(objFilters, function(index, filter){ 3844 3845 var objFilter = jQuery(filter); 3846 var isSelected = objFilter.hasClass("uc-has-selected"); 3847 3848 var role = objFilter.data("role"); 3849 3850 if(role != "child") 3851 return(true); 3852 3853 //add to grid and option to refresh 3854 3855 var objGrid = objFilter.data("grid"); 3856 3857 addFilterToInitAfter(objFilter, objGrid); 3858 3859 }); 3860 3861 } 3862 3863 3864 /** 3865 * add filter to grid init after array 3866 */ 3867 function addFilterToInitAfter(objFilter, objGrid){ 3868 3869 var role = objFilter.data("role"); 3870 3871 var key = "filters_init_after"; 3872 3873 if(role == "child") 3874 key = "filters_init_after_children"; 3875 3876 objFilter.data("initafter",true); 3877 3878 var arrFiltersInitAfter = objGrid.data(key); 3879 3880 if(!arrFiltersInitAfter) 3881 arrFiltersInitAfter = []; 3882 3883 arrFiltersInitAfter.push(objFilter); 3884 3885 if(g_showDebug == true) 3886 trace("Add init after: "+key+" | "+objFilter.attr("id") ); 3887 3888 objGrid.data(key, arrFiltersInitAfter); 3889 3890 } 3891 3892 /** 3893 * check filters init after 3894 */ 3895 function isSpecialFilterInitAfter(objFilter, objGrid){ 3896 3897 var type = getFilterType(objFilter); 3898 3899 if(type != g_types.PAGINATION) 3900 return(false); 3901 3902 var offsetPagination = objFilter.offset(); 3903 var offsetGrid = objGrid.offset(); 3904 3905 if(offsetPagination.top < offsetGrid.top){ 3906 3907 if(g_showDebug == true) 3908 trace("Set pagination to ajax init"); 3909 3910 return(true); 3911 } 3912 3913 return(false); 3914 } 3915 3916 3917 /** 3918 * init pagination filter 3919 */ 3920 function initFilters(objFilters){ 3921 3922 if(g_showDebug == true){ 3923 3924 trace("init filters"); 3925 3926 if(objFilters.length == 0) 3927 trace("no filters found"); 3928 else 3929 trace(objFilters); 3930 } 3931 3932 var numFilters = objFilters.length; 3933 3934 if(numFilters == 0) 3935 return(false); 3936 3937 var arrTypes = {}; 3938 var arrGeneralTypes = {}; 3939 3940 var objParent = getFiltersParent(objFilters); 3941 3942 jQuery.each(objFilters, function(index, filter){ 3943 3944 var objFilter = jQuery(filter); 3945 var type = getFilterType(objFilter); 3946 3947 //set single filter 3948 if(numFilters === 1){ 3949 objFilter.attr("data-singlefilter",true); 3950 } 3951 3952 initFilter(objFilter, type); 3953 3954 //collect the general type 3955 3956 arrTypes[type] = true; 3957 3958 if(type == g_types.GENERAL){ 3959 var generalType = objFilter.data("generaltype"); 3960 3961 if(!generalType){ 3962 trace(objFilter); 3963 throw new Error("The filter is missing generaltype data"); 3964 } 3965 3966 if(arrGeneralTypes.hasOwnProperty(generalType) == false) 3967 arrGeneralTypes[generalType] = objFilter; 3968 3969 } 3970 3971 objFilter.addClass(g_vars.CLASS_FILTER_INITED); 3972 3973 }); 3974 3975 initFilterEventsByTypes(arrTypes, arrGeneralTypes, objFilters, objParent); 3976 3977 } 3978 3979 3980 /** 3981 * set init state ajax url for each grid (for go back) 3982 */ 3983 function initGrid_setAjaxUrl(objGrid){ 3984 3985 var behave = objGrid.data("filterbehave"); 3986 3987 if(behave != "mixed_back") 3988 return(false); 3989 3990 //get all grid filters 3991 var objFilters = objGrid.data("filters"); 3992 3993 if(!objFilters) 3994 return(false); 3995 3996 if(objFilters.length == 0) 3997 return(false); 3998 3999 var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid,false,false,{getonly:true}); 4000 4001 var ajaxUrlInit = getVal(objAjaxOptions, "ajax_url"); 4002 4003 objGrid.data("initajaxurl", ajaxUrlInit); 4004 4005 } 4006 4007 4008 /** 4009 * set active filters data - for third party connections, active filters and clear button 4010 */ 4011 function initGrid_setActiveFiltersData(objGrid, objAjaxOptions){ 4012 4013 if(!objAjaxOptions) 4014 var objAjaxOptions = getGridAjaxOptions_simple(objGrid); 4015 4016 var arrTerms = getVal(objAjaxOptions, "terms"); 4017 4018 if(jQuery.isArray(arrTerms)) 4019 arrTerms = arrTerms.flat(); 4020 4021 var search = getVal(objAjaxOptions, "search"); 4022 4023 if(search) 4024 search = search.trim(); 4025 4026 if(search){ 4027 var objSearch = { 4028 type:"search", 4029 "key": "search|"+search, 4030 "title": search 4031 }; 4032 4033 if(!arrTerms) 4034 var arrTerms = []; 4035 4036 arrTerms.push(objSearch); 4037 } 4038 4039 objGrid.data("active_filters_items", arrTerms); 4040 objGrid.trigger(g_vars.EVENT_UPDATE_ACTIVE_FILTER_ITEMS, [arrTerms]); 4041 4042 } 4043 4044 4045 /** 4046 * init the grids, ininital filters refresh, 4047 * set active filters, and update initial url's 4048 */ 4049 function initGrids(){ 4050 4051 var objGrids = getAllGrids("loaded_only"); 4052 4053 if(objGrids.length == 0) 4054 return(false); 4055 4056 if(g_showDebug == true){ 4057 trace("init grids"); 4058 trace(objGrids); 4059 } 4060 4061 jQuery.each(objGrids, function(index, grid){ 4062 4063 var objGrid = jQuery(grid); 4064 4065 //--- set go back url if needed 4066 4067 initGrid_setAjaxUrl(objGrid); 4068 4069 initGrid_setInitFiltersAfterLoad(objGrid); 4070 4071 //--- set active filters (for clear and active filters links) 4072 4073 initGrid_setActiveFiltersData(objGrid); 4074 4075 4076 //--- refresh init filters 4077 4078 var objInitFilters = objGrid.data("filters_init_after"); 4079 4080 var isMainFiltersRefreshed = false; 4081 if(objInitFilters && objInitFilters.length > 0){ 4082 4083 isMainFiltersRefreshed = true; 4084 4085 if(g_showDebug == true){ 4086 trace("ajax init Filters"); 4087 trace(objInitFilters); 4088 } 4089 4090 refreshAjaxGrid(objGrid, "filters"); 4091 } 4092 4093 //--- refresh init filters - children 4094 4095 var objInitFiltersChildren = objGrid.data("filters_init_after_children"); 4096 4097 if(objInitFiltersChildren && objInitFiltersChildren.length > 0){ 4098 4099 if(isMainFiltersRefreshed == false){ 4100 4101 if(g_showDebug == true){ 4102 trace("ajax init child Filters"); 4103 trace(objInitFiltersChildren); 4104 } 4105 4106 refreshAjaxGrid(objGrid, "filters_children"); 4107 4108 } 4109 else 4110 objGrid.data("init_refresh_child_filters", true); 4111 } 4112 4113 objGrid.addClass("ucfilters--grid-inited"); 4114 4115 }); 4116 4117 4118 return(objGrids); 4119 } 4120 4121 /** 4122 * init grids events 4123 */ 4124 function initGridsEvents(objGrids){ 4125 4126 //init grids events 4127 4128 if(!objGrids || objGrids.length == 0) 4129 return(false); 4130 4131 4132 //grid several action 4133 4134 objGrids.on(g_vars.ACTION_REFRESH_GRID,function(){ 4135 4136 var objGrid = jQuery(this); 4137 4138 if(g_showDebug == true){ 4139 trace("Refresh grid - by event:" + g_vars.ACTION_REFRESH_GRID); 4140 console.trace(); 4141 } 4142 4143 refreshAjaxGrid(objGrid); 4144 }); 4145 4146 4147 objGrids.on(g_vars.ACTION_GET_FILTERS_URL,function(){ 4148 4149 var objGrid = jQuery(this); 4150 4151 var urlFilters = getGridUrlFiltersString(objGrid); 4152 4153 return(urlFilters); 4154 }); 4155 4156 //clear filters from event 4157 4158 objGrids.on(g_vars.ACTION_CLEAR_FILTERS, function(){ 4159 4160 var objGrid = jQuery(this); 4161 4162 var arrActiveFilterItems = getGridActiveFilterItems(objGrid); 4163 4164 //if already cleared - no need 4165 if(!arrActiveFilterItems) 4166 return(null); 4167 4168 clearAllFilters(objGrid, null, true); 4169 4170 objGrid.trigger(g_vars.ACTION_REFRESH_GRID); 4171 4172 }); 4173 4174 //unselect filter from event 4175 4176 objGrids.on(g_vars.EVENT_UNSELECT_FILTER, function(event, key){ 4177 4178 var objGrid = jQuery(this); 4179 4180 unselectFilterItem(objGrid, key); 4181 4182 objGrid.trigger(g_vars.ACTION_REFRESH_GRID); 4183 }); 4184 4185 } 4186 4187 /** 4188 * init events 4189 */ 4190 function initGeneralEvents(){ 4191 4192 addEventListener('popstate', onPopState); 4193 4194 g_objBody.on(g_vars.EVENT_DOM_UPDATED, runInitFilters); 4195 4196 } 4197 4198 4199 /** 4200 * validate the grids 4201 */ 4202 function validateGrid(objGrid){ 4203 4204 //check for |raw absence 4205 4206 var isAjax = objGrid.data("ajax"); 4207 4208 if(isAjax === "'true'") 4209 showElementError(objGrid, "This grid configured wrong way, missing |raw in html attributes"); 4210 4211 } 4212 4213 4214 /** 4215 * add some validation to the grids 4216 */ 4217 function validateGrids(){ 4218 4219 var objGrids = getAllGrids("loaded_only"); 4220 4221 jQuery.each(objGrids, function(index, grid){ 4222 4223 var objGrid = jQuery(grid); 4224 4225 validateGrid(objGrids); 4226 }); 4227 } 4228 4229 4230 /** 4231 * run init filters 4232 */ 4233 function runInitFilters(){ 4234 4235 validateGrids(); 4236 4237 //get the filters 4238 var objFilters = jQuery(".uc-grid-filter, .uc-filter-pagination").not("." + g_vars.CLASS_FILTER_INITED); 4239 4240 4241 //wait for load... 4242 4243 var objFiltersLoading = objFilters.filter(".uc-waitforload"); 4244 4245 if(objFiltersLoading.length && g_initFiltersCounter < 2){ 4246 4247 if(g_showDebug == true){ 4248 trace(objFiltersLoading);
4249 trace("Wait for Load!"); 4250 } 4251 4252 setTimeout(runInitFilters, 500); 4253 4254 g_initFiltersCounter++; 4255 4256 objFilters = null; 4257 objFiltersLoading = null; 4258 4259 return(false); 4260 } 4261 4262 //init for the next time 4263 g_initFiltersCounter = 0; 4264 4265 initFilters(objFilters); 4266 4267 //init all grids with several stuff like init filters, active modes and url's 4268 var objGrids = initGrids(); 4269 4270 initGridsEvents(objGrids); 4271 4272 } 4273 4274 4275 /** 4276 * init 4277 */ 4278 function init(){ 4279 4280 g_objBody = jQuery("body"); 4281 4282 var success = initGlobals(); 4283 //run again on fail 3 times 4284 if(success == false){ 4285 4286 if(typeof window.ueFiltersTimeoutCounter != "undefined") 4287 window.ueFiltersTimeoutCounter++; 4288 else 4289 window.ueFiltersTimeoutCounter = 0; 4290 4291 if(window.ueFiltersTimeoutCounter == 3){ 4292 trace("Failed to init filters"); 4293 return(false); 4294 } 4295 4296 setTimeout(init, 200); 4297 4298 return(false); 4299 } 4300 4301 //init remote object if exists 4302 if(typeof UERemoteConnection == "function") 4303 g_remote = window.ueRemoteConnection; 4304 4305 runInitFilters(); 4306 4307 initGeneralEvents(); 4308 4309 4310 //run init again on elementor popup 4311 4312 jQuery( document ).on( 'elementor/popup/show', function(event, id, objPopup){ 4313 4314 g_objBody.trigger(g_vars.EVENT_DOM_UPDATED); 4315 4316 }); 4317 4318 4319 } 4320 4321 4322 /** 4323 * is element in viewport 4324 */ 4325 this.isElementInViewport = function(objElement) { 4326 4327 var elementTop = objElement.offset().top; 4328 var elementBottom = elementTop + objElement.outerHeight(); 4329 4330 var viewportTop = jQuery(window).scrollTop(); 4331 var viewportBottom = viewportTop + jQuery(window).height(); 4332 4333 return (elementBottom > viewportTop && elementTop < viewportBottom); 4334 } 4335 4336 /** 4337 * run function with trashold, default is 500 4338 */ 4339 this.runWithTrashold = function(func, trashold){ 4340 4341 if(!trashold) 4342 var trashold = 500; 4343 4344 if(g_vars.trashold_handle) 4345 clearTimeout(g_vars.trashold_handle); 4346 4347 g_vars.trashold_handle = setTimeout(func, trashold); 4348 4349 }; 4350 4351 /** 4352 * get filter element data 4353 */ 4354 this.getFilterElementData = function(objElement){ 4355 4356 var objData = getFilterElementData(objElement); 4357 4358 return(objData); 4359 } 4360 4361 /** 4362 * get filter parent query data 4363 */ 4364 this.getFilterGridQueryData = function(objFilter){ 4365 4366 var objGrid = objFilter.data("grid"); 4367 if(!objGrid) 4368 return(null); 4369 4370 var queryData = objGrid.attr("querydata"); 4371 if(!queryData) 4372 return(null); 4373 4374 var objData = jQuery.parseJSON(queryData); 4375 4376 if(g_showDebug == true){ 4377 console.log("getQueryData (filter, grid, querydata): ",objFilter, objGrid, queryData); 4378 } 4379 4380 return(objData); 4381 } 4382 4383 /** 4384 * get key 4385 */ 4386 this.getFilterItemKey = function(objItem){ 4387 4388 if(!objItem || objItem.length == 0) 4389 return(null); 4390 4391 var key = objItem.data("key"); 4392 4393 if(key) 4394 return(key); 4395 4396 //fallback 4397 4398 key = "term|" + objItem.data("taxonomy") + "|" + objItem.data("slug"); 4399 4400 return(key); 4401 } 4402 4403 4404 /** 4405 * get value 4406 */ 4407 this.getVal = function(obj, name, defaultValue){ 4408 4409 return getVal(obj, name, defaultValue); 4410 } 4411 4412 /** 4413 * get filters by type 4414 * return jquery object 4415 */ 4416 this.getGridFiltersByType = function(objGrid, filterType){ 4417 4418 if(!filterType) 4419 throw new Error("getGridFiltersByType error - enter type as second param"); 4420 4421 var arrFilters = getGridFilters(objGrid); 4422 4423 if(arrFilters.length == 0) 4424 return(jQuery()); 4425 4426 var objChosenFilters = jQuery(); 4427 4428 jQuery.each(arrFilters, function(index, objFilter){ 4429 4430 var type = getFilterType(objFilter, true); 4431 4432 if(type == filterType){ 4433 objChosenFilters = objChosenFilters.add(objFilter); 4434 } 4435 4436 }); 4437 4438 return(objChosenFilters); 4439 } 4440 4441 4442 /** 4443 * init the class 4444 */ 4445 function construct(){ 4446 4447 if(!jQuery){ 4448 trace("Filters not loaded, jQuery not loaded"); 4449 return(false); 4450 } 4451 4452 jQuery("document").ready(function(){ 4453 setTimeout(init, 200); 4454 }); 4455 4456 } 4457 4458 construct(); 4459 4460} 4461 4462g_ucDynamicFilters = new UEDynamicFilters();
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.