PageSourceSearch

https://gosafersecurity.com/wp-content/plugins/unlimited-elements-…/filters/ue_filters.js?ver=1.5.99

js gosafersecurity.com collected 2026-10-04 13:33:54 UTC 85,358 bytes, 4,073 lines download raw bytes

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

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.