PageSourceSearch

https://tanip.ru/wp-content/plugins/unlimited-elements-for-element…/filters/ue_filters.js?ver=1.5.59

js tanip.ru collected 2026-10-07 11:53:06 UTC 61,038 bytes, 2,979 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 g_showDebug = false;
9	
10	var g_types = {
11		PAGINATION:"pagination",
12		LOADMORE:"loadmore",
13		TERMS_LIST:"terms_list",
14		SEARCH: "search",
15		SELECT: "select",
16		SUMMARY: "summary"
17	};
18	
19	var g_vars = {
20		CLASS_DIV_DEBUG:"uc-div-ajax-debug",
21		CLASS_GRID:"uc-filterable-grid",		
22		CLASS_GRID_NOREFRESH:"uc-grid-norefresh",	//grid that will not refresh
23		DEBUG_AJAX_OPTIONS: false,
24		CLASS_CLICKED:"uc-clicked",
25		CLASS_HIDDEN: "uc-filter-hidden",	//don't refresh with this class
26		CLASS_INITING: "uc-filter-initing",
27		CLASS_INITING_HIDDEN: "uc-initing-filter-hidden",
28		CLASS_REFRESH_SOON: "uc-ajax-refresh-soon",
29		EVENT_SET_HTML_ITEMS: "uc_ajax_sethtml",
30		
31		EVENT_BEFORE_REFRESH: "uc_before_ajax_refresh",	   //on grid
32		EVENT_AJAX_REFRESHED: "uc_ajax_refreshed",	   //on grid
33		EVENT_AJAX_REFRESHED_BODY: "uc_ajax_refreshed_body",	   //on grid
34		EVENT_INIT_FILTER:"init_filter",
35		ACTION_REFRESH_GRID: "uc_refresh",	//listen on grid
36		ACTION_GET_FILTERS_URL: "uc_get_filters_url",	//listen on grid
37		
38		REFRESH_MODE_PAGINATION: "pagination",
39		REFRESH_MODE_LOADMORE: "loadmore",
40		trashold_handle:null
41	};
42	
43	var g_options = {
44		is_cache_enabled:true,
45		ajax_reload: false,
46		widget_name: null
47	};
48	
49	
50	/**
51	 * console log some string
52	 */
53	function trace(str){
54		console.log(str);
55	}
56	
57	function ________GENERAL_______________(){}
58	
59		
60	
61	/**
62	 * add url param
63	 */
64	function addUrlParam(url, param, value){
65		
66		if(url.indexOf("?") == -1)
67			url += "?";
68		else
69			url += "&";
70		
71		if(typeof value == "undefined")
72			url += param;
73		else	
74			url += param + "=" + value;
75		
76		return(url);
77	}
78	
79	
80	/**
81	 * get object property
82	 */
83	function getVal(obj, name, defaultValue){
84		
85		if(!defaultValue)
86			var defaultValue = "";
87		
88		var val = "";
89		
90		if(!obj || typeof obj != "object")
91			val = defaultValue;
92		else if(obj.hasOwnProperty(name) == false){
93			val = defaultValue;
94		}else{
95			val = obj[name];			
96		}
97		
98		return(val);
99	}
100	
101	/**
102	 * turn string value ("true", "false") to string 
103	 */
104	function strToBool(str){
105		
106		switch(typeof str){
107			case "boolean":
108				return(str);
109			break;
110			case "undefined":
111				return(false);
112			break;
113			case "number":
114				if(str == 0)
115					return(false);
116				else 
117					return(true);
118			break;
119			case "string":
120				str = str.toLowerCase();
121						
122				if(str == "true" || str == "1")
123					return(true);
124				else
125					return(false);
126				
127			break;
128		}
129		
130		return(false);
131	};
132	
133	/**
134	 * get offsets distance
135	 */
136	function getOffsetsDistance(offset1, offset2){
137	  
138	  var dx = offset2.left-offset1.left;
139	  var dy = offset2.top-offset1.top;
140	  
141	  return Math.sqrt(dx*dx+dy*dy); 
142	}
143	
144	
145	/**
146	 * get closest object by offset
147	 */
148	function getClosestByOffset(objParents, objElement, isVertical){
149		
150		if(objParents.length == 0){
151			throw new Error("get closest by offset error - grids not found");
152		}
153		
154		
155		if(g_showDebug == true){
156			
157			trace("get closest grids for");
158			trace(objElement)
159			trace("parents");
160			trace(objParents);
161		}
162		
163		var objClosest = null;
164		var minDiff = 1000000;
165		
166		var elementOffset = objElement.offset();
167		
168		jQuery.each(objParents, function(index, parent){
169			
170			var objParent = jQuery(parent);
171			
172			var objGrid = jQuery(parent);	//return this one
173			
174			var distance = 0;
175			
176			var isVisible = objParent.is(":visible");
177			
178			var constantHeight = null;
179			
180			if(isVisible == false){
181				objParent = objParent.parent();
182			}
183			
184			var parentOffset = objParent.offset();
185			
186			if(isVertical == true){
187				
188				var offsetY = elementOffset.top;
189				var parentY = parentOffset.top;
190				
191				//get bottom of the parent
192				if(parentY < offsetY)
193					parentY += objParent.height();
194				
195				var distance = Math.abs(offsetY - parentY);
196				
197			}else{
198				
199				var parentOffset = objParent.offset();
200
201				var distance = getOffsetsDistance(parentOffset, elementOffset);
202			}
203			
204			if(g_showDebug == true){
205				
206				trace(objParent);
207				trace("distance: " + distance);
208				
209				trace("is vertical: " + isVertical);
210			}
211			
212			if(distance < minDiff){
213				minDiff = distance;
214				objClosest = objGrid;
215			}
216			
217		});
218		
219		if(g_showDebug == true){
220			
221			trace("filter: ");
222			trace(objElement);
223			
224			trace("Closest grid found:");
225			trace(objClosest);
226		}
227		
228		
229		return(objClosest);
230	}
231	
232	/**
233	 * get all grids
234	 */
235	function getAllGrids(){
236		
237		var objGrids = jQuery("."+ g_vars.CLASS_GRID);
238						
239		return(objGrids);
240	}
241	
242	/**
243	 * get closest grid to some object
244	 */
245	/**
246	 * get closest grid to some object
247	 */
248	function getClosestGrid(objSource){
249		
250		//in case there is only one grid - return it
251		if(g_objGrid)
252			return(g_objGrid);
253		
254		//in case there are nothing:
255		var objGrids = getAllGrids();
256		
257		if(objGrids.length == 0)
258			return(null);
259		
260		if(g_showDebug == true){
261			
262			trace("get closest grids");
263			trace(objSource);
264			trace(objGrids);
265		}
266		
267		//get grid from current section
268		
269		var objSection = objSource.parents("section");
270		
271		var objGrid = objSection.find("."+ g_vars.CLASS_GRID);
272		
273		if(objGrid.length == 1)
274			return(objGrid);
275		
276		//get closest by offset
277		
278		var objSingleGrid = getClosestByOffset(objGrids, objSource, true);
279		
280		if(objSingleGrid && objSingleGrid.length == 1)
281			return(objSingleGrid);		
282		
283		//return first grid in the list
284		
285		var objFirstGrid = jQuery(objGrids[0]);
286		
287		return(objFirstGrid);
288	}
289	
290	
291	
292	/**
293	 * add filter object to grid
294	 */
295	function bindFilterToGrid(objGrid, objFilter){
296		
297		var arrFilters = objGrid.data("filters");
298		var objTypes = objGrid.data("filter_types");
299		
300		if(!arrFilters)
301			arrFilters = [];
302		
303		if(!objTypes)
304			objTypes = {};
305		
306		var type = getFilterType(objFilter);
307		
308		//validate double types
309		
310		if(objTypes.hasOwnProperty(type)){
311			
312			switch(type){
313				case g_types.LOADMORE:
314					
315					trace("Double filter not allowed");					
316					trace("existing Filters:");
317					trace(arrFilters);
318					
319					trace("Second Filter");
320					trace(objFilter);
321					
322					trace("Grid:");
323					trace(objGrid);
324										
325					showElementError(objFilter, "Double load more button for one grid not allowed")
326					return(false);
327				break;
328			}
329			
330		}
331		
332		objTypes[type] = true;
333				
334		arrFilters.push(objFilter);
335		
336		//add init after filters
337		var isInitAfter = objFilter.data("initafter");
338		
339		if(isInitAfter === true){
340			
341			var arrFiltersInitAfter = objGrid.data("filters_init_after");
342			
343			if(!arrFiltersInitAfter)
344				arrFiltersInitAfter = [];
345			
346			arrFiltersInitAfter.push(objFilter);
347			
348			objGrid.data("filters_init_after", arrFiltersInitAfter);
349		}
350		
351		objGrid.data("filters", arrFilters);
352		objGrid.data("filter_types", objTypes);
353		
354		
355	}
356	
357	/**
358	 * 
359	 * get element widget id from parent wrapper
360	 */
361	function getElementWidgetID(objElement){
362		
363		if(!objElement || objElement.length == 0)
364			throw new Error("Element not found");
365		
366		//get widget id
367		
368		var objWidget = objElement.parents(".elementor-widget");
369		
370		if(objWidget.langth == 0)
371			throw new Error("Element parent not found");
372		
373		var widgetID = objWidget.data("id");
374		
375		if(!widgetID)
376			throw new Error("widget id not found");
377		
378		return(widgetID);
379	}
380	
381	/**
382	 * get the grid widget object from elementor element id
383	 */
384	function getGridFromElementorElementID(elementID){
385		
386		var objElement = g_objBody.find(".elementor-widget[data-id='"+elementID+"']");
387		
388		if(objElement.length == 0)
389			return(null);
390		
391		var objGrid = objElement.find("."+g_vars.CLASS_GRID);
392		
393		if(objGrid.length != 1)
394			return(null);
395		
396		return(objGrid);
397	}
398	
399	
400	
401	/**
402	 * get synced widget IDs
403	 */
404	function getSyncedWidgetData(objElement){
405		
406		if(!g_remote)
407			return(false);
408		
409		var arrSyncedGrids = g_remote.getSyncedElements(objElement);
410		
411		if(!arrSyncedGrids)
412			return(false);
413		
414		var arrWidgetIDs = [];
415		
416		var objGrids = null;
417		
418		for(var index in arrSyncedGrids){
419			
420			var objGrid = arrSyncedGrids[index];
421			
422			if(objGrid.hasClass(g_vars.CLASS_GRID) == false){
423				
424				var message = "Please enable ajax on all synced widgets";
425				var message2 = "Please enable ajax on this synced widget";
426				
427				showElementError(objGrid, message2);
428				
429				showAjaxError(message);
430				throw new Error(message);
431				return(false);
432			}
433			
434			var objWidgetID = getElementWidgetID(objGrid);
435			
436			//add to jquery collection
437			
438			if(!objGrids)
439				objGrids = objGrid;
440			else
441				objGrids = objGrids.add(objGrid);
442			
443			arrWidgetIDs.push(objWidgetID);
444		}
445		
446		var strWidgetIDs = arrWidgetIDs.toString();
447		
448		var objOutput = {};
449		objOutput["ids"] = strWidgetIDs;
450		objOutput["grids"] = objGrids;
451		
452		return(objOutput);
453	}
454	
455	
456	/**
457	 * get element layout data
458	 */
459	function getElementLayoutData(objElement, addSyncedGrids){
460		
461		if(!objElement || objElement.length == 0)
462			throw new Error("Element not found");
463		
464		//get widget id
465		
466		var objWidget = objElement.parents(".elementor-widget");
467		
468		if(objWidget.langth == 0)
469			throw new Error("Element parent not found");
470		
471		var widgetID = objWidget.data("id");
472		
473		if(!widgetID)
474			throw new Error("widget id not found");
475		
476		//get synced grids
477		var objSyncedData = null;
478		
479		//add sync if allowed and available
480		
481		if(addSyncedGrids){
482			
483			var objSyncedData = getSyncedWidgetData(objElement);
484			
485			if(g_showDebug && objSyncedData){
486				
487				trace("sync data");
488				trace(objSyncedData);
489			}
490		}else{
491			
492			if(g_showDebug)
493				trace("skip sync grid");
494			
495		}
496
497		
498		//get layout id
499		var objLayout = objWidget.parents(".elementor");
500		
501		if(objLayout.length == 0)
502			throw new Error("layout not found");
503		
504		var layoutID = objLayout.data("elementor-id");
505		
506		var output = {};
507		
508		output["widgetid"] = widgetID;
509		output["layoutid"] = layoutID;
510		
511		if(objSyncedData){
512			output["synced_widgetids"] = objSyncedData["ids"];
513			output["synced_grids"] = objSyncedData["grids"];
514		}
515		
516		return(output);
517	}
518	
519	/**
520	 * show element error above it
521	 */
522	function showElementError(objElement, error){
523		
524		var objParent = objElement.parent();
525		
526		var objError = objParent.find(".uc-filers-error-message");
527		if(objError.length == 0){
528			objParent.append("<div class='uc-filers-error-message' style='color:red;position:absolute;top:-24px;left:0px;'></div>");
529			var objError = objParent.find(".uc-filers-error-message");
530			objParent.css("border","1px solid red !important");
531		}
532		
533		objError.append(error);
534		
535	}
536	
537	/**
538	 * get grid empty message
539	 */
540	function getGridEmptyMessage(objGrid){
541	
542		var gridID = objGrid.attr("id");
543		
544		if(!gridID)
545			return(null);
546		
547		var objEmptyMessage = jQuery("#"+gridID+"_empty_message");
548		
549		if(objEmptyMessage.length == 0)
550			return(null);
551		
552		return(objEmptyMessage);
553	}
554	
555	
556	function ________FILTERS_______________(){}
557	
558	
559	/**
560	 * get filter type
561	 */
562	function getFilterType(objFilter){
563		
564		if(objFilter.hasClass("uc-filter-pagination"))
565			return(g_types.PAGINATION);
566				
567		if(objFilter.hasClass("uc-filter-load-more"))
568			return(g_types.LOADMORE);
569		
570		var filterType = objFilter.data("filtertype")
571		
572		if(filterType)
573			return(filterType);
574		
575		throw new Error("wrong filter type");
576		
577		return(null);
578	}
579	
580	
581	/**
582	 * clear non main grid filters
583	 * hide children and just clear the main filters
584	 */
585	function clearChildFilters(objGrid, objCurrentFilter, isHideChildren, termID){
586		
587		var objFilters = objGrid.data("filters");
588		
589		if(!objFilters)
590			return(false);
591		
592		if(objFilters.length == 0)
593			return(false);
594		
595		var currentFilterID = objCurrentFilter.attr("id");
596				
597		jQuery.each(objFilters, function(index, filter){
598			
599			var objFilter = jQuery(filter);
600			var filterID = objFilter.attr("id");
601			
602			if(filterID == currentFilterID)
603				return(true);
604						
605			var role = objFilter.data("role");
606						
607			if(role != "child" && role != "main" && role != "term_child")
608				return(true);
609			
610			var isHide = false;
611			var isShow = false;
612			
613			switch(role){
614				case "term_child":
615					if(isHideChildren == true)
616						isHide = true;
617						
618					var linkedTermID = objFilter.data("childterm");
619					
620					if(linkedTermID == termID){		//show the filter
621						
622						objFilter.removeClass(g_vars.CLASS_HIDDEN);
623						objFilter.removeClass(g_vars.CLASS_INITING);
624						objFilter.removeClass(g_vars.CLASS_INITING_HIDDEN);
625					}else{
626						isHide = true;
627					}
628						
629				break;
630				case "child":
631					
632					if(isHideChildren == true)
633						isHide = true;
634					else{
635						//hide the filters and refresh
636						
637						objFilter.removeClass(g_vars.CLASS_HIDDEN);
638						
639						objFilter.addClass(g_vars.CLASS_INITING);
640						objFilter.addClass(g_vars.CLASS_INITING_HIDDEN);
641						
642					}
643					
644				break;
645			}
646						
647			//hide the child filters and not refresh
648			
649			if(isHide == true)
650				objFilter.addClass(g_vars.CLASS_HIDDEN);	
651			
652			
653			clearFilter(objFilter);
654						
655		});
656		
657	}
658	
659	/**
660	 * clear some filter
661	 */
662	function clearFilter(objFilter){
663		
664		var type = getFilterType(objFilter);
665		
666		switch(type){
667			case g_types.TERMS_LIST:
668				var objSelectedItems = objFilter.find(".ue_taxonomy_item.uc-selected");
669				objSelectedItems.removeClass("uc-selected");
670				
671				var objAll = objFilter.find(".ue_taxonomy_item.uc-item-all");
672				objAll.addClass("uc-selected");
673			
674			break;
675			case g_types.SELECT:
676				
677				var objSelect = objFilter.find("select");
678				objSelect.val("");
679				
680			break;
681
682		}
683		
684	}
685	
686	function ________PAGINATION_FILTER______(){}
687	
688	
689	/**
690	 * get pagination selected url or null if is current
691	 */
692	function getPaginationSelectedData(objPagination){
693		
694		var objCurrentLink = objPagination.find("a.current");
695		
696		if(objCurrentLink.length == 0)
697			return(null);
698		
699		var url = objCurrentLink.attr("href");
700		
701		if(!url)
702			return(null);
703		
704		var numPage = objCurrentLink.text();
705				
706		if(jQuery.isNumeric(numPage) == false)
707			numPage = null;
708		
709		numPage = Number(numPage);
710		
711		if(numPage === 1)
712			numPage = null;
713		
714		var output = {};
715		output["url"] = url;
716		output["page"] = numPage;
717		
718		return(output);
719	}
720	
721	
722	/**
723	 * on ajax pagination click
724	 */
725	function onAjaxPaginationLinkClick(event){
726		
727		var objLink = jQuery(this);
728		
729		var objPagination = objLink.parents(".uc-filter-pagination");
730				
731		var objLinkCurrent = objPagination.find(".current");
732		
733		
734		//on next button click
735		
736		if(objLink.hasClass("next")){
737			
738			var nextLink = objLinkCurrent.next();
739			
740			var objNextLink = jQuery(nextLink);
741			
742			objNextLink.trigger("click");
743			
744			return(false);
745		}
746
747		
748		//on prev button click
749		
750		if(objLink.hasClass("prev")){
751			
752			var prevLink = objLinkCurrent.prev();
753			
754			var objPrevLink = jQuery(prevLink);
755			
756			objPrevLink.trigger("click");
757			
758			return(false);
759		}
760		
761		objLinkCurrent.removeClass("current");
762		
763		objLink.addClass("current");
764		
765		var objGrid = objPagination.data("grid");
766		
767		if(!objGrid || objGrid.length == 0)
768			throw new Error("Grid not found!");
769		
770		//run the ajax, prevent default
771		event.preventDefault();
772				
773		objPagination.addClass(g_vars.CLASS_CLICKED);
774		
775		refreshAjaxGrid(objGrid, g_vars.REFRESH_MODE_PAGINATION);
776		
777		return(false);
778	}
779
780	
781	function ________LOAD_MORE_______________(){}
782	
783	
784	/**
785	 * get current load more page
786	 */
787	function getLoadMoreUrlData(objFilter){
788		
789		var objData = objFilter.find(".uc-filter-load-more__data");
790		
791		var nextOffset = objData.data("nextoffset");
792		if(!nextOffset)		
793			nextOffset = null;
794				
795		var numItems = objFilter.data("numitems");
796		
797		if(!numItems)
798			numItems = null;
799		
800		//affect only single grids
801		
802		var isSingleGridOnly = objFilter.data("affect_single_grid");
803		
804			
805		var data = {};
806		data.offset = nextOffset;
807		data.numItems = numItems;
808		data.singlegrid = isSingleGridOnly;
809		
810		return(data);
811	}
812	
813	
814	/**
815	 * init load more filter
816	 */
817	function initLoadMoreFilter(objLoadMore){
818		
819		var objData = objFilter.find(".uc-filter-load-more__data");
820		
821		var isMore = objData.data("more");
822		if(isMore !== true)
823			return(false);
824	
825		//check if nessesary
826		objLoadMore.addClass("uc-loadmore-active");
827	}
828	
829	
830	/**
831	 * do the load more operation
832	 */
833	function onLoadMoreClick(){
834		
835		var objLink = jQuery(this);
836		
837		var objLoadMore = objLink.parents(".uc-filter-load-more");
838		
839		var objData = objLoadMore.find(".uc-filter-load-more__data");
840		
841		var isMore = objData.data("more");
842		
843		if(isMore == false)
844			return(false);
845		
846		var objGrid = objLoadMore.data("grid");
847		
848		if(!objGrid || objGrid.length == 0)
849			throw new Error("Grid not found!");
850		
851		//run the ajax, prevent default
852		
853		objLoadMore.addClass(g_vars.CLASS_CLICKED);
854		
855		refreshAjaxGrid(objGrid, g_vars.REFRESH_MODE_LOADMORE);
856		
857	}
858	
859	function ________SELECT_______________(){}
860	
861	/**
862	 * init select filter, select the selected item (avoid cache)
863	 */
864	function initSelectFilter(objFilter){
865				
866		var objSelected = objFilter.find(".uc-selected");
867		
868		if(objSelected.length == 0)
869			return(false);
870		
871		var value = objSelected.attr("value");
872		
873		var objSelect = objFilter.find("select");
874		
875		objSelect.val(value);
876		
877	}
878	
879	
880	function ________TERMS_LIST_______________(){}
881	
882	
883	/**
884	 * on terms list click
885	 */
886	function onTermsLinkClick(event){
887		
888		var className = "uc-selected";
889		
890		event.preventDefault();
891				
892		var objLink = jQuery(this);
893		
894		if(objLink.hasClass("uc-grid-filter")){
895			
896			var objTermsFilter = objLink;
897			
898		}else{
899			
900			var objTermsFilter = objLink.parents(".uc-grid-filter");
901		}
902		
903		var filterType = getFilterType(objTermsFilter);
904		
905		if(filterType == g_types.SELECT){
906			
907			var objLink = objTermsFilter.find("option:selected");
908			
909		}
910		
911		if(filterType == g_types.TERMS_LIST){			
912
913			var objActiveLinks = objLink.siblings("."+className).not(objLink);
914			
915			objActiveLinks.removeClass(className);
916			objLink.addClass(className);
917			
918		}
919		
920		
921		//set not refresh next iteration, because of the clicked
922		setNoRefreshFilter(objTermsFilter);		
923		var objGrid = objTermsFilter.data("grid");
924		
925		if(!objGrid || objGrid.length == 0)
926			throw new Error("Grid not found");
927		
928		//if main filter - clear other filters
929		
930		var filterRole = objTermsFilter.data("role");
931		
932		var termID = objLink.data("id");
933		
934		var isHideChildren = false;
935		if(!termID)
936			isHideChildren = true;
937		
938		if(filterRole == "main")
939			clearChildFilters(objGrid, objTermsFilter, isHideChildren, termID);
940		
941		//refresh grid		
942		refreshAjaxGrid(objGrid);
943		
944	}
945		
946	
947	/**
948	 * get terms list term id
949	 */
950	function getTermsListSelectedTerm(objFilter){
951		
952		if(!objFilter)
953			return(null);
954		
955		var filterType = getFilterType(objFilter);
956		
957		var objSelected = objFilter.find(".uc-selected");
958		
959		if(filterType == g_types.SELECT){
960			
961			var objSelected = objFilter.find("option:selected");
962			
963		}else{
964			
965			var objSelected = objFilter.find(".uc-selected");
966		}
967		
968		if(objSelected.length == 0){
969			
970			if(g_showDebug == true){
971				trace("no selected found, skipping...");
972			}
973			
974			return(null);
975		}
976		
977		//check for hidden
978		
979		if(filterType == g_types.TERMS_LIST && objSelected.is(":hidden")){
980			
981			if(g_showDebug == true){
982				
983				trace("the selected object");
984				trace(objSelected);
985				trace("the term is hidden, skipping...");
986				
987			}
988			
989			return(null);
990		}
991		
992		if(objSelected.length > 1)
993			objSelected = jQuery(objSelected[0]);
994		
995		var id = objSelected.data("id");
996		var slug = objSelected.data("slug");
997		var taxonomy = objSelected.data("taxonomy");
998		
999		if(!taxonomy)
1000			return(null);
1001		
1002		var objTerm = {
1003			"id": id,
1004			"slug": slug,
1005			"taxonomy": taxonomy
1006		};
1007		
1008		return(objTerm);
1009	}
1010
1011	/**
1012	 * select items in terms list by terms
1013	 */
1014	function termListSelectItems(objFilter, arrTerms){
1015		
1016		//deselect
1017		var objSelected = objFilter.find(".uc-selected");
1018		
1019		objSelected.removeClass("uc-selected");
1020		
1021		//select by term
1022		
1023		jQuery.each(arrTerms, function(index, term){
1024			
1025			var termID = getVal(term,"id");
1026			var objItem = objFilter.find("a.ue_taxonomy_item[data-id='"+termID+"']");
1027			
1028			if(objItem.length == 0)
1029				return(true);
1030			
1031			objItem.addClass("uc-selected");
1032		});
1033		
1034		
1035	}
1036	
1037	function ________GENERAL_FILTER_______________(){}
1038	
1039	
1040	/**
1041	 * on general filter change
1042	 */
1043	function onFilterChange(){
1044		
1045		var objFilter = jQuery(this);
1046		
1047		setNoRefreshFilter(objFilter);
1048		
1049		var objGrid = objFilter.data("grid");
1050				
1051		if(!objGrid || objGrid.length == 0){
1052			
1053			trace(objGrid);
1054			
1055			throw new Error("Wrong filter change");
1056			return(false);
1057		}
1058		
1059		
1060		refreshAjaxGrid(objGrid);
1061	}
1062	
1063	
1064	/**
1065	 * select filter items by terms, without refresh, just set selected
1066	 */
1067	function selectFilterItemsByTerms(objFilters, arrTerms){
1068		
1069		if(!objFilters || objFilters.length == 0)
1070			return(false);
1071		
1072		if(!arrTerms || arrTerms.length == 0)
1073			return(false);
1074		
1075		jQuery.each(objFilters,function(index, filter){
1076			
1077			var objFilter = jQuery(filter);
1078			
1079			selectFilterItems(objFilter, arrTerms);
1080			
1081		});
1082				
1083	}
1084	
1085	/**
1086	 * select filter items
1087	 */
1088	function selectFilterItems(objFilter, arrTerms){
1089		
1090		var type = getFilterType(objFilter);
1091		
1092		switch(type){
1093			//case g_types.SELECT:
1094			case g_types.TERMS_LIST:
1095				
1096				termListSelectItems(objFilter, arrTerms);
1097				
1098			break;
1099		}
1100		
1101	}
1102	
1103	function ________INIT_FILTERS_______________(){}
1104	
1105	/**
1106	 * get filter taxonomy id's
1107	 */
1108	function getFilterTaxIDs(objFilter, objIDs){
1109		
1110		var type = getFilterType(objFilter);
1111		
1112		//skip the if
1113		if(type == g_types.SELECT)
1114			var objItems = objFilter.find(".uc-select-filter__option");
1115		else
1116			var objItems = objFilter.find(".ue_taxonomy_item");
1117		
1118		if(objItems.length == 0)
1119			return(objIDs);
1120		
1121		jQuery.each(objItems, function(index, item){
1122			
1123			var objItem = jQuery(item);
1124			var taxID = objItem.data("id");
1125			
1126			if(!taxID)
1127				return(true);
1128			
1129			objIDs[taxID] = true;
1130		});
1131		
1132		
1133		return(objIDs);
1134	}
1135	
1136	/**
1137	 * get tax id's list string from assoc object
1138	 */
1139	function getTermDsList(objIDs){
1140		
1141		var strIDs = "";
1142		for(var id in objIDs){
1143			
1144			if(jQuery.isNumeric(id) == false)
1145				continue;
1146			
1147			if(strIDs)
1148				strIDs += ",";
1149			
1150			strIDs += id;
1151		}
1152		
1153		return(strIDs);
1154	}
1155	
1156	
1157	function ________DATA_______________(){}
1158	
1159	 	
1160	/**
1161	 * build terms query
1162	 * ucterms=product_cat~shoes.dress;cat~123.43;
1163	 */
1164	function buildTermsQuery(arrTerms){
1165		
1166		var query = "";
1167				
1168		//break by taxonomy
1169		var arrTax = {};
1170		jQuery.each(arrTerms, function(index, objTerm){
1171			
1172			var taxonomy = objTerm["taxonomy"];
1173			var slug = objTerm["slug"];
1174			
1175			var objTax = getVal(arrTax, taxonomy);
1176			if(!objTax)
1177				objTax = {};
1178			
1179			objTax[slug] = true;
1180			arrTax[taxonomy] = objTax;
1181			
1182		});
1183		
1184		//combine the query
1185		
1186		if(!arrTax)
1187			return(null);
1188		
1189		jQuery.each(arrTax,function(taxonomy,objSlugs){
1190			
1191			var strSlugs = "";
1192						
1193			var moreThenOne = false;
1194			for (var slug in objSlugs){
1195				
1196				if(strSlugs){
1197					moreThenOne = true;
1198					strSlugs += ".";
1199				}
1200				
1201				strSlugs += slug;
1202			}
1203			
1204			//add "and"
1205			if(moreThenOne == true)
1206				strSlugs += ".*";
1207			
1208			var strTax = taxonomy+"~"+strSlugs;
1209						
1210			if(query)
1211				query += ";";
1212			
1213			query += strTax;
1214			
1215		});
1216				
1217		return(query);
1218	}
1219	
1220	
1221	function ________AJAX_CACHE_________(){}
1222
1223	/**
1224	 * get ajax url
1225	 */
1226	function getAjaxCacheKeyFromUrl(ajaxUrl){
1227		
1228		var key = ajaxUrl;
1229		
1230		key = key.replace(g_urlAjax, "");
1231		key = key.replace(g_urlBase, "");
1232		
1233		//replace special signs
1234		key = replaceAll(key, "/","");
1235		key = replaceAll(key, "?","_");
1236		key = replaceAll(key, "&","_");
1237		key = replaceAll(key, "=","_");
1238		
1239		return(key);
1240	}
1241	
1242	/**
1243	 * get ajax cache key
1244	 */
1245	function getAjaxCacheKey(ajaxUrl, action, objData){
1246		
1247	    if(g_options.is_cache_enabled == false)
1248	    	return(false);
1249	    
1250	    //cache only by url meanwhile
1251	    
1252	    if(jQuery.isEmptyObject(objData) == false)
1253	    	return(false);
1254	    
1255	    if(action)
1256	    	return(false);
1257	    
1258	    var cacheKey = getAjaxCacheKeyFromUrl(ajaxUrl);
1259	    
1260	    if(!cacheKey)
1261	    	return(false);
1262	    
1263	    return(cacheKey);
1264	}
1265	
1266	
1267	/**
1268	 * cache ajax response
1269	 */
1270	function cacheAjaxResponse(ajaxUrl, action, objData, response){
1271		
1272	    var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData);
1273	    
1274	    if(!cacheKey)
1275	    	return(false);
1276	    
1277	    //some precoutions for overload
1278	    if(g_cache.length > 100)
1279	    	return(false);
1280	    
1281	    g_cache[cacheKey] = response;
1282	    
1283	}
1284	
1285		
1286	function ________AJAX_RESPONSE_______________(){}
1287
1288	/**
1289	 * replace the grid debug
1290	 */
1291	function operateAjax_setHtmlDebug(response, objGrid){
1292				
1293		//replace the debug
1294		var htmlDebug = getVal(response, "html_debug");
1295				
1296		if(!htmlDebug)
1297			return(false);
1298		
1299		var gridParent = objGrid.parent();
1300				
1301		var objDebug = objGrid.siblings(".uc-debug-query-wrapper");
1302		
1303		if(objDebug.length == 0)
1304			return(false);
1305				
1306		objDebug.replaceWith(htmlDebug);
1307	}
1308	
1309	
1310	/**
1311	 * set html grid from ajax response
1312	 */
1313	function operateAjax_setHtmlGrid(response, objGrid, isLoadMore){
1314		
1315		if(g_showDebug == true){
1316			trace("set html grid, response: ");
1317			trace(response);
1318			
1319			trace("obj grid:");
1320			trace(objGrid);
1321		}
1322		
1323		if(objGrid.length == 0)
1324			return(false);
1325						
1326		var objItemsWrapper = getGridItemsWrapper(objGrid);
1327		var objItemsWrapper2 = getGridItemsWrapper(objGrid, true);
1328		
1329		if(g_showDebug == true){
1330			trace("items wrapper 1: ");
1331			trace(objItemsWrapper);
1332			
1333			trace("items wrapper 2:");
1334			trace(objItemsWrapper2);
1335		}
1336		
1337		
1338		if(!objItemsWrapper || objItemsWrapper.length == 0)
1339			throw new Error("Missing items wrapper: .uc-items-wrapper");
1340		
1341	
1342		operateAjax_setHtmlDebug(response, objGrid);
1343		
1344		//set grid items
1345		
1346		//if init filters mode, and no items response - don't set
1347		if(response.hasOwnProperty("html_items") == false)
1348			return(false);
1349				
1350		var htmlItems = getVal(response, "html_items");
1351		
1352		var htmlItems2 = null;
1353		
1354		if(objItemsWrapper2)
1355			htmlItems2 = getVal(response, "html_items2"); 
1356		
1357		//replace widget id
1358		var gridID = objGrid.attr("id");
1359		
1360		htmlItems = replaceAll(htmlItems, "%uc_widget_id%", gridID);
1361		
1362		if(htmlItems2)
1363			htmlItems2 = replaceAll(htmlItems2, "%uc_widget_id%", gridID);
1364		
1365		var isCustomRefresh = objGrid.data("custom-sethtml");
1366		
1367		//show / hide empty message if available and empty response
1368		var objEmptyMessage = getGridEmptyMessage(objGrid);
1369				
1370		if(objEmptyMessage){
1371			if(htmlItems == "")
1372				objEmptyMessage.show();
1373			else
1374				objEmptyMessage.hide();				
1375		}
1376		
1377		//set the query data
1378		var queryDataOriginal = getVal(response, "query_data");
1379		var queryIDs = getVal(response,"query_ids");
1380		
1381		var queryData = jQuery.extend({}, queryDataOriginal);
1382		
1383		//add to old data
1384				
1385		if(isLoadMore == true){
1386			
1387			var currentQueryData = objGrid.attr("querydata");
1388			
1389			var objCurrentData = jQuery.parseJSON(currentQueryData);
1390			var currentNumPosts = getVal(objCurrentData, "count_posts");
1391			
1392			queryData.count_posts += currentNumPosts;
1393			
1394			var currentQueryIDs = objGrid.data("postids");
1395			
1396			if(queryIDs && currentQueryIDs)
1397				queryIDs = currentQueryIDs + "," + queryIDs;
1398		}
1399		
1400		//query data replace
1401		
1402		if(queryData){
1403			
1404			objGrid.removeAttr("querydata");
1405			
1406			var jsonData = JSON.stringify(queryData);
1407			objGrid.attr("querydata", jsonData);
1408			
1409			objGrid.data("querydata", queryData);
1410		}
1411		
1412		//post id's replace
1413		
1414		objGrid.removeAttr("data-postids");
1415		objGrid.attr("data-postids", queryIDs);
1416		objGrid.data("postids", queryIDs);
1417		
1418		
1419		//if custom refresh - just save the new html in data
1420		if(isCustomRefresh == true){
1421			
1422			objGrid.trigger(g_vars.EVENT_SET_HTML_ITEMS,[htmlItems, isLoadMore, htmlItems2]);
1423			return(false);
1424		}
1425		
1426		
1427		if(!htmlItems2)
1428			htmlItems2 = "";
1429		
1430		if(isLoadMore === true){
1431			
1432			if(g_showDebug == true){
1433				trace("append load more");
1434			}
1435			
1436			objItemsWrapper.append(htmlItems);
1437			
1438			if(objItemsWrapper)
1439				objItemsWrapper.append(htmlItems2);
1440			
1441		}else{
1442			
1443			objItemsWrapper.html(htmlItems);
1444			
1445			if(objItemsWrapper2 && objItemsWrapper2.length)
1446				objItemsWrapper2.html(htmlItems2);
1447			
1448		}
1449			
1450	}
1451	
1452	
1453	/**
1454	 * refresh synced grids
1455	 */
1456	function operateAjax_setHtmlSyngGrids(response, objGrid, isLoadMore){
1457				
1458		var objSyncWidgetsResponse = getVal(response, "html_sync_widgets");
1459		
1460		if(g_showDebug == true){
1461			trace("set html sync grids");
1462			trace(objSyncWidgetsResponse);
1463		}
1464		
1465		var queryData = getVal(response,"query_data");
1466		
1467		if(!objSyncWidgetsResponse)
1468			return(false);
1469		
1470		jQuery.each(objSyncWidgetsResponse, function(elementID, childResponse){
1471			
1472			var objGridWidget = getGridFromElementorElementID(elementID);
1473			
1474			if(!objGridWidget)
1475				return(true);
1476			
1477			objGridWidget.removeClass(g_vars.CLASS_REFRESH_SOON);
1478			
1479			childResponse.query_data = queryData;
1480			
1481			operateAjax_setHtmlGrid(childResponse, objGridWidget, isLoadMore);
1482						
1483			objGridWidget.trigger(g_vars.EVENT_AJAX_REFRESHED);
1484			g_objBody.trigger(g_vars.EVENT_AJAX_REFRESHED_BODY, [objGridWidget]);
1485						
1486		});
1487		
1488	}
1489	
1490	
1491	/**
1492	 * replace filters html
1493	 */
1494	function operateAjax_setHtmlWidgets(response, objFilters){
1495		
1496		if(!objFilters)
1497			return(false);
1498		
1499		if(objFilters.length == 0)
1500			return(false);
1501		
1502		var objHtmlWidgets = getVal(response, "html_widgets");
1503		
1504		if(!objHtmlWidgets)
1505			return(false);
1506				
1507		if(objHtmlWidgets.length == 0)
1508			return(false);
1509		
1510		var objHtmlDebug = getVal(response, "html_widgets_debug");
1511				
1512		jQuery.each(objFilters, function(index, objFilter){
1513			
1514			var widgetID = getElementWidgetID(objFilter);
1515			
1516			if(!widgetID)
1517				return(true);
1518			
1519			var html = getVal(objHtmlWidgets, widgetID);
1520			
1521			var objHtml = jQuery(html);
1522			
1523			var htmlInner = objHtml.html();
1524			
1525			//set the class
1526			
1527			var filterClassName = objHtml.attr("class");
1528						
1529			objFilter.attr("class", filterClassName);
1530			
1531			objFilter.removeClass(g_vars.CLASS_INITING);
1532			objFilter.removeClass(g_vars.CLASS_REFRESH_SOON);
1533			
1534			objFilter.html(htmlInner);
1535			
1536			
1537			//---- put the debug if exists
1538			
1539			var htmlDebug = null;
1540			
1541			if(objHtmlDebug)
1542				var htmlDebug = getVal(objHtmlDebug, widgetID);
1543			
1544			if(htmlDebug){
1545				var objParent = objFilter.parents(".elementor-widget-container");
1546				var objDebug = objParent.find(".uc-div-ajax-debug");
1547				
1548				if(objDebug.length)
1549					objDebug.replaceWith(htmlDebug);
1550			}
1551			
1552			objFilter.trigger("uc_ajax_reloaded");
1553			
1554		});
1555		
1556	}
1557	
1558	/**
1559	 * scroll to grid top
1560	 */
1561	function scrollToGridTop(objGrid){
1562		
1563		var gapTop = 150;
1564		
1565		var gridOffset = objGrid.offset().top;
1566		
1567		var gridTop = gridOffset - gapTop;
1568		
1569		if(gridTop < 0)
1570			gridTop = 0;
1571		
1572		//check if the grid top is visible
1573		
1574		var currentPos = jQuery(window).scrollTop();
1575		
1576		if(currentPos <= gridOffset)
1577			return(false);
1578		
1579		window.scrollTo({ top: gridTop, behavior: 'smooth' });
1580		
1581	}
1582	
1583	
1584	/**
1585	 * operate the response
1586	 */
1587	function operateAjaxRefreshResponse(response, objGrid, objFilters, isLoadMore, isNoScroll){
1588		
1589		operateAjax_setHtmlGrid(response, objGrid, isLoadMore);
1590		
1591		operateAjax_setHtmlWidgets(response, objFilters);
1592		
1593		operateAjax_setHtmlSyngGrids(response, objGrid, isLoadMore);
1594		
1595		objGrid.trigger(g_vars.EVENT_AJAX_REFRESHED);
1596		g_objBody.trigger(g_vars.EVENT_AJAX_REFRESHED_BODY, [objGrid]);
1597		
1598		//trigger body as well
1599		
1600		//scroll to top
1601		if(isLoadMore == false && isNoScroll !== true){
1602			
1603			setTimeout(function(){
1604				
1605				scrollToGridTop(objGrid);
1606				
1607			},200);
1608			
1609		}
1610				
1611	}
1612	
1613	
1614	/**
1615	 * replace all occurances
1616	 */
1617	function replaceAll(text, from, to){
1618		
1619		return text.split(from).join(to);		
1620	};
1621	
1622	
1623	
1624	
1625	/**
1626	 * get response from ajax cache
1627	 */
1628	function getResponseFromAjaxCache(ajaxUrl, action, objData){
1629	
1630	    var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData);
1631	    
1632	    if(!cacheKey)
1633	    	return(false);
1634		
1635	    var response = getVal(g_cache, cacheKey);
1636	    
1637	    return(response);
1638	}
1639	
1640	
1641	function ________AJAX_______________(){}
1642	
1643	/**
1644	 * set this filter not to refresh next time
1645	 */
1646	function setNoRefreshFilter(objFilter){
1647		
1648		objFilter.data("uc_norefresh",true);
1649		
1650	}
1651	
1652	/**
1653	 * show ajax error, should be something visible
1654	 */
1655	function showAjaxError(message){
1656		
1657		alert(message);
1658		
1659	}
1660	
1661	/**
1662	 * get the debug object
1663	 */
1664	function getDebugObject(){
1665		
1666		var objGrid = g_lastGridAjaxCall;
1667		
1668		if(!objGrid)
1669			return(null);
1670		
1671		var objDebug = objGrid.find("."+g_vars.CLASS_DIV_DEBUG);
1672		
1673		if(objDebug.length)
1674			return(objDebug);
1675		
1676		//insert if not exists
1677		
1678		objGrid.after("<div class='"+g_vars.CLASS_DIV_DEBUG+"' style='padding:10px;display:none;background-color:#D8FCC6'></div>");
1679		
1680		var objDebug = jQuery("body").find("."+g_vars.CLASS_DIV_DEBUG);
1681		
1682		return(objDebug);
1683	}
1684	
1685	
1686	/**
1687	 * show ajax debug
1688	 */
1689	function showAjaxDebug(str){
1690		
1691		trace("Ajax Error! - Check the debug");
1692		
1693		str = jQuery.trim(str);
1694		
1695		if(!str || str.length == 0)
1696			return(false);
1697		
1698		var objStr = jQuery(str);
1699		
1700		if(objStr.find("header").length || objStr.find("body").length){
1701			str = "Wrong ajax response!";
1702		}
1703		
1704		var objDebug = getDebugObject();
1705		
1706		if(!objDebug || objDebug.length == 0){
1707			
1708			alert(str);
1709			
1710			throw new Error("debug not found");
1711		}
1712		
1713		objDebug.show();
1714		objDebug.html(str);
1715		
1716	}
1717	
1718	
1719	/**
1720	 * small ajax request
1721	 */
1722	function ajaxRequest(ajaxUrl, action, objData, onSuccess){
1723		
1724		if(g_showDebug == true){
1725			trace("ajax request");
1726			trace(ajaxUrl);		
1727		}
1728		
1729		if(!objData)
1730			var objData = {};
1731		
1732		if(typeof objData != "object")
1733			throw new Error("wrong ajax param");
1734		
1735		//check response from cache
1736		var responseFromCache = getResponseFromAjaxCache(ajaxUrl, action, objData);
1737		
1738		if(responseFromCache){
1739			
1740			//simulate ajax request
1741			setTimeout(function(){
1742				onSuccess(responseFromCache);
1743			}, 300);
1744			
1745			return(false);
1746		}		
1747		
1748		var ajaxData = {};
1749		ajaxData["action"] = "unlimitedelements_ajax_action";
1750		ajaxData["client_action"] = action;
1751		
1752		var ajaxtype = "get";
1753		
1754		if(jQuery.isEmptyObject(objData) == false){
1755			ajaxData["data"] = objData;
1756			ajaxtype = "post";
1757		}
1758				
1759		
1760		var ajaxOptions = {
1761				type:ajaxtype,
1762				url:ajaxUrl,
1763				success:function(response){
1764					
1765					if(!response){
1766						showAjaxError("Empty ajax response!");
1767						return(false);					
1768					}
1769										
1770					if(typeof response != "object"){
1771						
1772						try{
1773							
1774							response = jQuery.parseJSON(response);
1775							
1776						}catch(e){
1777							
1778							showAjaxDebug(response);
1779							
1780							showAjaxError("Ajax Error!!! not ajax response");
1781							return(false);
1782						}
1783					}
1784					
1785					if(response == -1){
1786						showAjaxError("ajax error!!!");
1787						return(false);
1788					}
1789					
1790					if(response == 0){
1791						showAjaxError("ajax error, action: <b>"+action+"</b> not found");
1792						return(false);
1793					}
1794					
1795					if(response.success == undefined){
1796						showAjaxError("The 'success' param is a must!");
1797						return(false);
1798					}
1799					
1800					
1801					if(response.success == false){
1802						showAjaxError(response.message);
1803						return(false);
1804					}
1805					
1806					cacheAjaxResponse(ajaxUrl, action, objData, response);
1807					
1808					if(typeof onSuccess == "function"){
1809										
1810						onSuccess(response);
1811					}
1812					
1813				},
1814				error:function(jqXHR, textStatus, errorThrown){
1815										
1816					switch(textStatus){
1817						case "parsererror":
1818						case "error":
1819							
1820							//showAjaxError("parse error");
1821							
1822							showAjaxDebug(jqXHR.responseText);
1823							
1824						break;
1825					}
1826				}
1827		}
1828		
1829		if(ajaxtype == "post"){
1830			ajaxOptions.dataType = 'json';
1831			ajaxOptions.data = ajaxData
1832		}
1833		
1834		var handle = jQuery.ajax(ajaxOptions);
1835		
1836		return(handle);
1837	}
1838	
1839	
1840	
1841	/**
1842	 * get grid items wrapper
1843	 */
1844	function getGridItemsWrapper(objGrid, isSecond){
1845		
1846		var classItems = "uc-items-wrapper";
1847		
1848		if(isSecond == true)
1849			classItems = "uc-items-wrapper2";
1850		
1851		if(objGrid.hasClass(classItems))
1852			return(objGrid);
1853		
1854		var objItemsWrapper = objGrid.find("."+classItems);
1855		
1856		if(objItemsWrapper.length == 0 && isSecond == false)
1857			throw new Error("Missing items wrapper - with class: uc-items-wrapper");
1858		
1859		if(objItemsWrapper.length == 0)
1860			return(null);
1861		
1862		return(objItemsWrapper);
1863	}
1864	
1865	
1866	/**
1867	 * set ajax loader
1868	 */
1869	function showAjaxLoader(objElement){
1870		
1871		objElement.addClass("uc-ajax-loading");		
1872	}
1873	
1874	/**
1875	 * hide ajax loader
1876	 */
1877	function hideAjaxLoader(objElement){
1878		
1879		objElement.removeClass("uc-ajax-loading");		
1880	}
1881	
1882	
1883	/**
1884	 * show multiple ajax loader
1885	 */
1886	function showMultipleAjaxLoaders(objElements, isShow){
1887		
1888		if(!objElements)
1889			return(false);
1890		
1891		if(objElements.length == 0)
1892			return(false);
1893		
1894		jQuery.each(objElements,function(index, objElement){
1895			
1896			objElement = jQuery(objElement);
1897			
1898			if(isShow == true){
1899				
1900				showAjaxLoader(objElement);
1901			}
1902			else
1903				hideAjaxLoader(objElement);
1904		});
1905		
1906	}
1907	
1908		
1909	/**
1910	 * refresh ajax grid
1911	 */
1912	function refreshAjaxGrid(objGrid, refreshType){
1913		
1914		var isLoadMore = (refreshType == g_vars.REFRESH_MODE_LOADMORE);	 //for the output
1915		var isFiltersInit = (refreshType == "filters");
1916		
1917		//for the options - not refresh other filters
1918		var isLoadMoreMode = (refreshType == g_vars.REFRESH_MODE_LOADMORE || refreshType == g_vars.REFRESH_MODE_PAGINATION);
1919			
1920		//get all grid filters
1921		var objFilters = objGrid.data("filters");
1922		
1923		if(!objFilters)
1924			return(false);
1925		
1926		if(objFilters.length == 0)
1927			return(false);
1928		
1929		if(objGrid.hasClass(g_vars.CLASS_GRID_NOREFRESH))
1930			return(false);
1931		
1932		var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid, isFiltersInit, isLoadMoreMode);
1933		
1934		if(!objAjaxOptions){
1935			
1936			trace("ajax options are null");
1937			return(false);
1938		}
1939				
1940		var ajaxUrl = objAjaxOptions["ajax_url"];
1941		var urlReplace = objAjaxOptions["url_replace"];
1942		var arrTerms = objAjaxOptions["terms"];
1943		
1944		if(g_vars.DEBUG_AJAX_OPTIONS == true){
1945			
1946			trace("DEBUG AJAX OPTIONS");
1947			trace(objAjaxOptions);
1948			return(false);
1949		}
1950		
1951		//set the url params
1952		var behave = objGrid.data("filterbehave");
1953		
1954		var isSetUrl = (behave == "mixed" || behave == "mixed_back");
1955		
1956		if(isFiltersInit == false && isSetUrl === true){
1957			
1958			if(behave == "mixed_back"){
1959				
1960				//save state for back button
1961				
1962				var gridID = objGrid.attr("id");
1963				
1964				//save initial state
1965				var isStateEmpty = jQuery.isEmptyObject(history.state);
1966								
1967				var objState = {"ucaction":"change", "ajaxurl":ajaxUrl, "gridid":gridID, selected_terms:arrTerms};
1968				
1969				if(isStateEmpty){
1970					
1971					var ajaxUrlInitial = objGrid.data("initajaxurl");
1972					
1973					objState["ajaxurl"] = ajaxUrlInitial;
1974					
1975					history.replaceState(objState, null, urlReplace);
1976				}
1977				
1978				history.pushState(objState, null, urlReplace);		//with back
1979				
1980			}
1981			else
1982				history.replaceState({}, null, urlReplace);		//without back
1983		}
1984		
1985		doGridAjaxRequest(ajaxUrl, objGrid, objFilters, isLoadMore, isFiltersInit);
1986		
1987	}
1988	
1989	
1990	/**
1991	 * do the actual grid ajax request
1992	 */
1993	function doGridAjaxRequest(ajaxUrl, objGrid, objFilters, isLoadMore, isFiltersInit){
1994		
1995		var objEmptyMessage = getGridEmptyMessage(objGrid);
1996		
1997		//set the loaders
1998		
1999		if(isLoadMore !== true && isFiltersInit !== true){
2000			
2001			showAjaxLoader(objGrid);
2002			
2003			if(objEmptyMessage)
2004				showAjaxLoader(objEmptyMessage);
2005		}
2006		
2007		var objFiltersToReload = objFilters.filter(function(objFilter){
2008			
2009			return objFilter.hasClass(g_vars.CLASS_REFRESH_SOON);
2010		});
2011		
2012		showMultipleAjaxLoaders(objFiltersToReload, true);
2013				
2014		if(g_lastSyncGrids && isLoadMore !== true)
2015			showMultipleAjaxLoaders(g_lastSyncGrids, true);
2016		
2017		
2018		//ajax reload
2019		g_lastGridAjaxCall = objGrid;
2020		
2021		objGrid.trigger(g_vars.EVENT_BEFORE_REFRESH);
2022		
2023		var lastAjaxHandle = objGrid.data("last_ajax_refresh_handle");
2024		
2025		if(lastAjaxHandle){
2026			lastAjaxHandle.abort();
2027		}
2028		
2029		var ajaxHandle = ajaxRequest(ajaxUrl,null,null, function(response){
2030			
2031			if(isLoadMore !== true){
2032				hideAjaxLoader(objGrid);
2033				
2034				if(objEmptyMessage)
2035					hideAjaxLoader(objEmptyMessage);
2036			}
2037			
2038			showMultipleAjaxLoaders(objFilters, false);
2039			
2040			if(g_lastSyncGrids)
2041				showMultipleAjaxLoaders(g_lastSyncGrids, false);
2042			
2043			operateAjaxRefreshResponse(response, objGrid, objFilters, isLoadMore);
2044			
2045		});
2046		
2047		objGrid.data("last_ajax_refresh_handle", ajaxHandle);
2048		
2049	}
2050	
2051	function ________STATE_RELATED_______________(){}
2052
2053	
2054	/**
2055	 * do history
2056	 */
2057	function changeToHistoryState(state){
2058		
2059		if(g_showDebug == true){
2060			trace("change to history");
2061			trace(state);
2062		}
2063		
2064		var ajaxUrl = getVal(state, "ajaxurl");
2065		
2066		var gridID = getVal(state, "gridid");
2067		
2068		var arrTerms = getVal(state, "selected_terms");
2069		
2070		if(!gridID)
2071			return(false);
2072		
2073		if(!ajaxUrl)
2074			return(false);
2075
2076		var objGrid = jQuery("#"+gridID);
2077		
2078		var objFilters = objGrid.data("filters");
2079		
2080		if(!objFilters)
2081			return(false);
2082		
2083		//select by terms
2084		
2085		selectFilterItemsByTerms(objFilters, arrTerms);
2086		
2087		var responseFromCache = getResponseFromAjaxCache(ajaxUrl);
2088		
2089		if(!responseFromCache){
2090			
2091			//do ajax request
2092			
2093			doGridAjaxRequest(ajaxUrl, objGrid, objFilters);
2094			
2095			return(false);
2096		}
2097		
2098		//get data from cache
2099		
2100		operateAjaxRefreshResponse(responseFromCache, objGrid, objFilters, false, true);
2101		
2102	}
2103	
2104	/**
2105	 * on pop state, if it's a grid state, set the grid
2106	 */
2107	function onPopState(){
2108		
2109		if(!history.state)
2110			return(true);
2111		
2112		var action = getVal(history.state, "ucaction");
2113		
2114		if(!action)
2115			return(true);
2116		
2117		switch(action){
2118			case "change":
2119				
2120				changeToHistoryState(history.state);
2121				
2122			break;
2123			default:
2124				throw new Error("Wrong history action: " + action);
2125			break;
2126		}
2127		
2128	}
2129	
2130	
2131	function ________RUN_______________(){}
2132	
2133	/**
2134	 * get url filters string
2135	 */
2136	function getGridUrlFiltersString(objGrid){
2137		
2138		var objFilters = objGrid.data("filters");
2139		
2140		if(!objFilters)
2141			return("");
2142		
2143		var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid, false);
2144		
2145		var strFilters = getVal(objAjaxOptions, "filters_string");
2146		
2147		return(strFilters);
2148	}
2149	
2150	
2151	/**
2152	 * get grid ajax options
2153	 */
2154	function getGridAjaxOptions(objFilters, objGrid, isFiltersInitMode, isLoadMoreMode){
2155		
2156		if(!isLoadMoreMode)
2157			var isLoadMoreMode = false;
2158		
2159		if(g_showDebug){
2160			trace("getGridAjaxOptions");
2161						
2162			trace("Filters:");
2163			trace(objFilters);
2164			
2165			trace("grid:");
2166			trace(objGrid);
2167			trace("is init: " + isFiltersInitMode);
2168		}
2169		
2170		
2171		//filter only visible elements (by it's parents)
2172		
2173		var objVisibleFilters = objFilters.filter(function(objFilter){
2174			
2175			var objParent = objFilter.parent();
2176			
2177			return(!objParent.is(":hidden"));
2178		});
2179		
2180		
2181		if(objVisibleFilters.length < objFilters.length){
2182			
2183			var objFilters = objVisibleFilters;
2184			
2185			if(g_showDebug){
2186				trace("Visible Filters: ");
2187				trace(objFilters);
2188				
2189			}
2190		}
2191		
2192		if(!objFilters || objFilters.length == 0)
2193			return(null);
2194				
2195		var urlReplace = g_urlBase;
2196		
2197		var urlAjax = g_urlBase;
2198		
2199		var strRefreshIDs = "";
2200		
2201		var isReplaceMode = false;
2202		var page = null;
2203		var offset = null;
2204		var numItems = null;
2205		var arrTerms = [];
2206		var objTaxIDs = {};
2207		var strSelectedTerms = "";
2208		var search = "";
2209		var addSyncedGrids = true;
2210		
2211		
2212		//get ajax options
2213		jQuery.each(objFilters, function(index, objFilter){
2214			
2215			var isNoRefresh = objFilter.data("uc_norefresh");
2216			
2217			var type = getFilterType(objFilter);
2218			
2219			if(g_showDebug == true){
2220				
2221				trace("filter: "+type);
2222				trace(objFilter);
2223			}
2224			
2225			switch(type){
2226				case g_types.PAGINATION:
2227					
2228					if(isFiltersInitMode == true)
2229						return(true);
2230					
2231					//run pagination only if it's clicked, unless reset pagination
2232					var isClicked = objFilter.hasClass(g_vars.CLASS_CLICKED);
2233					if(isClicked == true){
2234						
2235						 var paginationData = getPaginationSelectedData(objFilter);
2236						 
2237						 var paginationPage = getVal(paginationData, "page"); 
2238						 
2239						 if(paginationPage)
2240							 page = paginationPage;		//never set the url
2241						 
2242						 if(g_showDebug){
2243							 trace("pagination data");
2244							 trace(paginationData);
2245						 }
2246						 
2247						objFilter.removeClass(g_vars.CLASS_CLICKED);
2248					}
2249					
2250				break;
2251				case g_types.LOADMORE:
2252					
2253					if(isFiltersInitMode == true)
2254						return(true);
2255					
2256					//run load more only if it's clicked, unless reset load more
2257					var isClicked = objFilter.hasClass(g_vars.CLASS_CLICKED);
2258					if(isClicked == true){
2259						
2260						var loadMoreData = getLoadMoreUrlData(objFilter);
2261						offset = loadMoreData.offset;
2262						numItems = loadMoreData.numItems;
2263						
2264						var isSingleGrid = loadMoreData.singlegrid;
2265						
2266						if(isSingleGrid == true)
2267							addSyncedGrids = false;
2268												
2269						if(!offset)
2270							urlAjax = null;
2271						
2272						objFilter.removeClass(g_vars.CLASS_CLICKED);
2273					}
2274					
2275				break;
2276				case g_types.TERMS_LIST:
2277				case g_types.SELECT:
2278										
2279					//if not init mode - take first item
2280					var objTerm = getTermsListSelectedTerm(objFilter);
2281					
2282					if(objTerm){
2283						
2284						if(isFiltersInitMode == false)
2285							arrTerms.push(objTerm);
2286						else{
2287							var termID = objTerm.id;
2288							if(strSelectedTerms)
2289								strSelectedTerms +=",";
2290							
2291							strSelectedTerms += termID;
2292						}
2293					}
2294															
2295					//replace mode 
2296					
2297					var modeReplace = objFilter.data("replace-mode");
2298					if(modeReplace === true)
2299						isReplaceMode = true;
2300					
2301					if(isLoadMoreMode == true)
2302						isNoRefresh = true;
2303					
2304					//debug
2305					if(g_showDebug == true){
2306						
2307						trace("Selected Term: ");
2308						trace(objTerm);
2309					}
2310					
2311				break;
2312				case g_types.SUMMARY:
2313					
2314					isNoRefresh = true;
2315					
2316					//take nothing
2317				break;
2318				case g_types.SEARCH:
2319					
2320					isNoRefresh = true;
2321					
2322					var objInput = objFilter.find("input");
2323					
2324					search = objInput.val();
2325					search = search.trim();
2326					
2327				break;
2328				default:
2329					throw new Error("Unknown filter type: "+type);
2330				break;
2331			}
2332			
2333			//handle filters init mode
2334			
2335			if(isFiltersInitMode == true){
2336				
2337				var isInit = objFilter.data("initafter");
2338				
2339				if(isInit == false)
2340					isNoRefresh = true;
2341			}
2342			
2343			//if hidden - no refresh
2344			var isFilterHidden = objFilter.hasClass(g_vars.CLASS_HIDDEN);
2345			if(isFilterHidden == true)
2346				isNoRefresh = true;
2347			
2348			objFilter.data("uc_norefresh",false);
2349			
2350			var filterRole = objFilter.data("role");
2351			
2352			var isMainFilter = (filterRole == "main");
2353			var isTermChild = (filterRole == "term_child");
2354			
2355			//add to refresh filter if it's qualify
2356			
2357			var isRefresh = true;
2358			
2359			if(isFiltersInitMode == false && (isMainFilter === true || isTermChild == true))
2360				isRefresh = false;
2361			
2362			if(isNoRefresh === true)
2363				isRefresh = false;
2364			
2365			if(isRefresh == true){
2366				
2367				var filterWidgetID = getElementWidgetID(objFilter);
2368				
2369				//add test tax id's for init mode
2370				objTaxIDs = getFilterTaxIDs(objFilter, objTaxIDs);
2371				
2372				if(strRefreshIDs)
2373					strRefreshIDs += ",";
2374				
2375				strRefreshIDs += filterWidgetID;
2376				
2377				objFilter.addClass(g_vars.CLASS_REFRESH_SOON);
2378			}
2379					
2380			
2381		});		//end filters iteration
2382		
2383		
2384		//add init filters additions
2385		
2386		var urlAddition_filtersTest = "";
2387		var strTaxIDs = getTermDsList(objTaxIDs);
2388		
2389		if(isFiltersInitMode == true){
2390		
2391			if(!strTaxIDs)
2392				urlAjax = null;
2393			else{
2394				
2395				if(urlAddition_filtersTest)
2396					urlAddition_filtersTest += "&";
2397				
2398				urlAddition_filtersTest += "modeinit=true";
2399			}
2400		}
2401		
2402		if(strTaxIDs){
2403			if(urlAddition_filtersTest)
2404				urlAddition_filtersTest += "&";
2405			
2406			urlAddition_filtersTest += "testtermids="+strTaxIDs;
2407		}
2408		
2409		g_lastSyncGrids = null;
2410		
2411		if(urlAjax == null)
2412			return(null);
2413		
2414		var dataLayout = getElementLayoutData(objGrid, addSyncedGrids);
2415		
2416		var widgetID = dataLayout["widgetid"];
2417		var layoutID = dataLayout["layoutid"];
2418		
2419		//disable synced
2420		
2421		if(addSyncedGrids == false){
2422			
2423			var syncedWidgetIDs = false;
2424			g_lastSyncGrids = null;
2425			
2426		}else{
2427			
2428			var syncedWidgetIDs = getVal(dataLayout,"synced_widgetids");
2429			g_lastSyncGrids = getVal(dataLayout,"synced_grids");
2430		}
2431		
2432		
2433		var urlFilterString = "";
2434		
2435		var urlAddition = "ucfrontajaxaction=getfiltersdata&layoutid="+layoutID+"&elid="+widgetID;
2436		
2437		urlAjax = addUrlParam(urlAjax, urlAddition);
2438		
2439		if(syncedWidgetIDs)
2440			urlAjax += "&syncelids="+syncedWidgetIDs;
2441		
2442		if(urlAddition_filtersTest)
2443			urlAjax = addUrlParam(urlAjax, urlAddition_filtersTest);
2444		
2445		if(page){
2446			urlAjax += "&ucpage="+page;
2447			
2448			urlReplace = addUrlParam(urlReplace, "ucpage="+page);
2449		}
2450				
2451		if(numItems)
2452			urlAjax += "&uccount="+numItems;
2453		
2454		if(arrTerms.length){
2455			
2456			var strTerms = buildTermsQuery(arrTerms);
2457			if(strTerms)
2458				urlAjax += "&ucterms="+strTerms;
2459			
2460			//set the url params as well
2461			
2462			urlReplace = addUrlParam(urlReplace, "ucterms="+strTerms);
2463			
2464			urlFilterString = addUrlParam(urlFilterString, "ucterms="+strTerms);
2465		}
2466		
2467		if(isFiltersInitMode && strSelectedTerms)
2468			urlAjax += "&ucinitselectedterms="+strSelectedTerms;
2469		
2470		//add refresh ids
2471		if(strRefreshIDs)
2472			urlAjax += "&addelids="+strRefreshIDs;
2473		
2474		if(isReplaceMode == true)
2475			urlAjax += "&ucreplace=1";
2476		
2477		//search
2478		if(search){
2479			search = encodeURIComponent(search);
2480			//search = escape(search);
2481			urlAjax += "&ucs=" + search;
2482			
2483			urlFilterString = addUrlParam(urlFilterString, "ucs=" + search);
2484		}
2485		
2486		//avoid duplicates - exclude, disable the offset
2487		
2488		if(objGrid.hasClass("uc-avoid-duplicates") && isLoadMoreMode == true){
2489			
2490			var strExcludePostIDs = getExcludePostIDs();
2491			
2492			if(strExcludePostIDs){
2493				urlAjax += "&ucexclude="+strExcludePostIDs;
2494				offset = null;
2495				
2496				urlFilterString = addUrlParam(urlFilterString, "ucexclude=" + strExcludePostIDs);
2497			}
2498			
2499		}
2500		
2501		if(offset){
2502			urlAjax += "&ucoffset="+offset;
2503			
2504			urlFilterString = addUrlParam(urlFilterString, "offset=" + offset);
2505		}
2506		
2507		//remove the "?" from first
2508		if(urlFilterString)
2509			urlFilterString = urlFilterString.substring(1);
2510		
2511		
2512		var output = {};
2513		output["ajax_url"] = urlAjax;
2514		output["url_replace"] = urlReplace;
2515		output["terms"] = arrTerms;
2516		output["filters_string"] = urlFilterString;
2517		
2518		return(output);
2519	}
2520	
2521	
2522	/**
2523	 * get all exclude post ids from all avoid duplicates grids
2524	 */
2525	function getExcludePostIDs(){
2526		
2527		var objGrids = jQuery(".uc-avoid-duplicates");
2528				
2529		var strIDs = "";
2530		
2531		jQuery.each(objGrids, function(index, grid){
2532			var objGrid = jQuery(grid);
2533			
2534			var postIDs = objGrid.data("postids");
2535			
2536			if(!postIDs)
2537				return(true);
2538			
2539			if(strIDs)
2540				strIDs += ",";
2541			
2542			strIDs += postIDs;
2543		});
2544		
2545		
2546		return(strIDs);
2547	}
2548	
2549	
2550	function ________INIT_______________(){}
2551	
2552		
2553	/**
2554	 * init listing object
2555	 */
2556	function initGridObject(){
2557		
2558		//init the listing
2559		g_objGrid = jQuery("."+ g_vars.CLASS_GRID);
2560		
2561		if(g_objGrid.length == 0){
2562			g_objGrid = null;
2563			return(false);
2564		}
2565		
2566		//set only available grid
2567		if(g_objGrid.length > 1){
2568			g_objGrid = null;
2569		}
2570		
2571	}
2572	
2573		
2574	
2575	/**
2576	 * init the globals
2577	 */
2578	function initGlobals(){
2579		
2580		if(typeof g_strFiltersData === "undefined")
2581			return(false);
2582		
2583		g_filtersData = JSON.parse(g_strFiltersData);
2584		
2585		if(jQuery.isEmptyObject(g_filtersData)){
2586			
2587			trace("filters error - filters data not found");
2588			return(false);
2589		}
2590		
2591		g_urlBase = getVal(g_filtersData, "urlbase");
2592		g_urlAjax = getVal(g_filtersData, "urlajax");
2593		
2594		var isShowDebug = getVal(g_filtersData, "debug");
2595		
2596		if(isShowDebug == true)
2597			g_showDebug = true;
2598
2599		if(g_showDebug == true)
2600			trace("Show Filters Debug");
2601			
2602		
2603		if(!g_urlBase){
2604			trace("ue filters error - base url not inited");
2605			return(false);
2606		}
2607
2608		if(!g_urlAjax){
2609			trace("ue filters error - ajax url not inited");
2610			return(false);
2611		}
2612		
2613		return(true);
2614	}
2615	
2616	
2617	/**
2618	 * init filter and bing to grid
2619	 */
2620	function initFilter(objFilter, type){
2621		
2622		var objGrid = getClosestGrid(objFilter);
2623		
2624		var error = "Filter Parent not found! Please put the posts element on the page, and turn on 'Enable Post Filtering' option on it";
2625		
2626		if(!objGrid){			
2627			showElementError(objFilter, error);
2628			return(null);
2629		}
2630		
2631		var isAjax = objGrid.data("ajax");
2632		
2633		if(isAjax == false){
2634			showElementError(objFilter, error);
2635			return(false);
2636		}
2637		
2638		//bind grid to filter
2639		objFilter.data("grid", objGrid);
2640				
2641		//bind filter to grid
2642		bindFilterToGrid(objGrid, objFilter);
2643		
2644		
2645		switch(type){
2646			case g_types.SELECT:
2647				initSelectFilter(objFilter);
2648			break;
2649		}
2650		
2651		objFilter.trigger(g_vars.EVENT_INIT_FILTER);
2652		
2653	}
2654	
2655	
2656	/**
2657	 * init filter events by types
2658	 */
2659	function initFilterEventsByTypes(arrTypes, objFilters){
2660		
2661		if(!arrTypes || arrTypes.length == 0)
2662			return(false);
2663		
2664		//init the events
2665		var objParent = objFilters.parents(".elementor");
2666		
2667		if(objParent.length > 1)
2668			objParent = jQuery(objParent[0]);
2669		
2670		for(var type in arrTypes){
2671						
2672			switch(type){
2673				case g_types.PAGINATION:
2674					
2675					objParent.on("click",".uc-filter-pagination a", onAjaxPaginationLinkClick);
2676					
2677				break;
2678				case g_types.LOADMORE:
2679					
2680					//load more
2681					objParent.on("click",".uc-filter-load-more__link", onLoadMoreClick);
2682				break;
2683				case g_types.TERMS_LIST:
2684					
2685					objParent.on("click",".ue_taxonomy.uc-grid-filter a.ue_taxonomy_item", onTermsLinkClick);
2686					
2687				break;
2688				case g_types.SEARCH:
2689					
2690					//do nothing for init
2691					
2692				break;
2693				case g_types.SELECT:
2694					
2695					objParent.on("change", ".uc-select-filter__select", onTermsLinkClick);
2696					
2697				break;
2698				case g_types.SUMMARY:
2699					
2700					//do nothing for now
2701					
2702				break;
2703				default:
2704					trace("init by type - unrecognized type: "+type);
2705				break;
2706			}
2707		}
2708				
2709	}
2710	
2711	
2712	/**
2713	 * init pagination filter
2714	 */
2715	function initFilters(){
2716		
2717		var objFilters = jQuery(".uc-grid-filter,.uc-filter-pagination");
2718		
2719		if(g_showDebug == true){
2720			
2721			trace("init filters");
2722			
2723			if(objFilters.length == 0)
2724				trace("no filters found");
2725			else
2726				trace(objFilters);
2727		}
2728		
2729		if(objFilters.length == 0)
2730			return(false);
2731		
2732		var arrTypes = {};
2733		
2734		jQuery.each(objFilters, function(index, filter){
2735			
2736			var objFilter = jQuery(filter);
2737			var type = getFilterType(objFilter);
2738			
2739			initFilter(objFilter, type);
2740						
2741			arrTypes[type] = true;
2742			
2743		});
2744		
2745		
2746		initFilterEventsByTypes(arrTypes, objFilters);
2747		
2748	}
2749	
2750	
2751	/**
2752	 * check and call ajax init filters
2753	 */
2754	function ajaxInitFilters(){
2755		
2756		var objGrids = getAllGrids();
2757		
2758		if(objGrids.length == 0)
2759			return(false);
2760						
2761		jQuery.each(objGrids, function(index, grid){
2762			
2763			var objGrid = jQuery(grid);
2764			
2765			var objInitFilters = objGrid.data("filters_init_after");
2766						
2767			if(!objInitFilters || objInitFilters.length == 0)
2768				return(true);
2769			
2770			refreshAjaxGrid(objGrid, "filters");
2771			
2772		});
2773				
2774		
2775	}
2776	
2777	
2778	
2779	
2780	/**
2781	 * init events
2782	 */
2783	function initEvents(){
2784		
2785		addEventListener('popstate', onPopState);
2786		
2787		//init grids events
2788		
2789		var objGrids = jQuery("."+ g_vars.CLASS_GRID);
2790		
2791		if(objGrids.length == 0)
2792			return(false);
2793		
2794		
2795		//grid several action
2796		
2797		objGrids.on(g_vars.ACTION_REFRESH_GRID,function(){
2798			
2799			var objGrid = jQuery(this);
2800			refreshAjaxGrid(objGrid);
2801		});
2802		
2803		
2804		
2805		objGrids.on(g_vars.ACTION_GET_FILTERS_URL,function(){
2806			
2807			var objGrid = jQuery(this);
2808			
2809			var urlFilters = getGridUrlFiltersString(objGrid);
2810			
2811			return(urlFilters);
2812		});
2813		
2814		
2815	}
2816	
2817	
2818	
2819	/**
2820	 * set init state ajax url for each grid (for go back)
2821	 */
2822	function initOriginGridAjaxUrls(){
2823		
2824		var objGrids = getAllGrids();
2825		
2826		jQuery.each(objGrids, function(index, grid){
2827			
2828			var objGrid = jQuery(grid);
2829			
2830			var behave = objGrid.data("filterbehave");
2831						
2832			if(behave != "mixed_back")
2833				return(true);
2834			
2835			//get all grid filters
2836			var objFilters = objGrid.data("filters");
2837			
2838			if(!objFilters)
2839				return(false);
2840			
2841			if(objFilters.length == 0)
2842				return(false);
2843			
2844			var objAjaxOptions = getGridAjaxOptions(objFilters, objGrid);
2845			
2846			var ajaxUrlInit = getVal(objAjaxOptions, "ajax_url");
2847			
2848			objGrid.data("initajaxurl", ajaxUrlInit);
2849			
2850		});
2851		
2852		
2853	}
2854
2855	/**
2856	 * validate the grids
2857	 */
2858	function validateGrid(objGrid){
2859		
2860		//check for |raw absence
2861		
2862		var isAjax = objGrid.data("ajax");
2863		
2864		if(isAjax === "'true'")
2865			showElementError(objGrid, "This grid configured wrong way, missing |raw in html attributes");
2866		
2867	}
2868	
2869	
2870	/**
2871	 * add some validation to the grids
2872	 */
2873	function validateGrids(){
2874		
2875		var objGrids = getAllGrids();
2876		
2877		jQuery.each(objGrids, function(index, grid){
2878			
2879			var objGrid = jQuery(grid);
2880			
2881			validateGrid(objGrids);
2882		});
2883	}
2884	
2885	
2886	/**
2887	 * init
2888	 */
2889	function init(){
2890		
2891		g_objBody = jQuery("body");
2892		
2893		var success = initGlobals();
2894		
2895		//run again on fail 3 times
2896		if(success == false){
2897			
2898			if(typeof window.ueFiltersTimeoutCounter != "undefined")
2899					window.ueFiltersTimeoutCounter++;
2900			else
2901				window.ueFiltersTimeoutCounter = 0;
2902			
2903			if(window.ueFiltersTimeoutCounter == 3){
2904				trace("Failed to init filters");
2905				return(false);
2906			}
2907			
2908			setTimeout(init, 200);
2909			
2910			return(false);
2911		}
2912		
2913		//init remote object if exists
2914		if(typeof UERemoteConnection == "function")
2915			g_remote = window.ueRemoteConnection;
2916		
2917		validateGrids();
2918		
2919		//init the single grid object
2920		initGridObject();
2921		
2922		initFilters();
2923		
2924		ajaxInitFilters();
2925		
2926		//set initial ajax url
2927		initOriginGridAjaxUrls();
2928		
2929		initEvents();
2930		
2931	}
2932	
2933	
2934	/**
2935	 * is element in viewport
2936	 */
2937	this.isElementInViewport = function(objElement) {
2938		  
2939		  var elementTop = objElement.offset().top;
2940		  var elementBottom = elementTop + objElement.outerHeight();
2941
2942		  var viewportTop = jQuery(window).scrollTop();
2943		  var viewportBottom = viewportTop + jQuery(window).height();
2944
2945		  return (elementBottom > viewportTop && elementTop < viewportBottom);
2946	}
2947	
2948	/**
2949	 * run function with trashold
2950	 */
2951	this.runWithTrashold = function(func, trashold){
2952		
2953		if(g_vars.trashold_handle)
2954			clearTimeout(g_vars.trashold_handle);
2955		
2956		g_vars.trashold_handle = setTimeout(func, trashold);
2957		
2958	};
2959	
2960	
2961	/**
2962	 * init the class
2963	 */
2964	function construct(){
2965		
2966		if(!jQuery){
2967			trace("Filters not loaded, jQuery not loaded");
2968			return(false);
2969		}
2970		
2971		jQuery("document").ready(init);
2972		
2973	}
2974	
2975	construct();
2976}
2977
2978g_ucDynamicFilters = new UEDynamicFilters();
2979

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.