PageSourceSearch

https://www.tuli.sk/includes/js/shop/ProductFilter.js?535967

js tuli.sk collected 2026-09-24 13:07:31 UTC 142,468 bytes, 4,876 lines download raw bytes

1/**
2 * Creativesites s.r.o
3 * @package BrowseFilter
4 *
5 * Pouzivane externe funkcie:
6 * - js_format_Money()
7 * - csstack()
8 * -
9 */
10var sphf = {
11	version: '2.9',									// Verzia scriptu
12	debug: false,									// Debug spravy viditelne v konzole
13	initialized: 0,									// Flag nastaveny na 1 ak filter bezi a bol inicializovany
14	csuser: 0,										// Cs user je aktivny
15	atempts: 0,										// Ak ajax zlyha pokusime sa akciu opakovat max este 1 krat
16	manager: false,									// True ak je aktivne manager prostredie
17	backend: false,									// True ak sme v backende / obsahu
18	obj: {},										// Rozne nacachovane objekty
19	elems: {},										// Nacachovane objekty
20	data: {},										// Udaje o skupine vo filtry
21	groups: {},										// Nastavenie pre kazdu skupinu zvlast
22	forced: {},										// Pole s custom shopovskymi filtrami
23	stats: {},										// Statistiky vratene v odpovedi zo servera
24	meta: {},										// Meta udaje vratene v odpovedi zo servera ako total,...
25	active: {},										// Aktualne zvolene hodnoty filtra
26	base: {},										// Pole s default facetmi pre neaktivny filter
27	facets: {},										// Pole s vypocitanymi facetmi
28	prices: {},										// Pole s udajmi pre aktualnu menu
29	cid: 0,											// Aktualne ID kategorie, musi byt inak filter nefunguje
30	mid: 0,											// ID modulu kde su uchovane nastavenia filtra
31	cache: 1,										// Cachovanie stromu a dat je zapnute
32	simple_paging: 0,								// Je aktivovany simple paging request
33	scrwidth: 0,									// Vypocitana Sirka scrollbaru
34	itmwidth: 0,									// Aktualna sirka boxu poloziek
35	resbtntop: 0,									// poloha tlacidla zobrazit vysledky
36	wheight: 0,										// Aktualna vyska okna
37	timeout: {},									// Objekty z funkcie setTimeout()
38	timing: {},										// JS meranie casu pre renderovanie stromu
39	quirk: true,									// Quirk mod pre stare browsre, nepodporujuce niektore html5 funkcie
40	editwrap: {},									// Vsetky elementy v modal okne pre editaciu
41	sortbox: {},									// Element obsahujuci hodnoty pre sortovanie
42	urlfilter: '',									// Toto je naplnene v quirk mode pri inicializacii filtra
43	touchdevice: false,								// True ak mame touch device
44	pingcode: '',									// Kontrolny ping pre requesti, podla ktoreho urcujeme aktivnu cache
45	cached: false,									// Flag nastaveny na true ak vysledky pochadzaju z cache
46	scales: {},										// Aktualne nastavene hodnoty pre adaptivny slider
47	orig_state: {},                                 // original nastavenie prostredia pri prvom nacitani stranky
48	pinginterval: 0,                                // Setnute interval ID ak bezi
49	ordering: {},                                   // Data s poradim skupin a hodnot vo filtri
50	sorter: {},                                     // presne sortnute aktivne polozky v poradi v akom sa nachadzaju vo filtri
51	attribs: [],                                    // Atributy elementov ktore sa dynamicky pridavaju na document ready
52	guide: [],                                      // Data pouzivane sprievodcom produktov
53	adfilter_btn: [],                               // Tlacidlo pre filter administracie
54	keywords: {},                                   // Data aktivnych skupin filtra
55	flags: {                                        // Rozne flagy pre kod
56		orderby_change: false
57	},
58	config: {                                       // Niektore shopovske configy s ktorymi pracuje funkcia
59		sitename: '',                               // Aktualny sitename zohladnujuci aktualnu cudzojazycnu domenu
60		sitename_divider: '-',  	                // Oddelovac v <title>
61		sitename_style: 0,                          // Styl zobrazenia premennych v <title> 0=sitename|page, 1=page|sitename
62		simple_orderby_fields_type: false,          // Jednoduche strankovanie
63		browse_default_orderby: [],
64		adjust_scroll: false
65	},
66	setting: {                                      // Nastavenia globalne pre rodiny skupin filtra
67		render_type: 0,                             // Typ renderovania poloziek do filtra 0=staticke html, 1=dynamicke js
68		group_open_on: 2,                           // Na aky event sa otvori skupina vo filtri 0=u
68ser script, 1=click, 2=hover
69		onclick_out: 0,                             // Zatvaranie skupiny pri muoseleave. 0=ziadna akcia, 1= zavriet skupinu. Iba pre typ click.
70		onclick_close: 1,                           // Pri otvorenej ponuke, sa po kliknuti na nazov skupiny ponuka zatvori
71		sorttype: 0,                                // Html typ vyberu sortovania na stranke, 0=select, 1=buttons. V pripade buttons sa zo selectu vyrobia tlacidla
72		group_active: 1,                            // Ak 1 aktivne polozky sa budu zlucovat do jednej skupiny
73		factim: 'append',                           // JQuery metoda pre vlozenie zoznamu aktivnych poloziek filtra
74		max_height: 200,                            // Maximalna vyska okna s polozkami skupiny
75		scrollspeed: 1000,                          // Rychlost scrolovania stranky
76		show_total: 0,                              // Zobrazit celkovy pocet produktov v kategorii
77		load_type: 1,                               // Typ loadnutia produktov po zmene filtra 0-tlacidlo ukaz vysledky, 1-automaticky
78		load_delay: 0,                              // Oneskorenie ajaxu v ms pri volani na shop browse
79		show_results: 1,                            // Povolenie zobrazenia tlacidla Ukazat vysledky, 0=vypnute, 1=ukazat pod filtrom, 2=ukazat nad filtrom
80		selected_def: 0                             // Zobrazit default tag v kazdej skupine ktora nema nic zvolene
81	},
82	seo: {                                          // Nastavenie seo
83		seo_url: 0,                                 // Shop ma povolene vytvarat SEO url adresy dynamicky podla filtra
84		change_title: 0,                            // Shop ma povolene menit <title> v <head> dynamicky podla filtra
85		change_h1: 0,                               // Shop ma povolene menit <h1> tag dynamicky podla filtra
86		group_append: 0,                            // Do SEO klucovych slov sa ma pridavat nazov skupiny alebo nie
87		pholder_title: 0,                           // Placeholder pre SEO parametre v <title>
88		value_links: 0,                             // Povolenie generovania <a> ku kazdemu parametru vo filtri
89		group_select: [],                           // Skupiny ktore su povolene pre vytvaranie SEO klucovych slov
90		dvd_gr_gr: '',                              // Oddelovac medzi skupinami
91		dvd_gr_vl: '',                              // Oddelovac skupina - hodnota
92		dvd_vl_vl: '',                              // Oddelovac medzi hodnotami
93		dvd_title: '|',                             // Oddelovac medzi slovami v <title>
94		dvd_h1: '-',                                // Oddelovac medzi slovami v <h1>
95		page: {
96			title_orig: '',
97			title_clean: '',
98			h1_orig: '',
99			h1_clean: ''
100		}
101	},
102	url: {											// Rozparsovana aktualna url
103		clean: '',
104		replace: '',
105		search: '',
106		hash: '',
107		seo: ''
108	},
109	events: {},
110	order_list: {},
111	last_list_cat: {
112		enabled: false
113	},
114	order_list_desc: ['l','z','cd','pd','nd','pr','kd','td','bd'],
115	order_list_asc: ['pa','na','ca','ka','ta','ba'],
116	uoms: [],
117	langs: {											// Osetrene preklady
118		all: 'All',
119		from: 'from',
120		filter: 'Filter',
121		more_results: 'More',
122		less_results: 'Less',
123		filter_active: 'You have active filter:',
124		filtering: 'Filtering...',
125		remove_all_filters: 'Remove all filters',
126		no_results: 'No results',
127		show: 'Show',
128		found1: 'Found',
129		found2: 'Found',
130		found3: 'Found',
131		result_1: 'result',
132		result_2: 'results',
133		result_3: 'results',
134		total_1: 'There is {total} product in this category',
135		total_2: 'There are {total} products in this category',
136		total_3: 'There are {total} products in this category',
137		pag_next1: 'Display next ',
138		pag_next2: 'Display next ',
139		pag_next3: 'Display next ',
140		pag_last1: 'Display last ',
141		pag_last2: 'Display last ',
142		pag_last3: 'Display last ',
143		set_group: 'Click to change settings for this group.',
144		has_setting: 'Filter group has own specific setting',
145		remove_group: 'Click to change settings for this group.',
146		remove_value: 'Click to change settings for this group.',
147		activ_no_res: 'Parameter is not available in the displayed results',
148		net_err: 'There is a problem with the network, please refresh the page.',
149		open_filter: 'Show filter',
150		close_filter: 'Close filter',
151		pick_text: 'Select an item',
152		show_results: 'Show filter results',
153		transfer_to_admin: 'Transfer to admin filter'
154
155	},
156	pagination: {
157		limit: 0,
158		limitstart: 0,
159		orderby: 'vm_product.product_name',
160		DescOrderBy: 'ASC',
161		pagestart: null,
162		pageend: null
163	},
164	options: {											            // Volby ktore je mozne zmenit v local js
165		disableStickyRes: false,                                    // Zakaze scroll event pre tlacidlo zobrazit viac
166		forceDeaultScroll: false,                                   // Forcne pouzitie default scrollbaru
167		positions: {                                                // jQuery metody a triedy pre appendnutie roznych elementov filtra
168			'simple_paging': [],                                    // Ciel pripnutia tlacidla jednoducheho strankovania
169			'filter_active': [],                                    // Ciel pripnutia textu celkom produktov/celkom najdenych
170			'filter_total': ['#shop-category-orderby-form', 'insertBefore'],   // Ciel pripnutia textu s informaciou total_found z total
171			'results_info': []                                      // Ciel pripnutia textu s informaciou o pocte odfiltrovanych poloziek
172		},
173		sortBtnsOrder: [],								            // Poradie sortovacich tlacidiel, zadavat kody urcene v sphf.order_list
174		search_value: {
175			showcase: true,                                         // Efekt predvyplnania placeholdera v input fielde podla aktualnych hodnot
176			regex: {}                                               // Vlastne regex hladanie hodnot v skupine {id_skupiny: function}
177	    },
178		extract: {},                                                // Polozky skupin ktore maju byt vytiahnute zo skupin a vlozene na koniec filtra
179		show_btn: {                                                 // Tlacidlo zobrazit filter
180			enabled: false,
181			nameFromModule: false,
182			cont: '#shop-category-orderby-form',
183			func: 'prepend'
184		},
185		adjustScroll: function() { // Funkcia na upravu scrolovania po paginacii
186			return -10;
187		},
188		/**
189		 * Spustane po prvej inicializacii filtra
190		 */
191		onFilterInit: function(){},
192		/**
193		 * Spustane po kompletnom ukonceni vykreslenia filtra
194		 */
195		onFilterRender: function(){},
196		/**
197		 * Spustane ihned po vykonani ajaxu pre kalkulaciu facetov.
198		 * Vola sa este pred vykreslenim filtra, a hned po setnuti vratenych dat do globaliek
199		 */
200		onCalculateRequest: function(){},
201		/**
202		 * Spustane ihned po vykonani ajaxu pre zvolenu polozku
203		 * Vola sa este pred vykreslenim filtra, a hned po vlozeni produktov a strankovania do middle
204		 */
205		onBrowseRequest: function(){},
206		/**
207		 * Spustane po vykonani renderingu aktivnych poloziek filtra
208		 */
209		onActiveRender: function(){},
210		/**
211		 * Custom bindovanie otvarania skupin. Skupina musi mat tuto volbu nastavenu.
212		 * Vola sa sa pri bindovani skupin.
213		 */
214		bindOpen: function(){}
215	},
216	/**
217	 * Inicializacia filtra, volane z local.js
218	 * @param {object} options - Jednotlive volby daneho shopu
219	 */
220	init: function(options){
221		sphf.checkDebug();
222
223		if (sphf.debug){
224			console.log('Sphinx filter [v.'+sphf.version+']');
225			csstack('init','');
226		}
227
228		if (sphf.csuser) {
229			sphf.timing.start = sphf.microtime(true);
230		}
231
232		sphf.obj.window = jQuery(window);
233		sphf.obj.body = jQuery('body');
234		sphf.obj.modul = jQuery('.modul_filter');
235		sphf.obj.module = jQuery('.module.mp_filter.mp');
236		sphf.obj.content = jQuery('#middle_content_inner');
237
238		// Hotfix, vsetky cookie musia byt setnute s cestou. Niekedy neboli
239		Cookies.set('sphf_filter', null, { path: '/' });
240
241		// Podmieneny reset filtra
242		if (Cookies.get('reset_sphf_filter')) {
243			Cookies.set('sphf_filter', '', { path: window.location.pathname });
244			Cookies.set('reset_sphf_filter', null, { path: '/' });
245		}
246
247		// Modul a produkty v shop browse musia existovat
248		if (typeof sphf.obj.modul === 'undefined' || sphf.obj.modul.length === 0) {
249			return;
250		}
251		if (typeof sphf.obj.content === 'undefined' || sphf.obj.content.length === 0) {
252			return;
253		}
254
255		sphf.obj.products = sphf.obj.content.find('#product_list');
256		sphf.obj.navtop = sphf.obj.content.find('.page-navigation-top');
257		sphf.obj.navbot = sphf.obj.content.find('.page-navigation-bottom');
258		sphf.obj.link = sphf.obj.modul.find('.sphf_link');
259		sphf.obj.collapser = sphf.obj.modul.find('.filter_collapser .button');
260
261		sphf.touchdevice = sphf.obj.body.hasClass('is_touch_device');
262
263		// Ak su produkty iba na jednej stranke, navigacny element chyba
264		if (sphf.obj.navbot.length === 0){
265
266			sphf.obj.content.append('<div class="page-navigation-bottom no_pagination"></div>');
267			sphf.obj.navbot = sphf.obj.content.find('.page-navigation-bottom');
268		}
269
270		sphf.events.onBrowseRequest = document.createEvent('Event');
271		sphf.events.onBrowseRequest.initEvent('onBrowseRequest', true, true);
272
273		// Cachovanie objektov filtra
274		sphf.elems.filter_group = {};
275		sphf.elems.extracted = {};
276		sphf.obj.modul.find('.filter_group').each(function(c,e){
277
278			var box = jQuery(e);
279			var id = box.attr('id');
280			box.data('ordering', c);
281			sphf.elems.filter_group[id] = box;
282		});
283
284		// Sortneme aktivne polozky filtra
285		sphf.sortActive();
286
287		sphf.manager = (sphf.obj.modul.hasClass('sphf_manager'));
288		sphf.backend = (sphf.obj.modul.hasClass('sphf_backend'));
289
290		// CS mini statistika
291		if (sphf.debug){
292
293			sphf.obj.stats = jQuery('<div/>', {'class':'csstats', 'id':'csstats'});
294			sphf.obj.modul.closest('.module_cont').append(sphf.obj.stats);
295			sphf.obj.stats.on('mouseenter mouseleave', function(){ sphf.toggleStats(this); });
296		}
297
298		// Rozsirenie options z local.js
299		if (typeof options !== 'undefined') {
300			sphf.options = jQuery.extend(true, sphf.options, options);
301		}
302
303		sphf.initLangs();
304
305		// Tlacidlo show filter
306		if ((typeof sphf.options.show_btn.enabled === 'function' && sphf.options.show_btn.enabled()) || (typeof sphf.options.show_btn.enabled !== 'function' && sphf.options.show_btn.enabled)){
307
308			sphf.initShowButton();
309		}
310
311		// Bindovanie eventov
312		if (!jQuery.isEmptyObject(sphf.setting)){
313
314			if (sphf.setting.group_open_on == 3){
315
316				sphf.options.bindOpen.call();
317			}
318
319			// Kompakt filter nepouziva otvaranie skupin
320			if ( sphf.setting.display !== 2 ){
321
322				if (  sphf.setting.group_open_on == 1 || sphf.touchdevice ){
323
324					sphf.obj.body.on('click', '.filter_title', function(e){ sphf.toggle(this, e); });
325					sphf.obj.body.on('click', function(e){
326
327						if (!jQuery(e.target).closest('.mp_filter').length){
328
329							// Odkaz musi fungovat na 1 klik
330							if (typeof e.target.nodeName !== 'undefined' && (e.target.nodeName == 'A' || e.target.nodeName == 'IMG')) return;
331
332							// To plati aj pre parentov
333							if (e.target.parentElement !== null && e.target.parentElement.nodeName == 'A') return;
334
335							var opened = sphf.obj.modul.find('.filter_group.opened').not('.initial_opened');
336
337							if (opened.length){
338
339								e.preventDefault();
340								opened.removeClass('opened').addClass('closed');
341								sphf.isGroupOpened();
342								return false;
343							}
344						}
345					});
346				}
347				if (sphf.setting.group_open_on == 2 && !sphf.touchdevice){
348
349					sphf.obj.body.on('mouseenter mouseleave', '.filter_group', function(e){ sphf.toggle(this, e); });
350				}
351				if (sphf.setting.group_open_on == 1 && sphf.setting.onclick_out == 1){
352
353					sphf.obj.body.on('mouseleave', '.filter_group', function(e){ sphf.toggle(this, e); });
354				}
355				if (!sphf.touchdevice && (sphf.setting.onclick_close == 1 && sphf.setting.group_open_on != 1)){
356
357					sphf.obj.body.on('click', '.filter_group.opened .filter_title', function(e){ sphf.toggle(this, e); });
358				}
359			}
360		}
361
362		// Precistime prvky od bordelu z inych scriptov, a zacneme na cistom stole
363		jQuery('select[name="orderby"]').removeAttr('onchange').off().addClass('no-redirect');
364		jQuery('select[name="limit"]').removeAttr('onchange').off().addClass('no-redirect');
365		if ( typeof window.js_CS_Config_orderby_span !== 'undefined' ) {
366			jQuery('.orderby_img, .orderby_span').removeAttr('onclick').addClass('no-redirect');
367		} else {
368			jQuery('.orderby_img').removeAttr('onclick').addClass('no-redirect');
369		}
370
371		// Strankovanie so zobrazenym filtrom
372		sphf.cleanUrl();
373
374		// Vyplnime premennu s udajmi o strankovani
375		sphf.buildPagination();
376
377		// Inicializacia sortovania
378		sphf.initSortButtons();
379
380		// Klik na polozku filtra
381		sphf.obj.body.on('change', '.fi_input', function(e){
382
383			if ( !jQuery(this).hasClass('hidden') ) sphf.changed(this, e);
384		});
385
386		// Klik na SEO odkaz vo filtry (klik na polozku filtra)
387		if (sphf.seo.value_links == 1){
388
389			sphf.obj.body.on('click', 'a.filter_link', function(e){
390
391				e.preventDefault();
392				if (typeof e.target !== 'undefined' && e.target !== 'undefined' && e.target.className === 'text'){
393
394					jQuery(this).closest('label').trigger('click');
395				}
396			});
397		}
398
399		// Klik na odkaz filtra
400		sphf.obj.body.on('click', 'a.sphf_link', function(e){ sphf.copyLink(this, e); });
401
402		// Obnovenie stranky po dynamickej zmene URL
403		window.addEventListener('popstate', function(event) {
404
405			if (sphf.debug){ console.log('    popstate event...', event.state); }
406
407		    if (event.state && event.state !== null && typeof event.state.sphf_state !== 'undefined'){
408
409				sphf.setState(event.state.sphf_state);
410				sphf.browse(null, true);
411		    }
412		}, false);
413
414		// Kompaktny rezim
415		if (sphf.obj.collapser.length) sphf.initSubGroups();
416
417		// Bind zakladnych prvkov strankovania
418		sphf.obj.body.on('click', 'a.pagenav', function(e){
419			e.preventDefault();
420			sphf.browse(this);
421		});
422		sphf.obj.body.on('change', 'select[name="orderby"]', function(){
423			sphf.browse(this);
424		});
425		sphf.obj.body.on('change', 'select[name="limit"]', function(){
426			sphf.browse(this);
427		});
428		if (typeof js_CS_Config_orderby_span !== 'undefined') {
429			sphf.obj.body.on('click', '.orderby_img, .orderby_span', function () {
430				// Nastavime input
431				let btn = jQuery(this);
432				if (btn.hasClass('ASC')) {
433					jQuery('input[name="DescOrderBy"]').val('DESC');
434				} else {
435					jQuery('input[name="DescOrderBy"]').val('ASC');
436				}
437				sphf.browse(this);
438				if (btn.hasClass('ASC')) {
439					btn
440						.removeClass('ASC')
441						.addClass('DESC');
442				} else {
443					btn
444						.removeClass('DESC')
445						.addClass('ASC');
446				}
447			});
448		} else {
449			sphf.obj.body.on('click', '.orderby_img', function () {
450
451				if (sphf.csuser) {
452					sphf.timing.start = sphf.microtime(true);
453				}
454
455				// Nastavime input
456				let btn = jQuery(this);
457				if (btn.hasClass('ASC')) {
458					jQuery('input[name="DescOrderBy"]').val('DESC');
459				} else {
460					jQuery('input[name="DescOrderBy"]').val('ASC');
461				}
462				sphf.browse(this);
463			});
464		}
465
466		// Pre shopy podporujuce zobrazovanie viacerych mien, resetneme cookie, ktore robia problemy pri nastavenom filtri
467		sphf.obj.body.on('click', '.selected_currency a', function () {
468
469			if (sphf.url.path !== '' && sphf.url.path !== '/') {
470				Cookies.set('sphf_filter', '', {path: sphf.url.path});
471			}
472		});
473
474		// Inicialne nastavenie url podla cookie, teraz tam chybaju udaje
475		if (typeof sphf.stats.global !== 'undefined' && sphf.stats.global.commanded == 2 && !jQuery.isEmptyObject(sphf.active)) {
476
477			sphf.paginator('', sphf.stats.global.pagination.limitstart);
478		}
479
480		// Inicialny rendering a cachovanie obsahu modulu
481		sphf.renderItems();
482
483		// Renderovanie poloziek pre sprievodcu
484		if (sphf.guide.length) {
485			sphf.renderGuide();
486		}
487
488		// Inicializacia boxu aktivnych poloziek
489		sphf.initActive();
490
491		// Aktualizacia url odkazu na filter
492		sphf.updateLink();
493
494		// Tlacidlo adfilter pre administraciu
495		sphf.initAdfilterButton();
496
497		// V quirk mode musime zaslat request na server so spravnymi udajmi
498		if (sphf.urlfilter !== '') {
499			sphf.browse();
500		} else {
501			sphf.renderActive();
502		}
503
504		sphf.postRender();
505
506		// Musime po prvom refreshi zaznamenat udaje pre nasledujuce popstate eventy
507		if (!sphf.quirk) {
508			// Toto nastavime pre stranku na ktorej nemame ziadne
509			sphf.orig_state = sphf.getState();
510
511			// Ak url nesedi s seo url musime ju zmenit
512			var url = ((typeof sphf.seo.url !== 'undefined' && sphf.seo.url !== '' && document.location.href !== sphf.seo.url) ? sphf.seo.url + (sphf.url.
512search !== '' ? sphf.url.search : '') + (sphf.url.hash !== '' ? sphf.url.hash : '') : document.location.href);
513			if (sphf.debug) {
514				console.log('   replacing history state...', {
515					urlPath: url,
516					currentUrl: document.location.href,
517					seoUrl: sphf.seo.url,
518					sphf_state: sphf.orig_state
519				});
520			}
521			history.replaceState({urlPath: url, sphf_state: sphf.orig_state}, null, url);
522		}
523
524		// Callback pri prvej inicializacii
525		sphf.options.onFilterInit.call('undefined', sphf.obj.modul);
526
527		sphf.initialized = 1;
528	},
529	initBackend: function(){
530		sphf.checkDebug();
531
532		if (sphf.debug){
533			console.log('Sphinx filter [v.'+sphf.version+']');
534			csstack('initBackend');
535		}
536
537		sphf.backend = true;
538		sphf.obj.window = jQuery(window);
539		sphf.obj.body = jQuery('body');
540		sphf.obj.modul = jQuery('.modul_filter');
541		sphf.obj.collapser = sphf.obj.modul.find('.filter_collapser .button');
542
543		sphf.initLangs();
544
545		sphf.obj.body.on('click', '.filter_group .csi-cog', function(){
546
547			sphf.openSetting(this, 'group');
548		});
549
550		// Kompaktny rezim
551		if (sphf.obj.collapser.length) {
552			sphf.initSubGroups();
553		}
554
555		// Oznacenie tagom ze skupina obsahuje specialne nastavenie
556		sphf.obj.modul.find('.filter_group').each(function(){
557
558			let group = jQuery(this);
559			let id = group.attr('id');
560
561			// Vsetky skupiny musia byt v backende zatvorene
562			group.removeClass('always_opened').removeClass('opened').addClass('closed');
563			group.find('.filter_title').attr('title', sphf.langs.set_group);
564
565			let btn = jQuery('<span>').addClass('cs_icon csi-cog ftr_setting');
566
567			if (typeof sphf.groups[id] !== 'undefined' && (typeof sphf.groups[id].isDefault === 'undefined' || !sphf.groups[id].isDefault)) {
568				btn.attr('title', sphf.langs.has_setting).addClass('has_setting');
569			} else {
570				btn.attr('title', sphf.langs.set_group);
571			}
572
573			group.find('.filter_title').before(btn);
574		});
575
576		sphf.obj.body.on('click', '.filter_title', function () {
577			sphf.openSetting(this, 'values');
578		});
579
580		// Kontrola beziaceho indexu
581		let ibtn = jQuery('.sph_menu span.csi-database.working');
582		if (ibtn.length) {
583			sphf.pingIndex(ibtn);
584		}
585	},
586	initShowButton: function(){
587		if (sphf.debug){ csstack('initShowButton'); }
588
589		sphf.obj.module.addClass('fixed_filter');
590
591		// Wrapper kontajnera tlacidla
592		let wrap = sphf.obj.navtop;;
593
594		if (typeof sphf.options.show_btn.cont !== 'undefined' && sphf.options.show_btn.cont !== ''){
595			wrap = jQuery(sphf.options.show_btn.cont);
596			if (typeof wrap === 'undefined' || !wrap.length){
597				wrap = sphf.obj.navtop;
598			}
599		}
600
601		let name = sphf.langs.filter;
602		if ( sphf.options.show_btn.nameFromModule && sphf.obj.module.find('.module_name').length ) {
603			name = sphf.obj.module.find('.module_name').text();
604		}
605
606		sphf.obj.show_btn = jQuery('<div>').addClass('show_filter_btn_box');
607		sphf.obj.show_btn.append('<div class="button show_filter_btn"><div class="icon"><span class="line"></span><span class="line"></span><span class="line"></span></div>' + name + '</div>');
608
609		sphf.obj.show_btn.on('click', function(){ sphf.obj.body.addClass('open_filter'); });
610
611		let func = (typeof sphf.options.show_btn.func === 'undefined' ? 'prepend' : sphf.options.show_btn.func);
612
613		if (typeof wrap[func] === 'function'){
614
615			if (func === 'insertBefore' || func === 'insertAfter'){
616				sphf.obj.show_btn[func](wrap);
617			} else {
618				wrap[func](sphf.obj.show_btn);
619			}
620		} else {
621
622			wrap.append(sphf.obj.show_btn);
623		}
624
625		sphf.obj.res_btn = jQuery('<div>').addClass('button');
626		sphf.obj.res_btn.text(sphf.langs.show_results);
627	    sphf.obj.module.find('.module_bot').append(sphf.obj.res_btn);
628
629	    sphf.obj.res_btn.on('click',function(){ sphf.obj.body.removeClass('open_filter'); });
630
631	    // overlay event
632	    jQuery('#bottom').on('click',function(){ sphf.obj.body.removeClass('open_filter'); });
633	},
634	/**
635	 * Niektore inicializacie pri kompakt zobrazeni filtra
636	 */
637	initSubGroups: function(){
638		if (sphf.debug){ csstack('initSubGroups'); }
639
640		sphf.obj.filter_body = sphf.obj.modul.find('.filter_sub_body');
641		sphf.obj.filter_menu = sphf.obj.modul.find('.filter_sub_menu');
642
643		sphf.obj.body.on('click', '.filter_collapser .button', function(){
644
645			sphf.toggleFilter();
646		});
647
648		sphf.obj.body.on('click', '.filter_sub_menu .sub_group_name', function(){
649
650			sphf.toggleSubGroup(this);
651		});
652	},
653	/**
654	 * Nastavenie langov, kde v kode pouzivame uz iba objekt sphf.langs
655	 */
656	initLangs: function(){
657		if (sphf.debug){ csstack('initLangs'); }
658
659		jQuery.each(sphf.langs, function(c,v){
660
661			sphf.langs[c] = (typeof window['js_lang_sphf_'+c] !== 'undefined' ? window['js_lang_sphf_'+c] : v);
662		});
663	},
664	/**
665	 * Inicializuje custom tlacidla pre sortovanie vysledkov
666	 */
667	initSortButtons: function(){
668		if (sphf.debug){ csstack('initSortButtons'); }
669
670		let a = '';
671
672		// Renderovanie vyberu sortovania, ktore su zobrazene ako buttons namiesto selectu
673		if (sphf.setting.sorttype == 1) {
674
675			let container = jQuery('#shop-category-orderby-container');
676			let select = jQuery('select[name="orderby"]');
677			let found = false;
678			let buttons = {};
679			let sorting = (sphf.options.sortBtnsOrder.length ? sphf.options.sortBtnsOrder : []);
680
681			sphf.sortwrap = jQuery('<div>').addClass('sort_tab_cont');
682
683			if (select.length > 0) {
684
685				select.find('option').each(function () {
686
687					var option = jQuery(this);
688					var key = option.val();
689					var name = option.text();
690
691					if (typeof sphf.order_list[key] !== 'undefined') {
692
693						found = true;
694
695						if (sorting.indexOf(sphf.order_list[key]) < 0) {
696							sorting.push(sphf.order_list[key]);
697						}
698
699						a = (sphf.pagination.orderby === key ? ' active' : '');
700
701						let aria = '';
702						if (config('js_CS_Config_wcag')) {
703							sphf.sortwrap
704								.attr('role', 'group')
705								.attr('aria-label', js_global_wcag.sortButtonsGroup || 'Tlačidlové zobrazenie pre radenie produktov');
706
707							aria = ' aria-pressed="false"';
708							if (sphf.pagination.orderby === key) {
709								aria = ' aria-pressed="true"';
710							}
711						}
712
713						buttons[sphf.order_list[key]] = '<a href="javascript:void(0);" role="button" onclick="sphf.sort(\'' + sphf.order_list[key] + '\', false);" class="align_tab sort_type_' + sphf.order_list[key] + ' no_content_design_link' + a + '" ' + aria + '>' + name + '</a>';
714					}
715				});
716
717				// Renderovanie tlacidiel, podla sortovania
718				for (var i = 0; i < sorting.length; i++) {
719
720					sphf.sortwrap.append(buttons[sorting[i]]);
721				}
722			}
723
724			container.prepend(sphf.sortwrap);
725
726			if (found) {
727				select.hide();
728			}
729		}
730	},
731	toggleFilter: function () {
732		if (sphf.debug) {
733			csstack('toggleFilter');
734		}
735
736		if (sphf.obj.modul.hasClass('filter_opened')) {
737			sphf.obj.collapser.find('span').html(sphf.langs.open_filter);
738			sphf.obj.modul.removeClass('filter_opened');
739		} else {
740			sphf.obj.collapser.find('span').html(sphf.langs.close_filter);
741			sphf.obj.modul.addClass('filter_opened');
742		}
743
744		// Otvorenie prvej skupiny
745		if (!sphf.obj.filter_menu.find('.sub_group_name.sub_active').length) {
746			sphf.obj.filter_menu.find('.sub_group_name').first().trigger('click');
747		}
748	},
749	toggleSubGroup: function (elem) {
750		if (sphf.debug) {
751			csstack('toggleSubGroup');
752		}
753
754		let btn = jQuery(elem);
755
756		if (btn.hasClass('sub_active')) {
757			return;
758		}
759
760		let id = btn.data('id');
761
762		sphf.obj.filter_menu.find('.sub_group_name.sub_active').removeClass('sub_active');
763
764		btn.addClass('sub_active');
765
766		sphf.obj.modul.find('.filter_sub_group.sub_active').removeClass('sub_active');
767
768		let groups = sphf.obj.modul.find('#' + id);
769		groups.addClass('sub_active');
770
771		// Inicializacia skupin
772		if (!sphf.backend && !groups.hasClass('groups_initializad')) {
773
774			groups.find('.filter_group').each(function () {
775
776				var box = jQuery(this);
777				if (!box.hasClass('group_initialized')) {
778					sphf.initGroup(box);
779				}
780				if (!box.hasClass('facets_rendered')) {
781					sphf.renderFacets(box);
782				}
783			});
784
785			groups.addClass('groups_initializad')
786		}
787	},
788	initResButton: function () {
789		if (sphf.debug) {
790			csstack('initResButton');
791		}
792
793		sphf.obj.resbtn = sphf.obj.modul.find('.filter_submit');
794
795		if (sphf.obj.resbtn.length > 0) {
796
797			sphf.resbtntop = sphf.obj.resbtn.offset().top;
798			sphf.wheight = sphf.obj.window.height();
799
800			if (sphf.options.disableStickyRes === false) {
801
802				sphf.obj.window.on("scroll", function () {
803					sphf.updateResButton();
804				});
805			}
806
807			sphf.obj.resbtn.on('click', function () {
808				sphf.browse();
809			});
810
811			sphf.obj.resbtn.css({
812				'left': sphf.obj.resbtn.offset().left + 'px',
813				'width': sphf.obj.resbtn.width() + 'px'
814			});
815			sphf.updateResButton();
816		}
817	},
818	insertElem: function(type, obj){
819		if (sphf.debug){ csstack('insertElem'); }
820
821		let r = false;
822
823		if (typeof sphf.options.positions[type] !== 'undefined' && sphf.options.positions[type].length){
824
825			let target = jQuery(sphf.options.positions[type][0]);
826
827			if (target.length){
828
829				let func = sphf.options.positions[type][1];
830
831				if (typeof target[func] == 'function'){
832
833					if (func === 'insertBefore' || func === 'insertAfter'){
834						obj[func](target);
835					} else {
836						target[func](obj);
837					}
838					r = true;
839				} else {
840
841					if (sphf.debug){ console.warn('SPHF WARN: Function "'+func+'" is not jQuery function'); }
842				}
843			} else {
844
845				if (sphf.debug){ console.warn('SPHF WARN: Target "'+sphf.options.positions[type][0]+'" not found'); }
846			}
847		}
848
849		return r;
850	},
851	initPagButton: function(){
852		if (sphf.debug){ csstack('initPagButton'); }
853
854		sphf.obj.pagbtn = jQuery('<div>').addClass('simple_paging').css('display','none').html('<div></div>');
855
856		if (!sphf.insertElem('simple_paging', sphf.obj.pagbtn)){
857
858			sphf.obj.pagbtn.appendTo(sphf.obj.content);
859		}
860
861		sphf.obj.pagbtn.on('click', function(){ sphf.simplePaging(); });
862	},
863	initSearch: function( box, id ){
864		if (sphf.debug){ csstack('initSearch', [id]); }
865
866		sphf.elems.filter_group[id]['items'] = [];
867		sphf.elems.filter_group[id]['labels'] = [];
868		sphf.elems.filter_group[id]['search_box'] = jQuery('<div>').addClass('filter_search');
869		sphf.elems.filter_group[id]['search_input'] = jQuery('<input>').attr('type', 'text').attr('name', 'value_search').val('');
870
871		sphf.elems.filter_group[id]['search_box'].append(sphf.elems.filter_group[id]['search_input']);
872
873		var wrap = box.closest('.filter_group');
874
875		wrap.addClass('is_search');
876
877		if ( sphf.options.search_value.showcase ){
878
879			wrap.on('afterShow.sphf', function(){ sphf.startPlaceholder(id); });
880			wrap.on('afterHide.sphf', function(){ sphf.stopPlaceholder(id); });
881		}
882
883		box.find('.filter_selected').after(sphf.elems.filter_group[id]['search_box']);
884
885		// Cachovanie elementov a hladanych slov
886		box.find('.filter_item').each(function(){
887
888			var elm = jQuery(this);
889			var txt = elm.find('.text').text();
890
891			sphf.elems.filter_group[id]['items'].push(elm);
892			sphf.elems.filter_group[id]['labels'].push(txt);
893		});
894
895		if ( sphf.options.search_value.showcase ){
896
897			sphf.elems.filter_group[id]['search_input'].on('focus', function(){ sphf.stopPlaceholder(id); });
898		}
899
900		sphf.elems.filter_group[id]['search_input'].on('keyup', function(){ sphf.searchValue(id); });
901	},
902	search: function(elem){
903		if (sphf.debug){ csstack(); }
904
905		var btn = jQuery(elem);
906		var box = btn.closest('.filter_group');
907		box.find('input.fi_input').trigger('change');
908	},
909	startPlaceholder: function(id){
910		if (sphf.debug){ csstack('startPlaceholder', [id]); }
911
912		if ( sphf.elems.filter_group[id]['labels'].length ){
913
914			var idx = 0;
915			var newidx = 0;
916			var char = 0;
917			if (typeof sphf.elems.filter_group[id]['plc_timeout'] !== 'undefined' && sphf.elems.filter_group[id]['plc_timeout'] > 0){
918				 clearTimeout(sphf.elems.filter_group[id]['plc_timeout']);
919			}
920			sphf.elems.filter_group[id]['plc_timeout'] = 0;
921			sphf.elems.filter_group[id]['search_input'].attr('placeholder', '|');
922			var typeIt = function(idx) {
923
924				var txt = sphf.elems.filter_group[id]['labels'][idx];
925				var txtLen = txt.length;
926			    var humanize = Math.round(Math.random() * (200 - 30)) + 30;
927			    if (typeof sphf.elems.filter_group[id]['plc_timeout'] !== 'undefined' && sphf.elems.filter_group[id]['plc_timeout'] == null) return;
928			    sphf.elems.filter_group[id]['plc_timeout'] = setTimeout(function () {
929
930			        char++;
931			        var type = txt.substring(0, char);
932			        sphf.elems.filter_group[id]['search_input'].attr('placeholder', type + '|');
933			        typeIt(idx);
934
935			        if (char == txtLen) {
936			            sphf.elems.filter_group[id]['search_input'].attr('placeholder', sphf.elems.filter_group[id]['search_input'].attr('placeholder').slice(0, -1)) // remove the '|'
937			            clearTimeout(sphf.elems.filter_group[id]['plc_timeout']);
938
939			            char = 0;
940			            newidx = idx+1;
941			            if (typeof sphf.elems.filter_group[id]['labels'][newidx] == 'undefined') newidx = 0;
942			            sphf.elems.filter_group[id]['plc_timeout'] = setTimeout(function(){
943			            	typeIt(newidx);
944			            },1000);
945			        }
946			    }, humanize);
947			};
948			typeIt(idx);
949		}
950	},
951	stopPlaceholder: function(id){
952		if (sphf.debug){ csstack('stopPlaceholder', [id]); }
953
954		clearTimeout(sphf.elems.filter_group[id]['plc_timeout']);
955		sphf.elems.filter_group[id]['plc_timeout'] = null;
956		sphf.elems.filter_group[id]['search_input'].attr('placeholder', '')
957	},
958	searchValue: function(id){
959		if (sphf.debug){ csstack('searchValue', [id]); }
960
961		var keywords = sphf.getSearchValueKeywords(id);
962		var regexps = [];
963
964		jQuery.each(keywords, function(c,v){
965
966			var keyword = v.latinise();
967
968			if (typeof sphf.options.search_value.regex[id] === 'function'){
969
970				keyword = sphf.options.search_value.regex[id](keyword);
971			}
972
973			regexps.push(new RegExp(keyword, "i"));
974		});
975
976		jQuery.each(sphf.elems.filter_group[id]['labels'], function(c,v){
977
978			var label = v.latinise();
979			var found = false;
980			if ( !regexps.length ){
981				sphf.elems.filter_group[id]['items'][c].show();
982			} else {
983				for( var i = 0; i<regexps.length; i++ ){
984
985					if ( regexps[i].test(String(label)) ) {
986
987						sphf.elems.filter_group[id]['items'][c].show();
988						found = true;
989						break;
990					}
991				}
992				if ( !found ) {
993					sphf.elems.filter_group[id]['items'][c].hide();
994				}
995			}
996		});
997	},
998	getSearchValueKeywords: function(id){
999		if (sphf.debug){ csstack('searchValue', [id]); }
1000
1001		var keywords = sphf.elems.filter_group[id]['search_input'].val().trim();
1002
1003		keywords = keywords.split('|');
1004
1005		for( var i = 0; i<keywords.length; i++ ){
1006			keywords[i] = keywords[i].trim();
1007            if ( '' === keywords[i] ){
1008                keywords.splice(i, 1);
1009            }
1010        }
1011
1012		return keywords;
1013	},
1014	initSlider: function( box, id ){
1015		if (sphf.debug){ csstack('initSlider', [id]); }
1016
1017		sphf.elems.filter_group[id].range_slider = box.find('.filter_range');
1018		sphf.elems.filter_group[id].range_text = box.find('.filter_range_value');
1019
1020		var wrap = box.closest('.filter_group');
1021		var act = sphf.currentSlider(id);
1022
1023		if (sphf.elems.filter_group[id].range_slider.length > 0){
1024
1025			wrap.addClass('is_range');
1026
1027			// Ak mame rovnake alebo nulove hodnoty, slider schovame
1028			if (act[0] === act[1] || (act[0] === 0 && act[1] === 0)) {
1029				wrap.addClass('not_usable');
1030			}
1031
1032			var slidermin = sphf.groups[id].range.min;
1033			var slidermax = sphf.groups[id].range.max;
1034			var sliderstp = sphf.groups[id].steps;
1035
1036			if (typeof sphf.groups[id] !== 'undefined' && typeof sphf.scales[id] != 'undefined') {
1037				slidermin = 0;
1038				slidermax = sphf.getMaxScaleKey(id);
1039				sliderstp = 1;
1040			}
1041
1042			// Forcneme steps podla nastavenej currency decimals kvoli rozdielnym currency
1043			if (id === 'price_range' && sphf.prices.decimals != sphf.countDecimals(sliderstp) && sphf.groups[id].adaptive != 1) {
1044
1045				var zero = '0';
1046				sliderstp = 1 / parseInt('1' + zero.repeat(sphf.prices.decimals));
1047				if (sphf.debug) {
1048					console.log('Adjusting slider step to currency decimals...', sliderstp);
1049				}
1050			}
1051
1052			if (sphf.debug) {
1053				console.log('Initialize slider with:', slidermin, slidermax, sliderstp, [ act[0], act[1] ]);
1054			}
1055
1056			sphf.elems.filter_group[id].range_slider.slider({
1057				range: true,
1058				min: slidermin,
1059				max: slidermax,
1060				step: sliderstp,
1061				values: [ act[0], act[1] ],
1062				animate: 500,
1063				create: function(event){
1064					sphf.rangeText(0, id);
1065
1066					// Zobrazenie a pocitanie facetov pre slider
1067					if (sphf.showFacet(id)) {
1068						sphf.elems.filter_group[id].range_facet = sphf.elems.filter_group[id].range_slider.find('.ui-slider-range');
1069					}
1070				},
1071				slide: function(event, ui){
1072					// Zobrazenie a pocitanie facetov pre slider
1073					if (sphf.showFacet(id) && typeof sphf.scales[id] !== 'undefined') {
1074						sphf.countScale(id, ui.values);
1075					}
1076
1077					sphf.rangeText(ui.values, id);
1078				},
1079				stop: function(event, ui){
1080					if (sphf.debug){ csstack('change', [id]); }
1081
1082					if (sphf.csuser){ sphf.timing.start = sphf.microtime(true); }
1083
1084					var uivalues = [ui.values[0], ui.values[1]];
1085					var range = sphf.scaleMinMax(id);
1086					var values = uivalues;
1087
1088					if (sphf.debug){
1089						console.log('-ui',JSON.stringify(ui.values));
1090						console.log('-uivalues',JSON.stringify(uivalues));
1091						console.log('-range',JSON.stringify(range));
1092					}
1093
1094					// Zobrazenie a pocitanie facetov pre slider
1095					if (sphf.showFacet(id)) {
1096						sphf.elems.filter_group[id]['range_facet'].html('');
1097					}
1098
1099					// Ak mame inu hodnotu, ako min max, setneme ho medzi aktivne polozky
1100					if (typeof sphf.scales[id] !== 'undefined' ) {
1101
1102						values = sphf.scaleKeyToValue(id, uivalues);
1103
1104						if (range[0] != ui.values[0] || range[1] != ui.values[1]){
1105
1106							sphf.setActive(id, values);
1107						} else {
1108
1109							sphf.removeActive(id, 0);
1110						}
1111					} else {
1112
1113						if (range[0] != values[0] || range[1] != values[1]){
1114
1115							sphf.setActive(id, values);
1116						} else {
1117
1118							sphf.removeActive(id, 0);
1119						}
1120					}
1121
1122					sphf.resetTotal();
1123					sphf.renderActive();
1124					sphf.changeFilter();
1125				}
1126			});
1127
1128			// Bind na inputy pre direct zadanie hodnot
1129			if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id]['inputs'] == 1){
1130
1131				sphf.obj.body.on('blur', '#'+id+' input[name="filter_range_from"]', function(){ sphf.setSlider(this, id); });
1132				sphf.obj.body.on('blur', '#'+id+' input[name="filter_range_to"]', function(){ sphf.setSlider(this, id); });
1133
1134				// Enter key
1135				sphf.obj.body.on('keyup', '#'+id+' input[name="filter_range_from"]', function(e){
1136					if(e.keyCode == 13){
1137						jQuery(this).trigger('blur');
1138					}
1139				});
1140				sphf.obj.body.on('keyup', '#'+id+' input[name="filter_range_to"]', function(e){
1141					if(e.keyCode == 13){
1142						jQuery(this).trigger('blur');
1143					}
1144				});
1145			}
1146		}
1147	},
1148	countDecimals: function (value) {
1149	    if(Math.floor(value) === value) {
1150			return 0;
1151	    }
1152        return value.toString().split(".")[1].length || 0;
1153	},
1154	/**
1155	 * Skopiruje url odkaz do pameti
1156	 */
1157	copyLink: function(elem, event){
1158		if (sphf.debug){ csstack('copyLink'); }
1159
1160		event.stopPropagation();
1161		event.preventDefault();
1162
1163		let btn = jQuery(elem);
1164		let url = btn.attr('href');
1165
1166		let textArea = document.createElement("textarea");
1167		textArea.style.position = 'fixed';
1168		textArea.style.width = '2em';
1169		textArea.style.height = '2em';
1170		textArea.style.border = 'none';
1171		textArea.style.outline = 'none';
1172		textArea.style.boxShadow = 'none';
1173		textArea.style.background = 'transparent';
1174		textArea.value = url;
1175		document.body.appendChild(textArea);
1176		textArea.select();
1177
1178		try {
1179			let successful = document.execCommand('copy');
1180			if (successful) {
1181
1182				btn.addClass('sphf_copied');
1183				window.setTimeout(function () {
1184					btn.removeClass('sphf_copied');
1185				}, 1000);
1186			}
1187
1188		} catch (err) {
1189
1190			if (sphf.debug) {
1191				console.log('Nemôže kopírovať...');
1192			}
1193		}
1194	},
1195	/**
1196	 * Aktualizuje odkaz na filter s novou url
1197	 */
1198	updateLink: function () {
1199		if (sphf.debug) {
1200			csstack('updateLink');
1201		}
1202
1203		if (sphf.obj.link.length) {
1204
1205			if (typeof sphf.seo.url !== 'undefined' && sphf.seo.url !== '') {
1206
1207				sphf.obj.link.attr('href', sphf.seo.url);
1208			}
1209
1210			// Pre default filter, bez zvolenych hodnot tlacidlo nezobrazujeme
1211			if (jQuery.isEmptyObject(sphf.active)) {
1212				sphf.obj.link.detach();
1213			} else if (sphf.obj.link.parent().length === 0) {
1214				sphf.obj.modul.find('.sphf_link_box').html(sphf.obj.link);
1215			}
1216		}
1217	},
1218	/**
1219	 * Spocita facety pre dynamicky slider ak je tato moznost povolena
1220	 */
1221	countScale: function (id, range) {
1222
1223		let count = 0;
1224
1225		if (typeof sphf.scales[id] !== 'undefined' && sphf.scales[id] !== null) {
1226
1227			for (let i = range[0]; i <= range[1]; i++) {
1228				count += parseInt(sphf.scales[id][i]['count']);
1229			}
1230
1231			if (sphf.showFacet(id)) {
1232				sphf.elems.filter_group[id]['range_facet'].html('<div class="filter_range_facet">' + count + '</div>').css('overflow', 'visible');
1233			}
1234		}
1235
1236		return count;
1237	},
1238	/**
1239	 * Z realnych hodnot najde nablizsiu najvecsiu hodnotu v poli scale
1240	 */
1241	revertScale: function(id, value){
1242		if (sphf.debug){ csstack('revertScale', [id,value]); }
1243
1244		value = parseFloat(value);
1245		var found = 0;
1246
1247		if (typeof sphf.scales[id] === 'undefined' || sphf.scales[id] === null) {
1248			return 0;
1249		}
1250
1251		// Iba ak je hodnota vacsia ako 0, inak nema cenu hladat
1252		if (value > 0) {
1253
1254			for (var i = 0; i < sphf.scales[id].length; i++) {
1255				if (value <= parseFloat(sphf.scales[id][i]['value'])) {
1256					found = i;
1257					break;
1258				}
1259			}
1260		}
1261
1262		return found;
1263	},
1264	/**
1265	 * Pre adaptivny slider, zmeni realne hodnoty na keys stupnice
1266	 */
1267	scaleValuesToKey: function(id, values){
1268		if (sphf.debug){ csstack('scaleValuesToKey', [id,values]); }
1269
1270		if ( typeof sphf.scales[id] !== 'undefined' ){
1271
1272			var ok = [false,false];
1273
1274			// Iba ak je hodnota vacsia ako 0, inak nema cenu hladat
1275			jQuery.each(sphf.groups[id].scale, function(c,v){
1276
1277				if ( ok[0] && ok[1] ) return false;
1278
1279				if ( !ok[0] && values[0] == v.value ){
1280
1281					values[0] = c;
1282					ok[0] = true;
1283				}
1284				if ( !ok[1] && values[1] == v.value ){
1285
1286					values[1] = c;
1287					ok[1] = true;
1288				}
1289			});
1290		}
1291
1292		return values;
1293	},
1294	/**
1295	 * Pre adaptivny slider, zmeni scale keys na realne hodnoty
1296	 */
1297	scaleKeyToValue: function(id, values){
1298		if (sphf.debug){ csstack('scaleKeyToValue', [id,values]); }
1299
1300		if (typeof sphf.scales[id] !== 'undefined' && sphf.scales[id] !== null && typeof sphf.scales[id][values[0]] !== 'undefined' && typeof sphf.scales[id][values[1]] !== 'undefined') {
1301			values[0] = sphf.scales[id][values[0]].value;
1302			values[1] = sphf.scales[id][values[1]].value;
1303		}
1304
1305		return values;
1306	},
1307	/**
1308	 * Podla realnych hodnot vrati prislusne kluce v poli
1309	 * @return {object}
1310	 */
1311	scaleValueToKey: function(id, values){
1312		if (sphf.debug){ csstack('scaleValueToKey', [id,values]); }
1313
1314		var r = [];
1315
1316		if (typeof sphf.scales[id] !== 'undefined') {
1317
1318			// Iba ak je hodnota vacsia ako 0, inak nema cenu hladat
1319			jQuery.each(sphf.scales[id], function (c, v) {
1320				if (typeof r[0] !== 'undefined' && typeof r[1] !== 'undefined') {
1321					return false;
1322				}
1323				if (typeof r[0] === 'undefined' && values[0] == v.value) {
1324					r[0] = c;
1325				}
1326				if (typeof r[1] === 'undefined' && values[1] == v.value) {
1327					r[1] = c;
1328				}
1329			});
1330		}
1331
1332		// Ak sme nic nenasli, spravime doplnujuci fallback
1333		if (typeof r[0] === 'undefined') {
1334			r[0] = 0;
1335			if (sphf.debug) {
1336				console.log('no min found fallback to', r[0]);
1337			}
1338		}
1339		if (typeof r[1] === 'undefined') {
1340			r[1] = sphf.getMaxScaleKey(id);
1341			if (sphf.debug) {
1342				console.log('no max found fallback to', r[1]);
1343			}
1344		}
1345
1346		return r;
1347	},
1348	initActive: function () {
1349		if (sphf.debug) {
1350			csstack('initActive');
1351		}
1352
1353		if (sphf.manager) {
1354			sphf.setting.factic = '.filter_active_wrapper';
1355		}
1356
1357		if (jQuery.isEmptyObject(sphf.setting)) {
1358			return;
1359		}
1360
1361		let wrap;
1362
1363		if (typeof sphf.setting.factic !== 'undefined' || sphf.setting.factic !== '') {
1364			wrap = jQuery(sphf.setting.factic);
1365		}
1366
1367		if (typeof wrap === 'undefined' || wrap === null || !wrap.length) {
1368				wrap = sphf.obj.modul;
1369			}
1370
1371		let active_class = '.fp_active';
1372
1373		// Hlavny kontajner aktivnych poloziek
1374		sphf.obj.activ = jQuery(active_class);
1375
1376		if (typeof sphf.obj.activ == 'undefined' || sphf.obj.activ.length == 0) {
1377
1378			let func = (typeof sphf.setting.factim === 'undefined' ? 'append' : sphf.setting.factim);
1379
1380			if (typeof wrap[func] == 'function') {
1381
1382				if (func === 'insertBefore' || func === 'insertAfter') {
1383					jQuery('<div class="fp_active"></div>')[func](wrap);
1384				} else {
1385					wrap[func]('<div class="fp_active"></div>');
1386				}
1387			} else {
1388
1389				wrap.append('<div class="fp_active"></div>');
1390			}
1391
1392			sphf.obj.activ = jQuery(active_class);
1393		}
1394
1395		sphf.obj.body.on('click', '.fp_active_reset', function () {
1396			sphf.resetFilter(this);
1397		});
1398		sphf.obj.body.on('click', '.activ_item', function () {
1399			sphf.removeItem(this);
1400		});
1401		sphf.obj.body.on('click', '.item_remove', function () {
1402			sphf.removeItem(this);
1403		});
1404
1405		if (sphf.setting.group_active == 1) {
1406
1407			sphf.obj.body.on('click', '.activ_group', function () {
1408
1409				if (jQuery(this).hasClass('no_removable')) {
1410					return;
1411				}
1412				sphf.removeGroup(this);
1413			});
1414		}
1415
1416		sphf.checkActive();
1417
1418		sphf.isGroupOpened();
1419	},
1420	checkActive: function(){
1421		if (sphf.debug){ csstack('checkActive'); }
1422
1423		// Preselect aktivnych poloziek, vsetky su teraz unchecknute
1424		jQuery.each(sphf.active, function(group, values){
1425
1426			var box = sphf.obj.modul.find('#'+group);
1427
1428			jQuery.each(values, function(i, v){
1429
1430				var input = (group === 'keywords' ? box.find('#keyword') : box.find('#'+group+'_'+v));
1431
1432				if (group === 'keywords'){
1433
1434					input.val(decodeURIComponent(v));
1435				} else if (typeof sphf.groups[group] !== 'undefined' && sphf.groups[group].type == 3){
1436
1437					input.closest('.filter_item').addClass('item_checked').find('.fi_image, .fi_image_label').addClass('is_checked');
1438				} else {
1439
1440					input.prop('checked', true);
1441				}
1442			});
1443		});
1444	},
1445	/**
1446	 * Overuje ci sa maju facety zobrazovat pre tuto skupinu
1447	 * @param {string} id
1448	 */
1449	showFacet: function(id) {
1450		return (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id]['showfacet'] > 0);
1451	},
1452	/**
1453	 * vykreslenie aktivnych poloziek filtra do osobitneho elementu na stranke
1454	 */
1455	renderActive: function(){
1456		if (sphf.debug){ csstack('renderActive'); }
1457
1458		var active_filled = false;
1459
1460		sphf.obj.activ.empty().addClass('is_empty');
1461		sphf.obj.modul.find('.filter_group').removeClass('is_picked');
1462
1463		let active_wrap = jQuery('.fp_active_title');
1464		let active_info = jQuery('.filter_result_info');
1465		let adjust_info = jQuery('.filter_adjust_info');
1466		let total_info = jQuery('.filter_total_info');
1467
1468		if (active_wrap.length) active_wrap.remove();
1469		if (active_info.length) active_info.remove();
1470		if (adjust_info.length) adjust_info.remove();
1471		if (total_info.length) total_info.remove();
1472
1473		active_wrap = jQuery('<div>').addClass('fp_active_title');
1474
1475		if ( sphf.guide.length ){
1476
1477			var guide_status = 1;
1478
1479			jQuery.each(sphf.guide, function(c, v){
1480
1481				if ( typeof sphf.active[v.id] === 'undefined' || !sphf.active[v.id].length ){
1482
1483					guide_status = 0;
1484				}
1485			});
1486
1487			if ( guide_status ) sphf.obj.modul.addClass('guide_picked');
1488			else sphf.obj.modul.removeClass('guide_picked');
1489		}
1490
1491		jQuery.each(sphf.active, function(id, d){
1492
1493			// V pripade ze parameter bol v cookie
1494			if (typeof sphf.elems.filter_group[id] == 'undefined') return true;
1495
1496			var group_selected = sphf.elems.filter_group[id].find('.filter_selected');
1497			var is_range = sphf.elems.filter_group[id].hasClass('is_range');
1498			var is_select = sphf.elems.filter_group[id].hasClass('filter_select');
1499
1500			group_selected.empty();
1501
1502			if (d.length > 0){
1503
1504				var items_extracted = 0;
1505				var items_filled = 0;
1506				var div = jQuery('<div/>');
1507				var grp = jQuery('<span/>');
1508				var group_title = '';
1509				var grptitle = sphf.elems.filter_group[id].find('.filter_title_text');
1510
1511				if (grptitle.length){
1512					group_title = grptitle.html();
1513				} else if (typeof sphf.keywords[id] !== 'undefined'){
1514					group_title = sphf.keywords[id].label;
1515				}
1516
1517
1518				div.data('param_group', id);
1519
1520				// Render vsetkych poloziek do jednej skupiny
1521				if (sphf.setting.group_active == 1){
1522
1523					div.attr('class', 'activ_set '+id);
1524					if (typeof d == 'object' && d.length < 2){
1525
1526						grp.attr('class', 'activ_group no_removable');
1527					} else {
1528
1529						grp.attr('class', 'activ_group');
1530						grp.attr('title', sphf.langs.remove_group);
1531					}
1532					grp.html(group_title+'<span class="fp_aux_grp_remove"></span>');
1533					div.append(grp);
1534				} else {
1535
1536					div.attr('class', 'activ_set no_grouping');
1537					grp.attr('class', 'title');
1538					grp.html(group_title+':');
1539				}
1540
1541				var joined_title = '';
1542
1543
1544				jQuery.each(d, function(c, item){
1545
1546					if (typeof item == 'undefined') return true;
1547
1548					var item_title = '';
1549
1550					if (id === 'keywords'){
1551
1552						item_title = decodeURIComponent(item);
1553					}
1554					else if (is_range){
1555
1556						// Formatovanie mien
1557						if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id]['uom'] == 1){
1558
1559							item = js_format_Money( item, sphf.prices['decimals'], '', sphf.prices['1000_symbol'], sphf.prices['dec_symbol']);
1560						}
1561
1562						// Pripravime prvy kluc
1563						if ( c === 0 && d.length > 1 ){
1564							joined_title += item + sphf.getUom(id) + ' - ';
1565							return true;
1566						} else {
1567							joined_title += item + sphf.getUom(id);
1568						}
1569					}
1570					else {
1571
1572						var ibox = sphf.elems.filter_group[id].find('.fi_input[value="'+item+'"]');
1573						if (ibox.hasClass('is_extracted')) {
1574							items_extracted++;
1575						}
1576						item_title = ibox.closest('.filter_item').find('.text').html();
1577					}
1578
1579					if (item_title === null || typeof item_title == 'undefined' || item_title === 'undefined') {
1580						item_title = '';
1581					}
1582
1583					// JAN quickfix, niekedy sa hodnota nenachadza vo filtri
1584					if (item_title === '' && typeof sphf.keywords[id] !== 'undefined' && typeof sphf.keywords[id]['values'][item] !== 'undefined'){
1585						item_title = sphf.keywords[id]['values'][item];
1586					}
1587
1588					items_filled++;
1589
1590					var classnores = '';
1591					var titlenores = '';
1592
1593					// Item nastavime na 0 pre zlozene hodnoty
1594					if (is_range) {
1595
1596						item = 0;
1597						item_title = joined_title;
1598					} else {
1599
1600						var target_facet = id;
1601						if (typeof sphf.facets[id + '_avails'] !== 'undefined') {
1602							target_facet = id + '_avails';
1603						} else if (typeof sphf.facets[id + '_composites'] !== 'undefined') {
1604							target_facet = id + '_composites';
1605						}
1606						if (sphf.showFacet(target_facet) && (typeof sphf.facets[target_facet] === 'undefined' || typeof sphf.facets[target_facet][item] === 'undefined')) {
1607							classnores = ' activ_no_res';
1608							titlenores = '. ' + sphf.langs.activ_no_res;
1609						}
1610					}
1611
1612					// V skupine zobrazime aj text hodnoty
1613					if (is_select) {
1614						sphf.elems.filter_group[id].find('.filter_title_current').html(item_title);
1615					}
1616
1617					var itmo = jQuery('<span/>');
1618					var itmi = jQuery('<span/>');
1619					var itmd = jQuery('<span/>');
1620
1621					itmo.attr('class', 'activ_item'+classnores);
1622					itmo.html(item_title + '<span class="item_remove"></span>');
1623					itmo.attr('title', sphf.langs.remove_value + titlenores);
1624					itmo.data('param_value', item);
1625					itmo.data('param_group', id);
1626
1627					if (sphf.setting.group_active == 0) {
1628						itmo.prepend(grp.clone());
1629					}
1630
1631					div.append(itmo);
1632
1633					itmd.attr('class', 'item_remove');
1634					itmd.data('param_value', item);
1635					itmd.data('param_group', id);
1636
1637					itmi.attr('class', 'fp_activ_item');
1638					itmi.append(item_title);
1639					itmi.append(itmd);
1640
1641					// Zoznam aktivnych poloziek v skupine
1642					group_selected.append(itmi);
1643				});
1644
1645				// Globalny zoznam poloziek
1646				if (items_filled) {
1647
1648					if (group_selected.is(':hidden')) {
1649						group_selected.slideDown(250);
1650					}
1651					sphf.obj.activ.append(div);
1652					if (items_filled > items_extracted) {
1653						sphf.elems.filter_group[id].addClass('is_picked');
1654					}
1655					active_filled = true;
1656				}
1657			} else {
1658
1659				if ( !sphf.setting.selected_def ){
1660
1661					group_selected.hide();
1662				}
1663
1664			}
1665		});
1666
1667		let html = '';
1668		let total = sphf.getTotal();
1669		let total_base = sphf.getTotalBase();
1670
1671		// Tlacidlo pre filter v administracii
1672		sphf.toggleAdfilterButton(active_filled && total > 0 && is_admin());
1673
1674		if (active_filled){
1675
1676			if (total < 0){
1677
1678				active_wrap.addClass('fp_loading');
1679				html += sphf.langs.filter_active+'<span class="filter_result">'+sphf.langs.filtering+'</span>';
1680			} else if (total == 0){
1681
1682				html += sphf.langs.filter_active+'<span class="filter_result no_results">'+sphf.langs.no_results+'</span>';
1683			} else if (total == 1){
1684
1685				html += sphf.langs.filter_active+'<span class="filter_result">';
1686				html += '<span class="txt_pre">'+sphf.langs.found1+'</span><span class="found">1</span><span class="txt_aft">'+sphf.langs.result_1+'</span>';
1687				html += '</span>';
1688			} else if(total > 1 && total < 5){
1689
1690				html += sphf.langs.filter_active+'<span class="filter_result">';
1691				html += '<span class="txt_pre">'+sphf.langs.found2+'</span><span class="found">'+total+'</span><span class="txt_aft">'+sphf.langs.result_2+'</span>';
1692				html += '</span>';
1693			} else {
1694
1695				html += sphf.langs.filter_active+'<span class="filter_result">';
1696				html += '<span class="txt_pre">'+sphf.langs.found3+'</span><span class="found">'+total+'</span><span class="txt_aft">'+sphf.langs.result_3+'</span>';
1697				html += '</span>';
1698			}
1699
1700			active_info = jQuery('<span class="filter_result_info">').html(html);
1701
1702			// TODO: @Mato zatial nechce vypisovat ziadnu hlasku
1703			if ( typeof sphf.stats.filtering !== 'undefined' && typeof sphf.stats.filtering.adjust !== 'undefined' ){
1704				adjust_info = jQuery('<div>').addClass('filter_adjust_info').html('');
1705			}
1706
1707			if ( !sphf.insertElem('results_info', active_info) ){
1708				active_wrap.html(active_info);
1709			}
1710
1711			if ( !sphf.insertElem('filter_active', active_wrap) ){
1712				sphf.obj.activ.prepend(active_wrap);
1713			}
1714			sphf.obj.activ.append('<div class="cleaner"><!-- &nbsp; --></div>');
1715			sphf.obj.activ.append('<a href="javascript:void(0);" class="fp_active_reset">
1715'+sphf.langs.remove_all_filters+'</a>');
1716			sphf.obj.activ.removeClass('is_empty');
1717		} else if (sphf.setting.show_total){
1718
1719			if (total > 0) {
1720
1721				let inflex = sphf.getInflex('total_', total);
1722
1723				active_wrap.html(sphf.langs[inflex].replace('{total}', '<span>' + total + '</span>'));
1724
1725				if (!sphf.insertElem('filter_active', active_wrap)) {
1726					sphf.obj.activ.prepend(active_wrap);
1727				}
1728			}
1729		}
1730
1731		// Info o celkom najdenych
1732		if (total >= 0) {
1733			let current = total;
1734			// Pre virtualne varianty musime dat total_base zoskupeny pocet
1735			if (!active_filled) {
1736				total_base = total;
1737			}
1738			if (total === total_base) {
1739				current = sphf.langs.all;
1740			}
1741
1742			total_info = jQuery('<span class="filter_total_info">').html('<span class="filter_total_current">' + current + '</span> ' + sphf.langs.from + ' <span class="filter_total_final">' + total_base + '</span>');
1743
1744			if (!sphf.insertElem('filter_total', total_info)) {
1745				sphf.obj.activ.prepend(total_info);
1746			}
1747		}
1748
1749		if (active_filled) {
1750			sphf.obj.module.addClass('has_active_items');
1751		} else {
1752			sphf.obj.module.removeClass('has_active_items');
1753		}
1754
1755		// Callback po renderovani aktivnych parametrov
1756		sphf.options.onActiveRender.call('undefined', sphf.obj.activ);
1757	},
1758	/**
1759	 * Inicializuje tlacidlo pre nastavenie filtra v administracii
1760	 */
1761	initAdfilterButton: function(){
1762		if (sphf.debug){ csstack('initAdfilterButton'); }
1763
1764		if (!is_admin()) {
1765			return;
1766		}
1767
1768		sphf.adfilter_btn = jQuery('<div>').addClass('adfilter_btn').attr('title',sphf.langs.transfer_to_admin);
1769
1770		sphf.adfilter_btn.on( 'click', sphf.clickAdfilterButton );
1771
1772		sphf.obj.modul.append(sphf.adfilter_btn);
1773	},
1774	/**
1775	 * Specialna funkcia ktora zobrazi tlacidlo pre nastavenie filtra v administracii
1776	 * @param {boolean} show
1777	 */
1778	toggleAdfilterButton: function(show){
1779		if (sphf.debug){ csstack('adfilterButton', [show]); }
1780
1781		if (!sphf.adfilter_btn.length) {
1782			return;
1783		}
1784
1785		if (show) {
1786			sphf.adfilter_btn.addClass('showed');
1787		} else {
1788			sphf.adfilter_btn.removeClass('showed');
1789		}
1790	},
1791	/**
1792	 * Skopiruje ID produktov pre nastavenie filtra v administracii
1793	 */
1794	clickAdfilterButton: function(){
1795		if (sphf.debug){ csstack('clickAdfilterButton'); }
1796
1797		if (!sphf.adfilter_btn.length || sphf.adfilter_btn.hasClass('loading')) {
1798			return;
1799		}
1800
1801		sphf.adfilter_btn.addClass('loading');
1802		sphf.calculate(true);
1803	},
1804	getInflex: function(name, qty) {
1805
1806		if (qty > 5) {
1807			return name + 3;
1808		} else if (qty > 1) {
1809			return name + 2;
1810		} else {
1811			return name + 1;
1812		}
1813	},
1814	getTotal: function () {
1815		if (sphf.debug) {
1816			csstack('getTotal');
1817		}
1818		return typeof sphf.meta.total_found !== 'undefined' ? parseInt(sphf.meta.total_found) : 0;
1819	},
1820	getTotalBase: function () {
1821		if (sphf.debug) {
1822			csstack('getTotalBase');
1823		}
1824		return typeof sphf.base.meta !== 'undefined' && typeof sphf.base.meta.total_found !== 'undefined' ? parseInt(sphf.base.meta.total_found) : 0;
1825	},
1826	resetTotal: function () {
1827		if (sphf.debug) {
1828			csstack('resetTotal');
1829		}
1830
1831		sphf.meta.total_found = -1;
1832	},
1833	changed: function (elem, e) {
1834		if (sphf.debug) {
1835			csstack('changed');
1836		}
1837
1838		if (sphf.csuser) {
1839			sphf.timing.start = sphf.microtime(true);
1840		}
1841
1842		let input = jQuery(elem);
1843		let item = input.closest('.filter_item');
1844		let value = sphf.getValue(input);
1845
1846		if (item.hasClass('filter_option')) {
1847			sphf.toggle(elem, e);
1848		}
1849
1850		let id = (item.hasClass('extracted') ? item.data('id') : input.closest('.filter_group').attr('id'));
1851
1852		if (input.is(':checked') || input.hasClass('is_checked') || (id === 'keywords' && jQuery.trim(value) !== '')) {
1853
1854			item.addClass('item_checked');
1855
1856			if (id === 'keywords') {
1857				sphf.setActive(id, [encodeURIComponent(value)]);
1858			} else {
1859				sphf.setActive(id, encodeURIComponent(value));
1860			}
1861		} else if (typeof sphf.active[id] !== 'undefined') {
1862
1863			item.removeClass('item_checked');
1864
1865			sphf.removeActive(id, value);
1866		}
1867
1868		if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].type === 5) {
1869			sphf.verifyGuide();
1870		}
1871
1872		// Resetujeme celkovy pocet produktov
1873		sphf.resetTotal();
1874
1875		sphf.renderActive();
1876		sphf.changeFilter();
1877
1878	},
1879	/**
1880	 * Vrati aktualnu hodnotu elementu
1881	 * @param elem
1882	 */
1883	getValue: function (elem) {
1884
1885		// Obrazky
1886		if (elem.hasClass('fi_image') || elem.hasClass('fi_image_label')) {
1887			return elem.closest('.filter_item').find('.fi_input').val();
1888		} else {
1889			return elem.val();
1890		}
1891	},
1892	changeFilter: function(){
1893		if (sphf.debug){ csstack('changeFilter'); }
1894
1895		if (sphf.setting.load_type == 0){
1896
1897			sphf.calculate();
1898		} else {
1899
1900			if (sphf.setting.load_delay > 0){
1901
1902				if (typeof sphf.timeout.browse !== 'undefined' && sphf.timeout.browse > 0){ return; }
1903
1904				sphf.timeout.browse = setTimeout(function (){
1905
1906					sphf.browse();
1907				}, sphf.setting.load_delay);
1908			} else {
1909
1910				sphf.browse();
1911			}
1912		}
1913	},
1914	/**
1915	 * Spustene po kliku na tlacidlo sortovania
1916	 * @param {string} by Fixne stanoveny kod sortovania v sphf.order_list
1917	 * @param {boolean} passive True ak sa maju html polozky iba oznacit bez samotneho spustenia strankovania
1918	 */
1919	sort: function(by, passive) {
1920		if (sphf.debug){ csstack('sort', [by,passive]); }
1921
1922		var select = jQuery('select[name="orderby"]');
1923		var orderdir = jQuery('input[name="DescOrderBy"]');
1924
1925		for (var i in sphf.order_list) {
1926
1927			if (!sphf.order_list.hasOwnProperty(i) || sphf.order_list[i] !== by) {
1928				continue;
1929			}
1930
1931			// force setnutie radenia iba ak menime typ radenia
1932			if (typeof sphf.config.browse_default_orderby[by] !== 'undefined' && ( (sphf.setting.sorttype && select.val() !== i) || (!sphf.setting.sorttype && sphf.flags.orderby_change) ) ) {
1933				orderdir.val(sphf.config.browse_default_orderby[by]);
1934				sphf.pagination.DescOrderBy = sphf.config.browse_default_orderby[by];
1935			}
1936
1937			select.val(i);
1938
1939			if (sphf.setting.sorttype) {
1940				let allLinks = sphf.sortwrap.find('a');
1941				let activeLink = sphf.sortwrap.find('.sort_type_' + sphf.order_list[i]);
1942
1943				allLinks.removeClass('active');
1944				activeLink.addClass('active');
1945
1946				if (config('js_CS_Config_wcag')) {
1947					allLinks.attr('aria-pressed', 'false');
1948					activeLink.attr('aria-pressed', 'true');
1949				}
1950			}
1951
1952			if (passive !== true) {
1953				select.trigger('change');
1954			}
1955
1956			break;
1957		}
1958	},
1959	/**
1960	 * Podla aktualne nastavenych hodnot zapise cookie
1961	 */
1962	updateCookie: function(){
1963		if (sphf.debug){ csstack('updateCookie'); }
1964
1965		let active = sphf.encodeActive();
1966
1967		let values = [];
1968		values.push(sphf.order_list[sphf.pagination.orderby]);
1969		values.push((sphf.pagination.DescOrderBy === 'ASC' ? 'a' : 'd'));
1970		values.push(sphf.pagination.limit);
1971		values.push(sphf.pagination.limitstart);
1972
1973		// Hodnoty filtra
1974		if (active !== '') {
1975			values.push(active);
1976		}
1977
1978		// Ulozenie do cookie pre navrat na stranku, musi byt cookie aby php vratilo pozadovane vysledky pri prvom requeste
1979		if (sphf.url.path !== '' && sphf.url.path !== '/') {
1980			Cookies.set('sphf_filter', values.join(','), { path: sphf.url.path });
1981		}
1982	},
1983	/**
1984	 * Pouzivane pri popstate eventoch pre aktualizovanie html elementov filtra
1985	 * @param {string} id
1986	 */
1987	updateHtml: function(id){
1988		if (sphf.debug){ csstack('updateHtml', [id]); }
1989
1990		if (typeof sphf.elems.filter_group[id] === 'undefined' || id === 'keywords'){ return; }
1991
1992		// Reset poloziek, ktore uz nepatria medzi aktivne zvolene
1993		if (sphf.elems.filter_group[id].hasClass('is_range')){
1994
1995			if (typeof sphf.active[id] !== 'undefined'){
1996
1997				var verge = sphf.scaleMinMax(id);
1998				var range = sphf.elems.filter_group[id].range_slider.slider("values");
1999				var scope = (typeof sphf.active[id] !== 'undefined' ? [sphf.active[id][0],sphf.active[id][1]] : verge);
2000				var minmax = [sphf.elems.filter_group[id].range_slider.slider("option","min"), sphf.elems.filter_group[id].range_slider.slider("option","max")];
2001
2002				if (sphf.debug) {
2003					console.log('-scope orig: '+JSON.stringify(scope));
2004					console.log('-range orig: '+JSON.stringify(range));
2005				}
2006
2007				if (typeof sphf.scales[id] !== 'undefined') {
2008					scope = sphf.scaleValueToKey(id, scope);
2009					range = sphf.scaleKeyToValue(id, range);
2010				}
2011
2012				if (sphf.debug){
2013					console.log('-scope: '+JSON.stringify(scope));
2014					console.log('-range: '+JSON.stringify(range));
2015					console.log('-verge: '+JSON.stringify(verge));
2016					console.log('-minmax: '+JSON.stringify(minmax));
2017				}
2018
2019				if (verge[0] != minmax[0] || verge[1] != minmax[1]){
2020
2021					sphf.setMinMax(id, verge);
2022
2023					if (sphf.debug) {
2024						console.log('setting slider ' + id + ' to:', scope);
2025					}
2026					sphf.elems.filter_group[id].range_slider.slider("values", 0, scope[0]);
2027					sphf.elems.filter_group[id].range_slider.slider("values", 1, scope[1]);
2028
2029					sphf.rangeText(scope, id);
2030				} else if (scope[0] != range[0] || scope[1] != range[1]){
2031
2032					if (sphf.debug) {
2033						console.log('setting slider ' + id + ' to:', scope);
2034					}
2035					sphf.elems.filter_group[id].range_slider.slider("values", 0, scope[0]);
2036					sphf.elems.filter_group[id].range_slider.slider("values", 1, scope[1]);
2037
2038					sphf.rangeText(scope, id);
2039				}
2040			} else {
2041
2042				sphf.resetSlider(id, false);
2043			}
2044		} else {
2045
2046			// Reset poloziek
2047			sphf.elems.filter_group[id].find('.item_checked').each(function(){
2048
2049				var value = parseInt(jQuery(this).find('.fi_input').val());
2050
2051				if (typeof sphf.active[id] === 'undefined' || sphf.active[id].indexOf(value) === -1) {
2052
2053					sphf.resetItem(id, value);
2054				}
2055			});
2056
2057			// Oznacenie poloziek ktore su v active
2058			if (typeof sphf.active[id] !== 'undefined'){
2059
2060				jQuery.each(sphf.active[id], function(c, value){
2061
2062					sphf.setItem(id, value);
2063				});
2064			}
2065		}
2066	},
2067	/**
2068	 * Zaznamenanie custom atributov u elementov
2069	 */
2070	scanElements: function(){
2071		if (sphf.debug){ csstack('scanElements'); }
2072
2073		let inp;
2074		let val;
2075
2076		sphf.attribs = [];
2077
2078		// Luigisbox data-action
2079		inp = sphf.obj.content.find('input.categ_add_to_cart:first');
2080		val = inp.data('action');
2081		if (typeof val !== 'undefined' && val !== null){
2082			sphf.attribs.push({target:'input.categ_add_to_cart', attr:'data-action', value: val});
2083		}
2084	},
2085	/**
2086	 * Obcestvenie custom atributov u elementov
2087	 */
2088	enhanceElements: function(){
2089		if (sphf.debug){ csstack('enhanceElements'); }
2090
2091		if (sphf.attribs.length){
2092
2093			for(let i=0; i<sphf.attribs.length; i++){
2094
2095				let elems = sphf.obj.content.find(sphf.attribs[i].target);
2096				if (elems.length){
2097
2098					elems.attr(sphf.attribs[i].attr, sphf.attribs[i].value);
2099				}
2100			}
2101		}
2102	},
2103	/**
2104	 * Vrati iba prepocitane facety bez vysledkov hladania, podla nastaveneho filtra
2105	 * @param {boolean} [adfilter] Vrati link do administracie
2106	 */
2107	calculate: function(adfilter){
2108		if (sphf.debug){ csstack('calculate', [adfilter]); }
2109
2110		sphf.createPing();
2111
2112		var start = 0;
2113		var options = {};
2114
2115		options.is_calculate = 1;
2116		options.is_adfilter = (adfilter ? 1 : 0);
2117		options.href = window.location.href;
2118		options.category_id = sphf.cid;
2119		options.cache_enabled = sphf.cache;
2120		options.filter = JSON.stringify(sphf.active);
2121		options.pingcode = sphf.pingcode;
2122		options.orderby = sphf.pagination.orderby;
2123		options.DescOrderBy = sphf.pagination.DescOrderBy;
2124
2125		if (sphf.csuser){
2126			start = sphf.microtime(true);
2127		}
2128
2129		new AjaxRequest({
2130			'module_id': sphf.mid,
2131			'request': options
2132		})
2133			.setController("Filter")
2134			.setAction('calculate')
2135			.onSuccess(function (jsonData) {
2136
2137				if (sphf.csuser) {
2138					sphf.timing.request = sphf.microtime(true) - start;
2139				}
2140
2141				if (typeof jsonData.data !== 'undefined') {
2142
2143					if (adfilter) {
2144
2145						sphf.adfilter_btn.removeClass('loading');
2146						window.open(jsonData.data.data.admin_link, '_blank');
2147					} else {
2148
2149						sphf.setData(jsonData.data.data);
2150
2151						// Renderovanie poloziek pre sprievodcu
2152						if (sphf.guide.length) {
2153							sphf.renderGuide();
2154						}
2155
2156						// Callback pri vyrenderovani obsahu
2157						sphf.options.onCalculateRequest.call();
2158
2159						sphf.postRender();
2160					}
2161				}
2162			})
2163			.onError(function (response) {
2164
2165			})
2166			.send();
2167	},
2168	/**
2169	 * Vrati vysledky pre akukolvek akciu vo filtri, strankovani, zmeny order by...
2170	 */
2171	browse: function(el, popstate){
2172		if (sphf.debug){ csstack('browse', [typeof el,popstate]); }
2173
2174		var elem = jQuery(el);
2175
2176		if (sphf.csuser) {
2177			sphf.timing.start = sphf.microtime(true);
2178		}
2179
2180		sphf.flags.orderby_change = false;
2181
2182		if (!popstate && sphf.urlfilter === '') {
2183			sphf.paginator(elem);
2184		}
2185
2186		sphf.updateCookie();
2187		sphf.createPing();
2188		sphf.scanElements();
2189
2190		var options = {
2191			is_sphf: '1',
2192			option: 'com_shop',
2193			page: 'shop.browse',
2194			Itemid: '1040',
2195			category_id: sphf.cid,
2196			module_id: sphf.mid,
2197			cache_enabled: sphf.cache,
2198			no_html: '1',
2199			no_css: '1',
2200			no_menu: '1',
2201			no_vm_html: '1',
2202			sef_rewrite_index2_index: '1',
2203			limit: sphf.pagination.limit,
2204			limitstart: sphf.pagination.limitstart,
2205			orderby: sphf.pagination.orderby,
2206			DescOrderBy: sphf.pagination.DescOrderBy,
2207			filter: JSON.stringify(sphf.active),
2208			urlfilter: sphf.urlfilter,
2209			pingcode: sphf.pingcode
2210		};
2211
2212		if (sphf.simple_paging && sphf.pagination.pagestart > 0 && sphf.pagination.pageend > 0) {
2213			options.simple_paging = 1;
2214			options.pagestart = sphf.pagination.pagestart;
2215			options.pageend = sphf.pagination.pageend;
2216		}
2217
2218		// Pripneme forced filtre, ktore sa nastavia v php kode
2219		if (!jQuery.isEmptyObject(sphf.forced)) {
2220			jQuery.each(sphf.forced, function (c, v) {
2221				options[c] = v;
2222			});
2223		}
2224
2225		// Musime zaslat spat povodne meta udaje, kedze tie sa nespravne alebo neskoro generuju na frontende
2226		if (typeof sphf.seo.page !== 'undefined') {
2227			if (typeof sphf.seo.page.title_orig !== 'undefined') options.title_orig = sphf.seo.page.title_orig;
2228			if (typeof sphf.seo.page.h1_orig !== 'undefined') options.h1_orig = sphf.seo.page.h1_orig;
2229		}
2230
2231		var loaded = false;
2232
2233		if (sphf.simple_paging) {
2234			sphf.obj.pagbtn.append('<span class="featureprod_ajax_loader"></span>');
2235		} else {
2236
2237			sphf.scroll(elem, function () {
2238				if (!loaded) {
2239					sphf.obj.products.append('<span class="featureprod_ajax_loader"></span>');
2240				}
2241			});
2242		}
2243
2244		sphf.obj.products.addClass('prod_ajax_loader_overlay');
2245
2246		if (sphf.csuser){ var start = sphf.microtime(true); }
2247
2248		jQuery.post(js_global_live_site+'/index2.php', options)
2249			.done(function(res){
2250
2251				loaded = true;
2252
2253				sphf.obj.products.removeClass('prod_ajax_loader_overlay');
2254
2255				if (typeof sphf.obj.pagbtn !== 'undefined' && sphf.obj.pagbtn !== null && sphf.obj.pagbtn.length){
2256
2257					sphf.obj.pagbtn.remove();
2258					sphf.obj.pagbtn = null;
2259				}
2260
2261				if (sphf.csuser){ sphf.timing.request = sphf.microtime(true) - start; }
2262
2263				let result = csJsonParse(res, function(jso_err){
2264					sphf.reloadRequest(elem, jso_err);
2265				});
2266
2267				// Neplatne JSON, mozno chyba v poziadavke alebo nedostupny node
2268				if (result === null) {
2269					return;
2270				}
2271
2272				// Musi byt za JsonParse inak sa zacykluje v pripade chyby
2273				sphf.atempts = 0;
2274
2275				// Clear timeout
2276				if (sphf.setting.load_delay > 0 && typeof sphf.timeout.browse !== 'undefined' && sphf.timeout.browse !== null){
2277
2278					clearTimeout(sphf.timeout.browse);
2279					sphf.timeout.browse = 0;
2280				}
2281
2282				sphf.setData(result.data);
2283
2284				// Ak mame prazdny vysledok pripneme oznamenie
2285				if (typeof result.content !== 'undefined' && result.content.length > 0){
2286
2287					if (sphf.simple_paging) {
2288
2289						// Presun obsahu quarticOn
2290						var qONtxt = '';
2291						var qONold = sphf.obj.products.find('.qON_category_wrap');
2292						if (qONold.length) {
2293							qONtxt = qONold.html();
2294						}
2295
2296						if (sphf.obj.products.find('.browse_listing_wrapper_upper').length > 0) {
2297							// Ak ide o riadkovy vypis Vytvoríme jQuery objekt z obsahu
2298							let $content = jQuery(result.content);
2299							// Vytiahneme vsetky tr elementy
2300							let $rows = $content.find('tr:not(.browse_listing_header)');
2301							// Appendneme nove tr elementy k starym do uz existujucej tabulky
2302							sphf.obj.products.find('table tbody').append($rows);
2303						} else {
2304							sphf.obj.products.append(result.content);
2305						}
2306
2307						if (qONold.length) {
2308
2309							let qONnew = sphf.obj.products.find('.qON_category_wrap');
2310							if (qONnew.length && qONtxt != '') {
2311								qONnew.append(qONtxt);
2312								qONold.remove();
2313							}
2314						}
2315					} else {
2316						if (sphf.last_list_cat.enabled) {
2317							sphf.obj.content.html(result.content);
2318						} else {
2319							sphf.obj.products.html(result.content);
2320						}
2321					}
2322				} else {
2323
2324					if (sphf.last_list_cat.enabled) {
2325						sphf.obj.content.html(result.message);
2326					} else {
2327						sphf.obj.products.html(result.message);
2328					}
2329				}
2330
2331				if (typeof result.navigation === 'string'){
2332
2333					sphf.obj.navtop.html(result.navigation).removeClass('no_pagination');
2334					sphf.obj.navbot.html(result.navigation).removeClass('no_pagination');
2335				} else {
2336
2337					sphf.obj.navtop.html('').addClass('no_pagination');
2338					sphf.obj.navbot.html('').addClass('no_pagination');
2339				}
2340
2341				// Renderovanie poloziek pre sprievodcu
2342				if (sphf.guide.length){
2343					sphf.renderGuide();
2344				}
2345
2346				// Zmena URL,TITLE,H1
2347				sphf.buildSeo(popstate,result.custom_browse_title);
2348
2349				// Quirk mod, dokoncenie aktivnych poloziek
2350				if (sphf.urlfilter !== '' || (sphf.urlfilter === '' && !sphf.obj.activ.hasClass('is_empty'))) {
2351
2352					sphf.urlfilter = '';
2353					sphf.checkActive();
2354				}
2355
2356				sphf.renderActive();
2357
2358				// Callback pri vyrenderovani obsahu
2359				sphf.options.onBrowseRequest.call();
2360
2361				window.dispatchEvent(sphf.events.onBrowseRequest);
2362
2363				// Osetrenie pri prichode na stranku s prazdnymi vysledkami nemame wrapper s produktami vykresleny
2364				if ( !sphf.obj.products.length ) {
2365					window.location.reload();
2366				}
2367
2368				sphf.postRender(true);
2369			})
2370			.fail( function(xhr, textStatus){
2371
2372				loaded = true;
2373
2374				sphf.reloadRequest(elem, textStatus);
2375			});
2376	},
2377	/**
2378	 * V pripade zlyhania poziadavky skusime este raz
2379	 */
2380	reloadRequest: function(elem, textStatus){
2381		if (sphf.debug){ csstack('reloadRequest', [textStatus]); }
2382		if (sphf.atempts === 0){
2383
2384			if (sphf.debug){ console.log('    ERROR: Ajax has failed with message: '+textStatus+'. Reload atempt...'); }
2385			sphf.atempts = 1;
2386			setTimeout(function(){
2387				sphf.browse(elem);
2388			}, 1500);
2389		} else {
2390
2391			if (sphf.debug){ console.log('    ERROR: Ajax has failed. ['+textStatus+']'); }
2392
2393			// Reset do standard stavu + sprava
2394			sphf.atempts = 0;
2395			sphf.obj.products.html('<div class="sphf_err_msg">'+sphf.langs.net_err+'</div>');
2396			sphf.obj.products.removeClass('prod_ajax_loader_overlay');
2397		}
2398	},
2399	/**
2400	 * Replacne url s hodnotami strankovania a filtra, zaroven nastavi cookie pre scripty na serveri
2401	 * @param elem
2402	 * @param start
2403	 */
2404	paginator: function(elem, start){
2405		if (sphf.debug){ csstack('paginator', [start]); }
2406
2407		if (typeof start == 'undefined'){ start = -1; }
2408
2409		// Klik na polozku strankovania, ziskame limitstart.
2410		if (typeof elem !== 'undefined' && elem !== ''){
2411
2412			if (elem.attr('id') === 'orderby'){
2413
2414				sphf.flags.orderby_change = true;
2415			} else if (elem.hasClass('pagenav')){
2416
2417				start = sphf.getPage(elem.attr('class'), 'start');
2418
2419				sphf.pagination.limitstart = start;
2420			} else if (elem.hasClass('orderby_img')){
2421
2422				if (elem.hasClass('ASC')) elem.hide().next().show();
2423				else elem.hide().prev().show();
2424			}
2425		}
2426
2427		// Aktualne hodnoty limitstart, orderby, orderdir, limit
2428		sphf.buildPagination(start);
2429	},
2430	/**
2431	 * Vrati objekt obsahujuci aktualne nastavenie sphf prostredia. Pouzivane pri funkciach popstate
2432	 */
2433	getState: function(){
2434
2435		var r = {};
2436
2437		r.pagination = sphf.pagination;
2438		r.filter = sphf.active;
2439		r.urlfilter = sphf.urlfilter;
2440
2441		return r;
2442	},
2443	/**
2444	 * Nastavenie sphf prostredie podla poskytnutych data
2445	 */
2446	setState: function(data){
2447
2448		sphf.pagination = data.pagination;
2449		sphf.active = data.filter;
2450		sphf.urlfilter = data.urlfilter;
2451
2452		// Musime zmazat cookie, lebo nemusi byt kompatibilna s predchadzajucou strankou
2453		//if (sphf.url.path != '' && sphf.url.path != '/') Cookies.set('sphf_filter', '', { path: sphf.url.path });
2454	},
2455	getPage: function(classes, type){
2456		if (sphf.debug){ csstack('getPage', [classes,type]); }
2457
2458		var value = 0;
2459
2460		if (typeof classes == 'string'){
2461
2462			var regex = new RegExp(type+'_(\\d+)', "i");
2463			var classList = classes.split(/\s+/);
2464
2465			jQuery.each(classList, function(index, item) {
2466				var record = regex.exec(item);
2467				if (record !== null && typeof record[1] !== 'undefined' && parseInt(record[1], 10) > 0){
2468					value = parseInt(record[1], 10);
2469				}
2470			});
2471		}
2472
2473		return value;
2474	},
2475	buildPagination: function(start){
2476		if (sphf.debug){ csstack('buildPagination', [start]); }
2477
2478		var page = 0;
2479
2480		// Pri inicializacii filtra nemame start, a musime ho ziskat z html
2481		if (typeof start == 'undefined') {
2482			var active = sphf.obj.navbot.find('.pagenav.pn_active');
2483
2484			if (active.length > 0) {
2485				page = sphf.getPage(active.attr('class'), 'page');
2486			} else {
2487				start = 0;
2488			}
2489		}
2490
2491		// Pri zmene filtra start == -1 ,setneme vzdy start na 0, inak to robi paseku ak sme na 10 strane a mame vysledky iba na 3
2492		if (start < 0) {
2493			start = 0;
2494		}
2495
2496		var orderby = jQuery('select[name="orderby"] option:selected');
2497		var orderdir = jQuery('input[name="DescOrderBy"]');
2498		var limit = jQuery('select[name="limit"] option:selected');
2499
2500		if (orderby.length > 0) {
2501			sphf.pagination.orderby = orderby.val();
2502		} else {
2503			sphf.pagination.orderby = 'vm_product.product_name';
2504		}
2505
2506		if (orderdir.length > 0) {
2507			sphf.pagination.DescOrderBy = ((orderdir.val() === 'ASC') ? 'ASC' : 'DESC');
2508		} else {
2509			sphf.pagination.DescOrderBy = 'ASC';
2510		}
2511
2512		if (limit.length > 0) {
2513			sphf.pagination.limit = limit.html().replace(/&nbsp;/gi,'');
2514		}
2515
2516		// Forcnutie DESC
2517		var order_code = (typeof sphf.order_list[sphf.pagination.orderby] !== 'undefined' ? sphf.order_list[sphf.pagination.orderby] : '');
2518
2519		var default_order_by = '';
2520
2521		// force setnutie radenia iba ak menime typ radenia
2522		if (sphf.flags.orderby_change && typeof sphf.config.browse_default_orderby[order_code] !== 'undefined') {
2523			default_order_by = sphf.config.browse_default_orderby[order_code];
2524		}
2525
2526		if (sphf.order_list_desc.indexOf(order_code) !== -1 || default_order_by === 'DESC') {
2527
2528			sphf.pagination.DescOrderBy = 'DESC';
2529
2530			// Setneme ikony na spravne hodnoty
2531			if (orderdir.val() === 'ASC') {
2532				orderdir.val('DESC');
2533				jQuery('.orderby_img.ASC').hide();
2534				jQuery('.orderby_img.DESC').show();
2535			}
2536		}
2537
2538		// Forcnutie ASC
2539		if (sphf.order_list_asc.indexOf(order_code) !== -1 || default_order_by === 'ASC' || (sphf.pagination.orderby === 'vm_product.category_ordering' && sphf.setting.sorttype === 1 && sphf.config.simple_orderby_fields_type)) {
2540			sphf.pagination.DescOrderBy = 'ASC';
2541
2542			// Setneme ikony na spravne hodnoty
2543			if (orderdir.val() === 'DESC') {
2544
2545				orderdir.val('ASC');
2546				jQuery('.orderby_img.ASC').show();
2547				jQuery('.orderby_img.DESC').hide();
2548			}
2549		}
2550
2551		sphf.pagination.limitstart = (page > 0 ? ((page - 1) * sphf.pagination.limit) : start);
2552	},
2553	simplePaging: function () {
2554		if (sphf.debug) {
2555			csstack('simplePaging');
2556		}
2557
2558		sphf.simple_paging = 1;
2559		sphf.obj.pagbtn.addClass('active');
2560
2561		var page = 1;
2562		var active = sphf.obj.navbot.find('.pagenav.pn_active');
2563
2564		if (active.length > 0) {
2565			page = sphf.getPage(active.attr('class'), 'page');
2566		}
2567
2568		if (typeof sphf.stats.global.pagination.pagestart !== 'undefined' && sphf.stats.global.pagination.pagestart > 0) {
2569			sphf.pagination.pagestart = sphf.stats.global.pagination.pagestart;
2570		}
2571
2572		if (sphf.pagination.pagestart === null || sphf.pagination.pagestart === 0) {
2573			sphf.pagination.pagestart = page;
2574		}
2575
2576		sphf.pagination.pageend = page + 1;
2577		sphf.pagination.limitstart = (page - 1) * sphf.pagination.limit;
2578
2579		sphf.browse();
2580	},
2581	/**
2582	 * Z aktivnych poloziek filtra, zostavi seo klucove slova a vlozi ich do stranky na miesta <title> <h1>
2583	 */
2584	buildSeo: function(popstate, customBrowseTitle = undefined){
2585		if (sphf.debug){ csstack('buildSeo',[popstate]); }
2586
2587		var title = '';
2588
2589		// Replace <title>
2590		if (sphf.seo.change_title === 1){
2591
2592			if (sphf.seo.keywords.title !== ''){ title = sphf.seo.page.title_clean.replace('{seo}', sphf.seo.keywords.title); }
2593			else { title = sphf.seo.page.title_orig; }
2594
2595			if (typeof customBrowseTitle !== 'undefined') {
2596				title = customBrowseTitle;
2597			}
2598
2599			jQuery('head title').text(title);
2600		}
2601
2602		// Replace <h1>
2603		if (sphf.seo.change_h1 === 1 && !sphf.last_list_cat.enabled) {
2604
2605			if (sphf.seo.keywords.h1 !== '') {
2606				title = sphf.seo.page.h1_clean.replace('{seo}', sphf.seo.keywords.h1);
2607			} else {
2608				title = sphf.seo.page.h1_orig;
2609			}
2610
2611			// Musi byt direct child, inak to prepisuje texty pri fnc last_list_cat
2612			jQuery('.middle_content_inner > .shop_browse_category_h2').text(title);
2613			jQuery('.shop_browse_category_title').text(title);
2614		}
2615
2616		// Replace URL
2617		if (!popstate) {
2618
2619			var state = {urlPath: sphf.seo.url, sphf_state: sphf.getState()};
2620
2621			if (sphf.debug) {
2622				console.log('   pushing history state...', state);
2623			}
2624			history.pushState(state, null, sphf.seo.url);
2625		}
2626
2627		if (typeof customBrowseTitle !== 'undefined') {
2628			let canonicalTag = document.querySelector("link[rel='canonical']");
2629			if (canonicalTag) {
2630				canonicalTag.href = sphf.seo.url;
2631			}
2632		}
2633
2634
2635		// Aktualizacia url odkazu na filter
2636		sphf.updateLink();
2637	},
2638	/**
2639	 * Overi ci ma skupina povolene vytvarat seo url adresy
2640	 */
2641	isSeoGroup: function (group) {
2642
2643		if (typeof sphf.seo.group_select == 'undefined' || sphf.seo.group_select.length == 0) {
2644			return true;
2645		}
2646
2647		var is = false;
2648
2649		jQuery.each(sphf.seo.group_select, function (c, v) {
2650			if (group.search(v) > -1) {
2651				is = true;
2652			}
2653		});
2654
2655		return is;
2656	},
2657	/**
2658	 * Pre kazdy request nastavi kontrolny ping ktory vrati spat metodka getData v php. Podla neho vieme ci su statistiky realtime alebo cachovane
2659	 */
2660	createPing: function () {
2661		if (sphf.debug) {
2662			csstack('createPing');
2663		}
2664
2665		var code = [];
2666		var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2667
2668		for (var i = 0; i < 6; i++) {
2669
2670			code.push(possible.charAt(Math.floor(Math.random() * possible.length)));
2671		}
2672		sphf.pingcode = code.join('');
2673	},
2674	cleanUrl: function(){
2675		if (sphf.debug){ csstack('cleanUrl'); }
2676
2677		var path = [];
2678		var parts = '';
2679		var valid = false;
2680
2681		// Odstranime z url strankovaciu cast, ktoru neskor zlozime
2682		var parser = document.createElement('a');
2683		parser.href = window.location.href;
2684
2685		//parser.protocol;  => "http:"
2686		//parser.host;      => "example.com:3000"
2687		//parser.hostname;  => "example.com"
2688		//parser.port;      => "3000"
2689		//parser.pathname;  => "/pathname/"
2690		//parser.hash;      => "#hash"
2691		//parser.search;    => "?search=test"
2692		//parser.origin;    => "http://example.com:3000"
2693
2694		if (parser.pathname != ''){
2695
2696			var regex = new RegExp('\\S{1,2},\\S{1,2},\\d+,\\d+', "i");
2697			parts = parser.pathname.split('/');
2698
2699			for(var i = 0; i < parts.length; i++){
2700
2701				if (parts[i] != '' && parts[i] !== 'undefined'){
2702
2703					var match = regex.exec(parts[i]);
2704					if (match == null){ path.push(parts[i]); }
2705				}
2706			}
2707		}
2708
2709		var urlpath = ((path.length > 0) ? ('/' + path.join('/') + '/') : '/');
2710		sphf.url.seo = '';
2711		sphf.url.path = urlpath;
2712		sphf.url.hash = parser.hash;
2713		sphf.url.clean = parser.protocol + '//' + parser.hostname + urlpath;
2714		sphf.url.search = parser.search;
2715		sphf.url.replace = parser.protocol + '//' + parser.hostname + urlpath + '{seo}{paginator}/' + parser.search;
2716
2717		// Ak mame v url # ktory je naplnany v quirk modu pre starsie browsre tak server nenaplnil premennu sphf.active.
2718		// Musime ju naplnit tu a znova zaslat request na server pre spravne filtrovanie a strankovanie produktov
2719		// Je to preto lebo browsere nezasielaju hash tag na server, a vidime ho iba cez js
2720		var hash = sphf.getHashValue();
2721		if (hash !== '') {
2722
2723			// Naozaj je v hash to spravne strankovanie?
2724			var orderby = '';
2725			var orderdir = 'ASC';
2726			var limit = '';
2727			parts = hash.split(',');
2728			if (parts.length > 2) {
2729
2730				// Sort by
2731				jQuery.each(sphf.order_list, function (c, v) {
2732
2733					if (v == parts[0]) {
2734						orderby = c;
2735						valid = true;
2736						return true;
2737					}
2738				});
2739
2740				// Order dir
2741				if (parts[1] == 'd' || parts[1] == 'l' || parts[1] == 'z') {
2742					orderdir = 'DESC';
2743				}
2744
2745				// Limit
2746				limit = parseInt(parts[2], 10);
2747			}
2748
2749			// Naplnime sphf.active
2750			if (orderby !== '' && limit !== '') {
2751
2752				jQuery('select[name="orderby"]').val(orderby);
2753				jQuery('.orderby_img').hide();
2754				jQuery('.orderby_img.' + orderdir).show();
2755				if (typeof js_CS_Config_orderby_span !== 'undefined') {
2756					jQuery('.orderby_span').removeClass('ASC DESC').addClass(orderdir);
2757				}
2758				jQuery('#limit').val(limit);
2759				if (typeof parts[4] == 'string') {
2760					sphf.urlfilter = parts[4].replace('f:', '');
2761				}
2762			}
2763		}
2764	},
2765	getHashValue: function () {
2766		if (sphf.debug) {
2767			csstack('getHashValue'); }
2768
2769		var keyAndHash = location.hash.toLowerCase().match(new RegExp('#([^&]*)'));
2770		var value = '';
2771
2772		if (keyAndHash) { value = keyAndHash[1]; }
2773
2774		return value;
2775	},
2776	encodeActive: function () {
2777		if (sphf.debug) {
2778			csstack('encodeActive');
2779		}
2780
2781		var r = [];
2782
2783		if (typeof sphf.sorter.groups !== 'undefined') {
2784
2785			jQuery.each(sphf.sorter.groups, function (c, f) {
2786
2787				if (typeof sphf.active[f] === 'undefined') {
2788					return false;
2789				}
2790
2791				var v = sphf.active[f];
2792				var e = '';
2793
2794				jQuery.each(sphf.setting.codes, function (c, p) {
2795
2796					if (f.indexOf(p) > -1) {
2797
2798						e += c + f.replace(p, '') + '-';
2799					}
2800				});
2801
2802				e += v.join('_');
2803				r.push(e);
2804			});
2805		}
2806
2807		return (r.length > 0 ? 'f:' + r.join(';') : '');
2808	},
2809	resetFilter: function () {
2810		if (sphf.debug) {
2811			csstack('resetFilter');
2812		}
2813
2814		if (sphf.csuser) {
2815			sphf.timing.start = sphf.microtime(true);
2816		}
2817
2818		jQuery.each(sphf.active, function (id, v) {
2819
2820			jQuery.each(v, function (r, i) {
2821
2822				sphf.removeActive(id, i);
2823				sphf.resetItem(id, i);
2824			});
2825		});
2826
2827		sphf.active = {};
2828		sphf.sorter = {};
2829
2830		sphf.changeFilter();
2831	},
2832	removeItem: function(elem, delayed){
2833		if (sphf.debug){ csstack('removeItem', [delayed]); }
2834
2835		if (sphf.csuser && typeof delayed == 'undefined'){ sphf.timing.start = sphf.microtime(true); }
2836
2837		var tag = jQuery(elem);
2838
2839		var id = tag.data('param_group');
2840		var value = tag.data('param_value');
2841
2842		if (typeof sphf.elems.filter_group[id] == 'undefined'){ return; }
2843
2844		sphf.removeActive(id, value);
2845		sphf.resetItem(id, value);
2846
2847		if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].type === 5){ sphf.verifyGuide(); }
2848
2849		// Ak odoberame viac poloziek, nasledujuce funkcie sa spustia neskor, pri poslednej odobratej polozke
2850		if (typeof delayed !== 'undefined' && delayed){ return; }
2851
2852		sphf.resetTotal();
2853		sphf.renderActive();
2854		sphf.changeFilter();
2855	},
2856	removeGroup: function (elem) {
2857		if (sphf.debug) {
2858			csstack('removeGroup');
2859		}
2860
2861		if (sphf.csuser) {
2862			sphf.timing.start = sphf.microtime(true);
2863		}
2864
2865		var set = jQuery(elem).closest('.activ_set');
2866
2867		set.find('.activ_item').each(function () {
2868
2869			sphf.removeItem(this, true);
2870		});
2871
2872		sphf.renderActive();
2873		sphf.changeFilter();
2874	},
2875	setActive: function (id, value) {
2876		if (sphf.debug) {
2877			csstack('setActive', [id, value]);
2878		}
2879
2880		if (typeof value === 'object') {
2881
2882			sphf.active[id] = value;
2883		} else {
2884
2885			if (typeof sphf.active[id] === 'undefined') {
2886
2887				sphf.active[id] = [];
2888			}
2889
2890			// Radio polozky
2891			if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].type === 5) {
2892
2893				sphf.active[id] = [value];
2894			}
2895			// Ostatne hodnoty
2896			else if (sphf.active[id].indexOf(value) === -1) {
2897
2898				sphf.active[id].push(value);
2899			}
2900		}
2901
2902		sphf.sortActive();
2903	},
2904	removeActive: function (id, value) {
2905		if (sphf.debug) {
2906			csstack('removeActive', [id, value]);
2907		}
2908
2909		var a = [];
2910
2911		if (typeof sphf.active[id] !== 'undefined') {
2912
2913			// Zmazeme vsetky aktivne polozky v zozname, ktory neskor naplni metodka renderActive()
2914			if (sphf.setting.selected_def == 1) {
2915
2916				var cus_lang = 'js_lang_sphf_pick_text_' + id;
2917				var def_text = (typeof window[cus_lang] !== 'undefined' ? window[cus_lang] : sphf.langs.pick_text);
2918				sphf.elems.filter_group[id].find('.filter_selected').html('<div class="fp_default_item">' + def_text + '</div>');
2919			} else {
2920
2921				sphf.elems.filter_group[id].find('.filter_selected').empty();
2922			}
2923
2924
2925			// Input alebo Slider element
2926			if (id == 'keywords' || value == 0) {
2927
2928				delete sphf.active[id];
2929			}
2930			// Checkbox element
2931			else {
2932
2933				jQuery.each(sphf.active[id], function (c, v) {
2934
2935					if (v == value || typeof v == 'undefined' || v == null) {
2936						return true;
2937					}
2938
2939					a.push(v);
2940				});
2941
2942				if (a.length > 0) {
2943					sphf.active[id] = a;
2944				} else {
2945					delete sphf.active[id];
2946				}
2947			}
2948
2949			sphf.sortActive();
2950		}
2951	},
2952	setItem: function(id, value){
2953		if (sphf.debug){ csstack('setItem', [id,value]); }
2954
2955		var item_id = id + '_' + value;
2956
2957		var input = sphf.elems.filter_group[id].find('#' + item_id);
2958
2959		if (!input.is(':checked')) {
2960
2961			if (id === 'keywords') {
2962
2963				sphf.elems.filter_group[id].find('input').val(decodeURIComponent(value));
2964			} else {
2965
2966				input.attr('checked', 'checked').prop('checked', true).closest('.filter_item').addClass('item_checked');
2967
2968				if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].type == 3) {
2969
2970					input.find('.fi_image, .fi_image_label').addClass('is_checked');
2971				}
2972			}
2973		}
2974
2975		// Ak je tato polozka extractnuta
2976		if (input.hasClass('is_extracted')) {
2977
2978			var ex = sphf.obj.modul.find('#' + input.attr('id') + '_extracted');
2979
2980			if (ex.length) {
2981
2982				ex.attr('checked', 'checked').prop('checked', true).closest('.filter_item').addClass('item_checked');
2983			}
2984		}
2985	},
2986	resetItem: function(id, value){
2987		if (sphf.debug){ csstack('resetItem', [id,value]); }
2988
2989		var type = (typeof sphf.groups[id] !== 'undefined' && typeof sphf.groups[id].type !== 'undefined' ? parseInt(sphf.groups[id].type) : 0);
2990
2991		var input = (type === 4 ? sphf.elems.filter_group[id].find('.fi_input') : sphf.elems.filter_group[id].find('.fi_input[value="' + value + '"]'));
2992
2993		if (type !== 1 && !input.length) {
2994			return;
2995		}
2996
2997		// Input element
2998		if (type === 4){
2999
3000			input.val('');
3001		}
3002		// Slider element
3003		else if (type === 1){
3004
3005			sphf.resetSlider(id, false);
3006		}
3007		// Obrazkovy element
3008		else if (type === 3){
3009
3010			input.attr('checked', false).closest('.filter_item').removeClass('item_checked').find('.fi_image, .fi_image_label').removeClass('is_checked');
3011		}
3012		// Select
3013		else if (type === 5){
3014
3015			input.attr('checked', false).prop('checked', false).closest('.filter_item').removeClass('item_checked');
3016		}
3017		// Checkbox element
3018		else {
3019
3020			input.attr('checked', false).prop('checked', false).closest('.filter_item').removeClass('item_checked');
3021		}
3022
3023		// Ak je tato polozka extractnuta
3024		if (input.length && input.hasClass('is_extracted')){
3025
3026			var ex = sphf.obj.modul.find('#'+input.attr('id')+'_extracted');
3027
3028			if (ex.length){
3029
3030				ex.attr('checked', false).prop('checked', false).closest('.filter_item').removeClass('item_checked');
3031			}
3032		}
3033	},
3034	updateResButton: function(){
3035
3036		if ( typeof sphf.obj.window === 'undefined' || typeof sphf.obj.window.scrollTop !== 'function' ) {
3037			return;
3038		}
3039
3040		var top = sphf.obj.window.scrollTop();
3041
3042		sphf.obj.resbtn.toggleClass('sticky', (top + sphf.wheight) < sphf.resbtntop);
3043	},
3044	/**
3045	 * Spustane po ajax requeste filtrovania
3046	 * @param ajax
3047	 */
3048	postRender: function(ajax){
3049		if (sphf.debug){ csstack('postRender', [ajax]); }
3050
3051		// Tlacidlo zobrazit vysledky
3052		if (parseInt(sphf.setting.show_results) > 0) {
3053			sphf.renderResButton();
3054		}
3055
3056		// Tlacidlo jednoducheho strankovania
3057		if (parseInt(sphf.setting.simple_paging) === 1) {
3058			sphf.renderPagButton();
3059		}
3060
3061		// Kontrola nastavenia strankovania
3062		sphf.checkSorting();
3063
3064		// Pripnutie custom parametrov a atributov na elementy
3065		sphf.enhanceElements();
3066
3067		// Renderovanie facetov iba vsetkym otvorenym skupinam
3068		if (sphf.setting.facets && sphf.facets !== 'undefined' && !jQuery.isEmptyObject(sphf.facets)){
3069
3070			var subs = {};
3071
3072			sphf.obj.modul.find('.filter_group').each(function(){
3073
3074				var box = jQuery(this);
3075				var id = box.attr('id');
3076				var facet = id;
3077				box.removeClass('facets_rendered');
3078
3079				var special = box.hasClass('ftr_display_type_1');
3080				var visible = (sphf.setting.display === 2 ? box.closest('.filter_sub_group').hasClass('sub_active') : false);
3081
3082				if (facet === 'availabilities' && typeof sphf.facets['avail_attribs'] !== 'undefined') {
3083					facet = 'avail_attribs';
3084				}
3085
3086				if (visible || box.hasClass('always_opened') || box.hasClass('opened') || typeof sphf.options.extract[id] !== 'undefined') {
3087					sphf.renderFacets(box);
3088				}
3089				else if (!sphf.facetsFound(facet, '') && !box.hasClass('facets_disabled') && !special) {
3090					box.addClass('group_no_res');
3091				}
3092				else {
3093
3094					var found = special;
3095
3096					if (!found && typeof sphf.facets[id] !== 'undefined'){
3097
3098						jQuery.each(sphf.facets[id], function(c,v){
3099
3100							if (box.find('[id="'+id+'_'+c+'"]').length){
3101
3102								found = true;
3103								return false;
3104							}
3105						});
3106					}
3107
3108					if (!found) {
3109						box.addClass('group_no_res');
3110					} else {
3111						box.removeClass('group_no_res');
3112					}
3113				}
3114
3115				// Ziadne vysledky pre skupiny
3116				if (sphf.setting.display == 2){
3117
3118					var sub = box.closest('.filter_sub_group');
3119					var _id = sub.attr('id');
3120					if ( typeof subs[_id] === 'undefined' ) subs[_id] = sub;
3121				}
3122			});
3123
3124			if (sphf.setting.display == 2){
3125
3126				jQuery.each(subs, function(id,sub){
3127
3128					sub.removeClass('groups_initializad');
3129
3130					if ( !sub.find('.filter_group').not('.group_no_res').length ){
3131
3132						sub.addClass('sub_no_res');
3133						sphf.obj.modul.find('.filter_sub_menu .sub_group_name[data-id="'+id+'"]').addClass('sub_no_res');
3134					} else {
3135
3136						sub.removeClass('sub_no_res');
3137						sphf.obj.modul.find('.filter_sub_menu .sub_group_name[data-id="'+id+'"]').removeClass('sub_no_res');
3138					}
3139				});
3140			}
3141		}
3142
3143		// Platne iba pri browse v casti Sphinx manager
3144		if (sphf.debug && sphf.manager) {
3145
3146			if (typeof sphf.stats != 'undefined') {
3147				core.renderFilterStats(sphf.stats);
3148			}
3149			if (typeof sphf.setting != 'undefined') {
3150				core.renderFilterSetting(sphf.setting);
3151			}
3152		}
3153
3154		// Callback pri vyrenderovani obsahu
3155		sphf.options.onFilterRender.call();
3156
3157		// CS mini statistika, uplne na konci kvoli js timingu.
3158		if (sphf.debug) {
3159			sphf.renderStats();
3160		}
3161
3162		// Ine inicializacie funkcionalit netykajuce sa filtra. Ine funkcionality v shop browse...
3163		if (ajax && typeof js_product_compare_init == 'function' && typeof productCompareSettings !== 'undefined') {
3164			js_product_compare_init();
3165		}
3166		if (ajax && typeof js_first_init_ajax_cart == 'function') {
3167			js_first_init_ajax_cart();
3168		}
3169		if (ajax && typeof window.js_CS_Config_module_wishlist_new_enable !== 'undefined' && typeof js_wishlist_new_check_after_page_load === 'function') {
3170			js_wishlist_new_check_after_page_load();
3171		}
3172	},
3173	/**
3174	 * Overuje ci mame vo vysledku nejake facety k dispozicii
3175	 * @param {string} id
3176	 * @param {string} trunk Specialne dynamicke facety _composites, _avails,...
3177	 */
3178	facetsFound: function(id, trunk) {
3179		var facets = {};
3180		var is_attrib = id.search('attrib_') === 0;
3181
3182		if (trunk !== null && trunk !== '' && trunk !== 'undefined') {
3183			if (typeof sphf.facets[id + '_' + trunk] !== 'undefined') {
3184				facets = sphf.facets[id + '_' + trunk];
3185			}
3186		} else if (typeof sphf.facets[id + '_avails'] !== 'undefined') {
3187			facets = sphf.facets[id + '_avails'];
3188		} else if (typeof sphf.facets[id + '_composites'] !== 'undefined') {
3189			facets = sphf.facets[id + '_composites'];
3190		} else if (typeof sphf.facets[id] !== 'undefined') {
3191			facets = sphf.facets[id];
3192		}
3193
3194		var found = false;
3195		jQuery.each(facets, function(key, value){
3196			if (key > 0) {
3197				found = true;
3198				return false;
3199			}
3200		});
3201		return found;
3202	},
3203	renderStats: function(){
3204		if (sphf.debug){ csstack('renderStats'); }
3205
3206		var s = '';
3207
3208		var stop = sphf.microtime(true);
3209
3210		var jstotal = stop - sphf.timing.start;
3211		var jsrender = jstotal;
3212		var jsrequest = 0;
3213
3214		if (typeof sphf.timing.request !== 'undefined') {
3215
3216			jsrender = jstotal - sphf.timing.request;
3217			jsrequest = sphf.timing.request;
3218		}
3219
3220		// Statistiky su cachovane sphf.cached
3221		var d = 'Disabled';
3222		var u = '<span style="color:grey;">Notused</span>';
3223		var y = '<span style="color:green;">Yes</span>';
3224		var n = '<span style="color:red;">No</span>';
3225		var t = '<span class="csu_stats_fr">[sec]</span>';
3226		var c = sphf.cached;
3227		var ca = (typeof sphf.stats.global.cache != 'undefined' ? sphf.stats.global.cache : 0);
3228		var bc = (typeof sphf.stats.global.browse_cached != 'undefined' ? sphf.stats.global.browse_cached : 0);
3229		var sc = (typeof sphf.stats.global.stats_cached != 'undefined' ? sphf.stats.global.stats_cached : 0);
3230		var mc = (typeof sphf.stats.global.module_cached != 'undefined' ? sphf.stats.global.module_cached : 0);
3231		var dc = (typeof sphf.stats.global.data_cached != 'undefined' ? sphf.stats.global.data_cached : 0);
3232		var tc = (typeof sphf.stats.global.tree_cached != 'undefined' ? sphf.stats.global.tree_cached : 0);
3233		var fc = (typeof sphf.stats.global.facet_cached != 'undefined' ? sphf.stats.global.facet_cached : 0);
3234		var cm = (typeof sphf.stats.global.commanded != 'undefined' ? sphf.stats.global.commanded : 0);
3235
3236		s += '<div class="content" style="text-align:left;">';
3237		s += '<div>CSU: quick stats<span style="float:right">v.'+sphf.version+'</span></div>';
3238		s += '<div><p>Engine</p><p>'+(typeof sphf.setting.engine != 'undefined' ? sphf.setting.engine : '')+'</p></div>';
3239		s += '<div><p>Cache</p><p>'+(ca == 0 ? d : (ca == 1 ? 'Redis' : (ca == 2 ? 'Filecache' : '?')))+'</p></div>';
3240		s += '<div class="csstats_other"></div>';
3241		s += '<div><p>Browse cached</p><p>'+((bc == 1 || c) ? y : (bc == 2 ? d : (bc == 3 ? u : n)))+'</p></div>';
3242		s += '<div><p>Stats cached</p><p>
3242'+((bc == 2) ? d : ((sc || c) ? y : n))+'</p></div>';
3243		s += '<div><p>Modul cached</p><p>'+((mc == 1 || c) ? y : (mc == 2 ? d : (mc == 3 ? u : n)))+'</p></div>';
3244		s += '<div><p>Data cached</p><p>'+((dc == 1 || c) ? y : (dc == 2 ? d : (dc == 3 ? u : n)))+'</p></div>';
3245		s += '<div><p>Tree cached</p><p>'+((tc == 1 || c) ? y : (tc == 2 ? d : (tc == 3 ? u : n)))+'</p></div>';
3246		s += '<div><p>Facet cached</p><p>'+((fc == 1 || c) ? y : (fc == 2 ? d : (fc == 3 ? u : n)))+'</p></div>';
3247
3248		s += '<div class="csstats_other"></div>';
3249
3250		if (typeof sphf.meta.total_found !== 'undefined'){
3251
3252			s += '<div><p>Total found</p><p>'+sphf.meta.total_found+' '+(c ? '<span class="csu_stats_fr">[cached]</span>' : '')+'</p></div>';
3253		}
3254		s += '<div><p>PHP total</p><p>'+sphf.stats.global.total_time+t+'</p></div>';
3255		s += '<div><p>JS total</p><p>'+(Math.round(jstotal * 1e3) / 1e3)+t+'</p></div>';
3256		s += '<div><p>JS draw</p><p>'+(Math.round(jsrender * 1e3) / 1e3)+t+'</p></div>';
3257		s += '<div><p>JS ajax</p><p>'+(Math.round(jsrequest * 1e3) / 1e3)+t+'</p></div>';
3258
3259		s += '<div class="csstats_other"></div>';
3260
3261		jQuery.each(sphf.stats.global.pagination, function(key, val){
3262			s += '<div><p>'+key.charAt(0).toUpperCase() + key.slice(1)+'</p><p>'+val+'</p></div>';
3263		});
3264
3265		s += '<div class="csstats_other"></div>';
3266
3267		s += '<div><p>Ping code</p><p>'+((!c && sphf.pingcode != '') ? '<span style="color:#00bbff;">true</span>' : '<span style="color:red;">false</span>')+'<span class="csu_stats_fr">['+(sphf.pingcode != '' ? sphf.pingcode : '-----')+']</span></p></div>';
3268		s += '<div><p>Commanded</p><p>'+(cm == 0 ? 'Default' : (cm == 1 ? 'URL' : (cm == 2 ? 'Cookie' : 'Session')))+'</p></div>';
3269		s += '<div><p>Sort by group</p><p>'+sphf.stats.global.sort_by_group+'</p></div>';
3270
3271		s += '</div>';
3272
3273		sphf.obj.stats.html(s);
3274	},
3275	renderResButton: function(){
3276		if (sphf.debug){ csstack('renderResButton'); }
3277
3278		var total = sphf.getTotal();
3279		var html_a = '';
3280
3281		if (typeof sphf.obj.resbtn == 'undefined') sphf.initResButton();
3282
3283		if (total == 0) {
3284
3285			sphf.obj.resbtn.html(sphf.langs.no_results).addClass('no_results');
3286		} else {
3287
3288			if (total == 1) {
3289
3290				html_a = '<span class="txt_pre">' + sphf.langs.show + '</span><span class="found">1</span><span class="txt_aft">' + sphf.langs.result_1 + '</span>';
3291			} else if (total > 1 && total < 5) {
3292
3293				html_a = '<span class="txt_pre">' + sphf.langs.show + '</span><span class="found">' + total + '</span><span class="txt_aft">' + sphf.langs.result_2 + '</span>';
3294			} else {
3295
3296				html_a = '<span class="txt_pre">' + sphf.langs.show + '</span><span class="found">' + total + '</span><span class="txt_aft">' + sphf.langs.result_3 + '</span>';
3297			}
3298
3299			sphf.obj.resbtn.html(html_a).removeClass('no_results');
3300		}
3301
3302		sphf.obj.resbtn.show();
3303	},
3304	renderPagButton: function(){
3305		if (sphf.debug){ csstack('renderPagButton'); }
3306
3307		var total = sphf.getTotal();
3308		var limit = parseInt(sphf.pagination.limit);
3309		var limitstart = parseInt(sphf.pagination.limitstart);
3310
3311		if (typeof sphf.obj.pagbtn == 'undefined' || sphf.obj.pagbtn === null) {
3312			sphf.initPagButton();
3313		}
3314
3315		if (sphf.simple_paging) {
3316
3317			limitstart = (sphf.pagination.pageend - 1) * limit;
3318			sphf.simple_paging = 0;
3319			sphf.pagination.pagestart = 0;
3320			sphf.pagination.pageend = 0;
3321			sphf.obj.pagbtn.removeClass('active');
3322			sphf.obj.pagbtn.find('.featureprod_ajax_loader').remove();
3323		}
3324
3325		if (total === 0 || (total <= limitstart + limit)) {
3326
3327			sphf.obj.pagbtn.hide();
3328		} else {
3329
3330			var v = 0;
3331			var t = '';
3332
3333			if ((total - limit) < (limitstart + limit)) {
3334
3335				v = (total - (limitstart + limit));
3336
3337				if (v === 1) {
3338					t = sphf.langs.pag_last1;
3339				} else if (v > 1 && v < 5) {
3340					t = sphf.langs.pag_last2;
3341				} else {
3342					t = sphf.langs.pag_last3;
3343				}
3344			} else {
3345
3346				v = sphf.pagination.limit;
3347
3348				if (v === 1) {
3349					t = sphf.langs.pag_next1;
3350				} else if (v > 1 && v < 5) {
3351					t = sphf.langs.pag_next2;
3352				} else {
3353					t = sphf.langs.pag_next3;
3354				}
3355			}
3356
3357			if (v > 0) {
3358
3359				sphf.obj.pagbtn.find('div').text(sphf.replacer(t, v));
3360				sphf.obj.pagbtn.show();
3361			}
3362		}
3363	},
3364	setData: function(data){
3365		if (sphf.debug){ csstack('setData'); }
3366
3367		if (typeof data == 'undefined') {
3368			return;
3369		}
3370
3371		sphf.cid = (typeof data.cid !== 'undefined' ? data.cid : 0);
3372		sphf.mid = (typeof data.mid !== 'undefined' ? data.mid : 0);
3373		sphf.active = ((typeof data.active !== 'undefined' && data.active.length !== 0) ? data.active : sphf.active);
3374		sphf.facets = ((typeof data.facets !== 'undefined' && data.facets.length !== 0) ? data.facets : {});
3375		sphf.scales = ((typeof data.scales !== 'undefined' && data.scales.length !== 0) ? data.scales : {});
3376		sphf.base = ((typeof data.base !== 'undefined' && data.base.length !== 0) ? data.base : {});
3377		sphf.uoms = ((typeof data.uoms !== 'undefined' && data.uoms.length !== 0) ? data.uoms : {});
3378		sphf.prices = ((typeof data.prices !== 'undefined' && data.prices.length !== 0) ? data.prices : {});
3379		sphf.groups = ((typeof data.groups !== 'undefined' && data.groups.length !== 0) ? data.groups : sphf.groups);
3380		sphf.setting = ((typeof data.setting !== 'undefined' && data.setting.length !== 0) ? data.setting : sphf.setting);
3381		sphf.data = ((typeof data.filter !== 'undefined' && data.filter.length !== 0) ? data.filter : sphf.data);
3382		sphf.stats = ((typeof data.stats !== 'undefined' && data.stats.length !== 0) ? data.stats : {});
3383		sphf.meta = ((typeof data.meta !== 'undefined' && data.meta.length !== 0) ? data.meta : {});
3384		sphf.forced = ((typeof data.forced !== 'undefined' && data.forced.length !== 0) ? data.forced : {});
3385		sphf.keywords = ((typeof data.keywords !== 'undefined') ? data.keywords : {});
3386		sphf.seo = ((typeof data.seo !== 'undefined' && data.seo.length !== 0) ? data.seo : sphf.seo);
3387		sphf.config = ((typeof data.config !== 'undefined' && data.config.length !== 0) ? data.config : sphf.config);
3388		sphf.guide = ((typeof data.guide !== 'undefined' && data.guide.length !== 0) ? data.guide : sphf.guide);
3389		sphf.ordering = ((typeof data.ordering !== 'undefined' && data.ordering.length !== 0) ? data.ordering : sphf.ordering);
3390		sphf.order_list = ((typeof data.order_list !== 'undefined' && data.order_list.length !== 0) ? data.order_list : sphf.order_list);
3391		sphf.last_list_cat = ((typeof data.last_list_cat !== 'undefined') ? data.last_list_cat : sphf.last_list_cat);
3392
3393		// Mame data kompletne z cache?
3394		sphf.cached = (sphf.pingcode !== '' && (typeof sphf.stats.global.pingcode == 'undefined' || sphf.stats.global.pingcode !== sphf.pingcode));
3395
3396		// Default global premenne
3397		if (sphf.pagination.limit === 0) {
3398
3399			sphf.pagination.limit = (typeof sphf.stats.global !== 'undefined' && typeof sphf.stats.global.pagination !== 'undefined' ? sphf.stats.global.pagination.limit : 15);
3400		}
3401	},
3402	/**
3403	 * Inicializuje vykreslenie skupiny
3404	 */
3405	initGroup: function(group){
3406
3407		var id = group.attr('id');
3408
3409		if (sphf.debug){ csstack('initGroup', [id]); }
3410
3411		var box = group.find('.filter_items');
3412		var ibox = box.find('.filter_box');
3413
3414		box.find('input.fi_input').each(function () {
3415
3416			var elm = jQuery(this);
3417			var vid = parseInt(elm.val());
3418
3419			if (typeof sphf.base[id] !== 'undefined' && typeof sphf.base[id][vid] == 'undefined') {
3420
3421				elm.closest('.filter_item').remove();
3422			}
3423		});
3424
3425		// Custom nastavenia pre kazdu skupinu
3426		if (typeof sphf.groups[id] !== 'undefined') {
3427
3428			// Typ vykreslenia keyword inptut
3429			if (typeof sphf.groups[id]['search'] !== 'undefined' && sphf.groups[id]['search'] === 1) {
3430				sphf.initSearch(box, id);
3431			}
3432
3433			// Typ vykreslenia slider
3434			if (typeof sphf.groups[id].type !== 'undefined' && sphf.groups[id].type === 1) {
3435				sphf.initSlider(box, id);
3436			}
3437
3438			// Skupina stale otvorena, iba pre frontend - v backende su nastavenia pre skupiny
3439			if (typeof sphf.groups[id].opened !== 'undefined' && sphf.groups[id].opened === 1 && !sphf.backend) {
3440				group.removeClass('opened closed');
3441			}
3442		}
3443
3444		// Kompakt zobrazenie nepouziva otvaranie/zatvaranie poloziek skupin
3445		if ( sphf.setting.display !== 2 ){
3446
3447			// Zobrazenie skupin otvorene / zatvorene
3448			var boxheight = ibox.height();
3449			var wdth = 0;
3450
3451			// Fallback ak je parent div skryti alebo mu dali float left, zmeriame dynamicky vysku tejto skupiny
3452			if (boxheight === 0){
3453
3454				// Musime zobrat sirku kontainera v ktorom su polozky
3455				var wrap = ibox.closest('div');
3456				var ww = wrap.outerWidth();
3457
3458				// Kedze niektore divs mozu byt skryte height musime
3459				var tester = jQuery('<div>').addClass('sphf_height_probe').css('width', ww+'px').appendTo('body');
3460
3461				tester.html(ibox[0].outerHTML);
3462				boxheight = tester.height();
3463				tester.html('');
3464				if (sphf.debug){ console.log('    WARNING! Some parent element are hidden. Fallback height launched... Calculated height value: '+boxheight + ', Wrap width value: '+ww); }
3465
3466				tester.remove();
3467			}
3468
3469			if (boxheight > sphf.setting.max_height) {
3470
3471				// Zobrazit tlacidlo
3472				if (sphf.setting.scrollbar == 0) {
3473
3474					ibox.css('height', sphf.setting.max_height);
3475					box.append('<div class="filter_more" onclick="sphf.extend(this);">' + sphf.langs.more_results + '</div>');
3476
3477				}
3478				// Standard browser scrollbar
3479				else if (sphf.setting.scrollbar == 1 || sphf.options.forceDeaultScroll) {
3480
3481					if (sphf.itmwidth == 0) {
3482						sphf.itmwidth = parseInt(box.width());
3483					}
3484
3485					if (sphf.setting.display == 0) {
3486
3487						if (sphf.scrwidth == 0) {
3488							sphf.scrwidth = parseInt(sphf.scrollWidth());
3489						}
3490						wdth = (sphf.itmwidth + sphf.scrwidth);
3491					} else {
3492
3493						wdth = sphf.itmwidth;
3494					}
3495
3496					ibox.css({
3497						'height': sphf.setting.max_height,
3498						'overflow-y': 'scroll',
3499						'width': wdth + 'px'
3500					});
3501				}
3502				// Plugin scrollbar
3503				else if (sphf.setting.scrollbar == 2) {
3504
3505					// Pri nizkych rozdieloch skrolovania toto je neprakticke
3506					var inertia = ((boxheight - sphf.setting.max_height) > 100 ? 300 : 20);
3507
3508					if (sphf.debug) {
3509						console.log('Boxheight: ' + boxheight + ', Maxheight: ' + sphf.setting.max_height + ', Initializing scrollbar...');
3510					}
3511
3512					ibox.mCustomScrollbar({
3513						set_height: sphf.setting.max_height,
3514						theme: "dark-thick",
3515						horizontalScroll: false,
3516						scrollInertia: inertia,
3517						advanced: {
3518							autoScrollOnFocus: true,
3519							updateOnContentResize: true,
3520							updateOnBrowserResize: true
3521						},
3522						mouseWheel: {
3523							scrollAmount: (typeof sphf.options.scrollbar !== 'undefined' && typeof sphf.options.scrollbar.scrollAmount !== 'undefined' ? sphf.options.scrollbar.scrollAmount : 'auto'),
3524							preventDefault: true
3525						},
3526						onTotalScrollOffset: 20,
3527						onTotalScrollBackOffset: 20,
3528						callbacks: {
3529							onScroll: function () {
3530								jQuery(this).removeClass('scrolled');
3531							},
3532							onTotalScroll: function () {
3533								jQuery(this).addClass('scrolled');
3534							},
3535							onTotalScrollBack: function () {
3536								jQuery(this).removeClass('scrolled active');
3537							}
3538						},
3539						contentTouchScroll: true,
3540						documentTouchScroll: false,
3541						autoDraggerLength: true
3542					});
3543				}
3544
3545				box.addClass('overflowed');
3546			}
3547		}
3548
3549		group.addClass('group_initialized');
3550	},
3551	/**
3552	 * Vyprintuje elementy ktore filter pouziva
3553	 */
3554	renderItems: function(){
3555		if (sphf.debug){ csstack('renderItems'); }
3556
3557		// Toto sa vykonava iba raz na zaciatku vykreslenia poloziek filtra
3558		jQuery.each(sphf.elems.filter_group, function (id, group) {
3559
3560			var all_opened = (group.hasClass('ftr_params') && typeof sphf.setting.filters !== 'undefined' && typeof sphf.setting.filters.params !== 'undefined' && sphf.setting.filters.params.opened == 2);
3561
3562			if (all_opened || (typeof sphf.groups[id] !== 'undefined' && ((typeof sphf.groups[id].opened !== 'undefined' && sphf.groups[id].opened > 0) || typeof sphf.active[id] !== 'undefined'))) {
3563				sphf.initGroup(group);
3564			}
3565
3566			// Extract poloziek na koniec filtra
3567			if (typeof sphf.options.extract[id] !== 'undefined') {
3568				sphf.extract(id);
3569			}
3570
3571			if (sphf.setting.selected_def == 1) {
3572				var cus_lang = 'js_lang_sphf_pick_text_' + id;
3573				var def_text = (typeof window[cus_lang] !== 'undefined' ? window[cus_lang] : sphf.langs.pick_text);
3574				group.find('.filter_selected').html('<div class="fp_default_item">' + def_text + '</div>');
3575			}
3576		});
3577
3578		sphf.obj.body.on('click', '.fi_image, .fi_image_label', function (e) {
3579
3580			var img = jQuery(this);
3581			var item = img.closest('.filter_item');
3582
3583			// Klik na nezaskrtnutu polozku bez vysledkov
3584			if (item.hasClass('item_no_res') && !img.hasClass('is_checked')) {
3585				return;
3586			}
3587
3588			item.find('.fi_image, .fi_image_label').toggleClass('is_checked');
3589			item.toggleClass('item_checked');
3590			sphf.changed(this, e);
3591		});
3592	},
3593	/**
3594	 * Vytiahne specifikovane polozky zo skupiny a pripne ich na koniec
3595	 * @param {string} id ID skupiny
3596	 */
3597	extract: function (id) {
3598		if (sphf.debug) {
3599			csstack('extract', [id]);
3600		}
3601
3602		if (typeof sphf.options.extract[id] === 'undefined') {
3603			return;
3604		}
3605
3606		var extracted = 0;
3607		var content = sphf.obj.modul.find('.filter_content');
3608		var items = sphf.elems.filter_group[id].find('.filter_item');
3609
3610		items.each(function () {
3611
3612			var item = jQuery(this);
3613			var input = item.find('.fi_input');
3614			var attr = input.attr('id');
3615			var value = parseInt(input.val());
3616
3617			if (sphf.options.extract[id].length === 0 || sphf.options.extract[id].indexOf(value) > -1) {
3618
3619				sphf.elems.extracted[attr] = jQuery('<div>').addClass('filter_item extracted parent-' + id).data('id', id);
3620				sphf.elems.extracted[attr].html(item.html());
3621				sphf.elems.extracted[attr].find('input').attr('id', attr + '_extracted');
3622				sphf.elems.extracted[attr].find('label').attr('for', attr + '_extracted');
3623
3624				content.append(sphf.elems.extracted[attr]);
3625				item.addClass('is_extracted');
3626				input.addClass('is_extracted');
3627				extracted++;
3628			}
3629		});
3630
3631		if (extracted === items.length) {
3632
3633			sphf.elems.filter_group[id].addClass('extracted_empty');
3634		}
3635	},
3636	/**
3637	 * Sortne aktivne polozky podla toho ako su vo filtry usporiadane. Zamedzenie duplicitnych url s tymi istymi parametrami ale v inom poradi
3638	 */
3639	sortActive: function(){
3640		if (sphf.debug){ csstack('sortActive'); }
3641
3642		sphf.sorter.groups = [];
3643
3644		var i = 0;
3645		var sg = [];
3646		var smg = [];
3647
3648		jQuery.each(sphf.active, function(id, d){
3649
3650			var sv = [];
3651			var smv = [];
3652			var values = [];
3653			var slider = 0;
3654			var ranges = 0;
3655			var keyword = 0;
3656			var index = -1;
3657			var defined = (typeof sphf.ordering['values'] !== 'undefined' && typeof sphf.ordering['values'][id] !== 'undefined');
3658
3659			if (defined){
3660
3661				keyword = (sphf.ordering['values'][id] === 'k' ? 1 : 0);
3662				slider = (sphf.ordering['values'][id] === 's' ? 1 : 0);
3663				ranges = (sphf.ordering['values'][id] === 'r' ? 1 : 0);
3664				index = sphf.ordering['groups'].indexOf(id);
3665			}
3666
3667			if (index === -1 && typeof sphf.elems.filter_group[id] !== 'undefined'){
3668
3669				var current = sphf.elems.filter_group[id].data('ordering');
3670				index = (current !== 'undefined' && current !== null ? current : -1);
3671			}
3672
3673			if (index > -1){
3674
3675				// Mame spravny index
3676				sg.push({k: id, o: index});
3677			} else {
3678
3679				// Toto chyba z neznameho dovodu, dame ju na koniec
3680				smg.push(id);
3681			}
3682
3683			// Sortovanie hodnot
3684			if (!slider && !ranges && !keyword && defined) {
3685
3686				for (i = 0; i < d.length; i++) {
3687
3688					var dv = parseInt(d[i]);
3689
3690					index = sphf.ordering['values'][id].indexOf(dv);
3691
3692					if (index > -1) {
3693
3694						// Mame spravny index
3695						sv.push({k: dv, o: index});
3696					} else {
3697
3698						// Toto chyba z neznameho dovodu, dame ju na koniec
3699						smv.push(dv);
3700					}
3701				}
3702
3703				sv.sort(function (a, b) {
3704					return a.o - b.o;
3705				});
3706
3707				for (i = 0; i < sv.length; i++) {
3708
3709					values.push(sv[i]['k']);
3710				}
3711
3712				for (i = 0; i < smv.length; i++) {
3713
3714					values.push(smv[i]);
3715				}
3716
3717				sphf.active[id] = values;
3718
3719				if (sphf.debug) console.log('- setting active[' + id + '] to values', values);
3720			}
3721		});
3722
3723		sg.sort(function (a, b) {
3724		  return a.o - b.o;
3725		});
3726
3727		for (i = 0; i < sg.length; i++) {
3728
3729			sphf.sorter.groups.push(sg[i]['k']);
3730		}
3731
3732		for (i = 0; i < smg.length; i++) {
3733
3734			sphf.sorter.groups.push(smg[i]);
3735		}
3736	},
3737	/**
3738	 * Vykreslenie poloziek skupinam patriacim do sprievodcu
3739	 *
3740	 */
3741	renderGuide: function(){
3742		if (sphf.debug){ csstack('renderGuide'); }
3743
3744		jQuery.each(sphf.guide, function (i, v) {
3745
3746			var id = v.id;
3747
3748			// Prva skupina je renderovana defaultne vzdy
3749			if (i === 0 || typeof sphf.elems.filter_group[id] === 'undefined') {
3750				return true;
3751			}
3752
3753			var box = sphf.elems.filter_group[id];
3754			var ibox = box.find('.filter_items');
3755			var fbox = ibox.find('.filter_box');
3756
3757			if (fbox.hasClass('mCustomScrollbar')) {
3758				fbox.mCustomScrollbar('destroy');
3759			}
3760
3761			ibox.removeClass('overflowed');
3762			fbox.empty().removeClass('mCS_destroyed').removeAttr('style');
3763			box.addClass('parent_dependent').removeClass('group_initialized');
3764
3765			if (typeof v.items !== 'undefined') {
3766
3767				fbox.html(v.items);
3768				box.removeClass('parent_dependent');
3769				sphf.initGroup(box);
3770			}
3771		});
3772	},
3773	/**
3774	 * Overi spravnost nastavenia parentov, pre uz zvolene skupiny v sprievodcovi
3775	 */
3776	verifyGuide: function(){
3777		if (sphf.debug){ csstack('verifyGuide'); }
3778
3779		if (sphf.guide.length > 0) {
3780
3781			for (var i = 1; i < sphf.guide.length; i++) {
3782
3783				var group = sphf.guide[i];
3784
3785				if (typeof sphf.active[group.id] !== 'undefined' && typeof group.parent_id !== 'undefined') {
3786
3787					if (typeof sphf.active[group.parent_id] === 'undefined' || JSON.stringify(sphf.active[group.parent_id]) !== JSON.stringify(group.parent_value)) {
3788
3789						sphf.removeActive(group.id, 0);
3790					}
3791				}
3792			}
3793		}
3794	},
3795	/**
3796	 * Podla aktualne nastavenych lokalnych premennych skontroluje nastavenie a zobrazenie html elementov radenia a strankovania
3797	 */
3798	checkSorting: function(){
3799		if (sphf.debug){ csstack('checkSorting'); }
3800
3801		// Sortovanie podla
3802		if (typeof sphf.order_list[sphf.pagination.orderby] !== 'undefined'){
3803
3804			sphf.sort(sphf.order_list[sphf.pagination.orderby], true);
3805		}
3806
3807		// Smer sortovania
3808		if (sphf.pagination.DescOrderBy === 'DESC'){
3809
3810			jQuery('input[name="DescOrderBy"]').val('DESC');
3811			jQuery('.orderby_img.ASC').hide();
3812			jQuery('.orderby_img.DESC').show();
3813		} else {
3814
3815			jQuery('input[name="DescOrderBy"]').val('ASC');
3816			jQuery('.orderby_img.ASC').show();
3817			jQuery('.orderby_img.DESC').hide();
3818		}
3819	},
3820	/**
3821	 * Overi ci je skupina zvolena
3822	 * @param {string} name Nazov skupiny
3823	 * @param {boolean} only Naviac musi byt skupina zvolena iba sama
3824	 * @return {boolean}
3825	 */
3826	isGroupActive: function(name, only){
3827		if (sphf.debug){ csstack('isGroupActive', [name,only]); }
3828
3829		var r = false;
3830
3831		jQuery.each(sphf.active, function(group, values){
3832
3833			if (group.search(name) === 0){
3834
3835				r = true;
3836				if (!only) return false;
3837			} else if (only){
3838
3839				r = false;
3840				return false;
3841			}
3842		});
3843		return r;
3844	},
3845	/**
3846	 * Renderuje facety pre tuto skupinu a zaroven resetuje aktivovane polozky v html dome ak uz viac nie su realne nastavene
3847	 * @param {object} group
3848	 */
3849	renderFacets: function(group)
3850	{
3851		let id = group.attr('id');
3852
3853		if (sphf.debug){ csstack('renderFacets', [id]); }
3854
3855		// Keywords nemaju facety
3856		if ( id === 'keywords' ) {
3857			return;
3858		}
3859		var is_attrib = id.search('attrib_') === 0;
3860		var is_slider = typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].type === 1;
3861		var has_checked = typeof sphf.active[id] !== 'undefined';
3862		var exclusive = typeof sphf.groups[id] !== 'undefined' && typeof sphf.groups[id]['excfacets'] !== 'undefined' && sphf.groups[id]['excfacets'] == 1;
3863		var type = typeof sphf.groups[id] !== 'undefined' && typeof sphf.groups[id].type !== 'undefined' ? sphf.groups[id].type : 0;
3864		var facets = {};
3865		var range = [];
3866
3867		// Skupiny patriace do guide, maju stale facety base
3868		if (type === 5) {
3869			facets = (typeof sphf.base[id] !== 'undefined' ? sphf.base[id] : {});
3870		}
3871		// Facety pre atributy berieme z ineho facet pola ak je aktivna dostupnost
3872		else if (is_attrib && typeof sphf.facets[id + '_avails'] !== 'undefined') {
3873			facets = sphf.facetsFound(id, 'avails') ? sphf.facets[id + '_avails'] : {};
3874		}
3875		// Facety zlozenych variantov maju prednost
3876		else if (is_attrib && typeof sphf.facets[id + '_composites'] !== 'undefined') {
3877			facets = sphf.facetsFound(id, 'composites') ? sphf.facets[id + '_composites'] : {};
3878		}
3879		// Facety pre atributy berieme z ineho facet pola ak je aktivna dostupnost
3880		else if (typeof sphf.active.availabilities !== 'undefined' && id.search('attrib_') === 0 && typeof sphf.facets.attrib_avails !== 'undefined') {
3881			facets = sphf.facets.attrib_avails;
3882		}
3883		// Facety pre dostupnost berieme z ineho facet pola ak su aktivne atributy
3884		else if (id === 'availabilities' && typeof sphf.facets['avail_attribs'] !== 'undefined') {
3885			facets = sphf.facetsFound('avail_attribs', '') ? sphf.facets['avail_attribs'] : {};
3886		} else {
3887			facets = (typeof sphf.facets[id] !== 'undefined' ? sphf.facets[id] : {});
3888		}
3889
3890		// Extend product_special facets
3891		if (id === 'product_special' && typeof sphf.facets.product_special_shg !== 'undefined' && !jQuery.isEmptyObject(sphf.facets.product_special_shg)) {
3892			facets = jQuery.extend({}, facets, sphf.facets.product_special_shg);
3893		}
3894
3895		sphf.updateHtml(id);
3896
3897		group.removeClass('group_no_res');
3898
3899		if (group.hasClass('facets_disabled')) {
3900			return;
3901		}
3902
3903		// Ak nam chyba vo vysledku tato skupina nastavime vsetky jej hodnoty nie su dostupne a filtrovanie na ne by vratilo 0 vysledkov
3904		if (jQuery.isEmptyObject(facets)) {
3905
3906			// Reset adaptivneho slidera, pretoze chyba vo facetoch
3907			if (is_slider) {
3908
3909				if (typeof sphf.active[id] === 'undefined') {
3910					group.addClass('not_usable');
3911					sphf.elems.filter_group[id].range_slider.slider('disable');
3912					sphf.resetSlider(id, false);
3913				}
3914			} else {
3915
3916				if (!has_checked) {
3917
3918					group.addClass('group_no_res');
3919				}
3920
3921				var checked = false;
3922
3923				group.find('.filter_item').each(function () {
3924
3925					var box = jQuery(this);
3926					var inp = box.find('.fi_input');
3927
3928					if (box.hasClass('is_image')) {
3929
3930						checked = box.hasClass('item_checked');
3931					} else {
3932
3933						checked = inp.is(':checked');
3934						if (checked) {
3935							box.addClass('item_checked');
3936						} else {
3937							box.removeClass('item_checked');
3938						}
3939					}
3940
3941					if (!checked) {
3942
3943						box.find('.fi_input').prop("disabled", true);
3944					}
3945					box.removeClass('item_add_res').addClass('item_no_res');
3946					box.find('.count').html('');
3947				});
3948
3949				// Facety extractovanym polozkam
3950				if (typeof sphf.options.extract[id] !== 'undefined') {
3951
3952					sphf.obj.modul.find('.parent-' + id).addClass('item_no_res').find('.count').html('');
3953				}
3954			}
3955		}
3956		// Mame vysledky pre tuto skupinu!
3957		else {
3958
3959			// Slider
3960			if (is_slider) {
3961
3962				group.removeClass('not_usable');
3963				sphf.elems.filter_group[id].range_slider.slider('enable');
3964
3965				// Ak mame tento slider medzi aktivnymi polozkami, jeho aktualne nastavenie a min-max sa nemenia,
3966				// i napriek tomeu ze su zvolene ine polozky filtra
3967				if (typeof sphf.active[id] === 'undefined') {
3968
3969					var values = [0, sphf.getMaxScaleKey(id)];
3970					if (sphf.debug) {
3971						console.log('setting slider ' + id + ' to:', values);
3972					}
3973					sphf.elems.filter_group[id].range_slider.slider('option', 'max', values[1]);
3974					sphf.elems.filter_group[id].range_slider.slider("values", 0, values[0]);
3975					sphf.elems.filter_group[id].range_slider.slider("values", 1, values[1]);
3976					range = sphf.elems.filter_group[id].range_slider.slider("values");
3977					sphf.rangeText(range, id);
3978				}
3979			} else {
3980
3981				group.find('.filter_item').each(function(){
3982
3983					var box = jQuery(this);
3984					var inp = box.find('.fi_input');
3985					var iid = inp.attr('id');
3986					var val = inp.val();
3987					var checked = false;
3988
3989					if (box.hasClass('is_image')){
3990
3991						checked = box.hasClass('item_checked');
3992					} else {
3993
3994						checked = inp.is(':checked');
3995						if (checked){
3996							box.addClass('item_checked');
3997						} else {
3998							box.removeClass('item_checked');
3999						}
4000					}
4001
4002					if (typeof facets[val] === 'undefined') {
4003
4004						box.removeClass('item_add_res').addClass('item_no_res');
4005
4006						// Ak uz je polozka zaskrtnuta, nezakazeme ju lebo sa nebude dat odskrtnut
4007						if (!checked) {
4008							inp.prop("disabled", true);
4009						}
4010
4011						if (box.hasClass('is_extracted')) {
4012
4013							sphf.elems.extracted[iid].removeClass('item_add_res').addClass('item_no_res');
4014							if (!checked) {
4015								sphf.elems.extracted[iid].find('.fi_input').prop("disabled", true);
4016							}
4017						}
4018					} else {
4019
4020						if (!checked && has_checked) {
4021
4022							box.removeClass('item_no_res');
4023
4024							// Exclusivne pocitanie pre skupinu je zapnute
4025							if (!exclusive && type !== 5) {
4026								box.addClass('item_add_res');
4027							}
4028							box.find('.count').html(facets[val]);
4029							inp.prop("disabled", false);
4030
4031							if (box.hasClass('is_extracted')) {
4032
4033								if (!exclusive && type !== 5) {
4034									sphf.elems.extracted[iid].addClass('item_add_res');
4035								}
4036								sphf.elems.extracted[iid].find('.count').html(facets[val]);
4037								sphf.elems.extracted[iid].find('.fi_input').prop("disabled", false);
4038							}
4039						} else {
4040
4041							box.removeClass('item_no_res').removeClass('item_add_res');
4042							box.find('.count').html(facets[val]);
4043							inp.prop("disabled", false);
4044
4045							if (box.hasClass('is_extracted')) {
4046
4047								sphf.elems.extracted[iid].removeClass('item_no_res').removeClass('item_add_res');
4048								sphf.elems.extracted[iid].find('.count').html(facets[val]);
4049								sphf.elems.extracted[iid].find('.fi_input').prop("disabled", false);
4050							}
4051						}
4052					}
4053				});
4054			}
4055		}
4056
4057		group.addClass('facets_rendered');
4058	},
4059	getMaxScaleKey: function(id) {
4060		return (typeof sphf.scales[id] === 'object' && sphf.scales[id] !== null ? Math.max(0, sphf.scales[id].length - 1) : 0);
4061	},
4062	/**
4063	 *
4064	 * @param range
4065	 * @param id
4066	 * @returns {*}
4067	 */
4068	rangeText: function(range, id){
4069		if (sphf.debug){ csstack('rangeText', [range,id]); }
4070
4071		var html = '';
4072		var min = '';
4073		var max = '';
4074		var uom = sphf.getUom(id);
4075
4076		if (range === 0){
4077			range = sphf.elems.filter_group[id].range_slider.slider("values");
4078		}
4079
4080		range = sphf.scaleKeyToValue(id, range);
4081
4082		if (typeof range[0] != 'undefined') {
4083			min = range[0];
4084		}
4085		if (typeof range[1] != 'undefined') {
4086			max = range[1];
4087		}
4088
4089		// Formatovanie currency fieldov
4090		if (typeof sphf.groups[id] !== 'undefined' && sphf.groups[id].uom == 1){
4091
4092			min = js_format_Money( min, sphf.prices['decimals'], '', sphf.prices['1000_symbol'], sphf.prices['dec_symbol']);
4093			max = js_format_Money( max, sphf.prices['decimals'], '', sphf.prices['1000_symbol'], sphf.prices['dec_symbol']);
4094		}
4095
4096		// Input fields povolene
4097		if (sphf.groups[id]['inputs'] == 1){
4098
4099			min = '<input type="text" class="filter_range_input" name="filter_range_from" value="'+min+'" />';
4100			max = '<input type="text" class="filter_range_input" name="filter_range_to" value="'+max+'" />';
4101		}
4102
4103		html += '<span class="filter_range_from">' + min + uom + '</span>';
4104		html += '<span class="filter_range_divider"></span>';
4105		html += '<span class="filter_range_to">' + max + uom + '</span>';
4106
4107		sphf.elems.filter_group[id]['range_text'].html(html);
4108
4109		return range;
4110	},
4111	getUom: function(id){
4112		if (sphf.debug){ csstack('getUom',[id]); }
4113
4114		var uom;
4115
4116		if(typeof sphf.groups[id]['uom'] !== 'undefined' && sphf.groups[id]['uom'] == 1){
4117			uom = sphf.prices.symbol;
4118		} else {
4119			uom = (typeof sphf.uoms[sphf.groups[id]['uom']] !== 'undefined' ? sphf.uoms[sphf.groups[id]['uom']] : '');
4120		}
4121
4122		return uom;
4123	},
4124	/**
4125	 * Animuje scrollovanie stranky do pozadovanej vysky
4126	 * @param elem
4127	 * @param callback
4128	 */
4129	scroll: function(elem, callback){
4130		if (sphf.debug){ csstack('scroll'); }
4131
4132		var adj = (typeof sphf.options.adjustScroll === 'function' ? sphf.options.adjustScroll() : -10);
4133		if (!isNumeric(adj)) {
4134			adj = 10;
4135		}
4136		var pos = sphf.obj.body.scrollTop();
4137		var top = sphf.obj.content.offset().top + adj;
4138
4139		if (sphf.config.adjust_scroll) {
4140			top = sphf.obj.content.find('#product_list').offset().top;
4141
4142			var adminHeight = jQuery('#header_container').height();
4143
4144			if (adminHeight > 0) {
4145				top = top - adminHeight;
4146			}
4147		}
4148
4149		if (pos !== top && (sphf.setting.scrolltop == 1 || (sphf.setting.scrolltop == 2 && elem.hasClass('pagenav')))){
4150			jQuery('body,html').animate({
4151				scrollTop: top
4152			},
4153			sphf.setting.scrollspeed,
4154			'easeOutQuint',
4155			function() {
4156				if (typeof callback == 'function') {
4157					callback();
4158				}
4159			});
4160		} else {
4161			if (typeof callback == 'function') {
4162				callback();
4163			}
4164		}
4165	},
4166	/**
4167	 * Vrati aktualne nastavenu hodnotu pre slider, ak neni vrati default min - max
4168	 */
4169	currentSlider: function(id){
4170		if (sphf.debug){ csstack('currentSlider', [id]); }
4171
4172		var r = [];
4173
4174		if (typeof sphf.scales[id] !== 'undefined') {
4175			r[0] = typeof sphf.active[id] !== 'undefined' ? sphf.revertScale(id, sphf.active[id][0]) : 0;
4176			r[1] = typeof sphf.active[id] !== 'undefined' ? sphf.revertScale(id, sphf.active[id][1]) : sphf.getMaxScaleKey(id);
4177		}  else {
4178			r[0] = (typeof sphf.active[id] !== 'undefined' && typeof sphf.active[id][0] !== 'undefined' ? sphf.active[id][0] : sphf.groups[id]['range']['min']);
4179			r[1] = (typeof sphf.active[id] !== 'undefined' && typeof sphf.active[id][1] !== 'undefined' ? sphf.active[id][1] : sphf.groups[id]['range']['max']);
4180		}
4181
4182		return r;
4183	},
4184	/**
4185	 * Nastavenie slidra programovo alebo cez input fields
4186	 */
4187	setSlider: function(elem, id){
4188		if (sphf.debug){ csstack('setSlider', [id]); }
4189
4190		if (typeof sphf.elems.filter_group[id] == 'undefined'){ return; }
4191
4192		var btn = jQuery(elem);
4193		var value = btn.val();
4194
4195		// Pripravime string na float cislo
4196		value = value.replace(/,/g, '.');
4197		value = value.replace(/[.](?=.*[.])/g, '');
4198		value = parseFloat(value);
4199
4200		if (!jQuery.isNumeric(value)) {
4201			return;
4202		}
4203
4204		var is_from = (btn.attr('name') === 'filter_range_from');
4205
4206		if (typeof sphf.scales[id] !== 'undefined') {
4207			value = sphf.revertScale(id, value);
4208		}
4209
4210		// Nastavenie slidera
4211		if (is_from) {
4212
4213			if (sphf.debug) {
4214				console.log('setSlider [0] to value', value);
4215			}
4216			sphf.elems.filter_group[id].range_slider.slider("values", 0, value);
4217		} else {
4218
4219			if (sphf.debug) {
4220				console.log('setSlider [1] to value', value);
4221			}
4222			sphf.elems.filter_group[id].range_slider.slider("values", 1, value);
4223		}
4224
4225		var range = sphf.rangeText(0, id);
4226
4227		var verge = sphf.scaleMinMax(id);
4228
4229		var value_equal = ((is_from && value === verge[0]) || (!is_from && value === verge[1]));
4230
4231		var slider_equal = (range[0] === verge[0] && range[1] === verge[1]);
4232
4233		// Ak hodnoty slidra nie su medzi aktivnymi a min-max su rovnake nepokracujeme dalej
4234		if (typeof sphf.active[id] === 'undefined' && value_equal) {
4235
4236			if (sphf.debug) {
4237				console.log('    INFO: Value is equal to ' + (is_from ? 'min' : 'max') + ', no render needed...');
4238			}
4239			return;
4240		}
4241
4242		// Ak su hodnoty slidra rovnake a nezmenili sa, nepokracujeme dalej
4243		if (typeof sphf.active[id] !== 'undefined' && sphf.active[id][0] === range[0] && sphf.active[id][1] === range[1]){
4244
4245			if (sphf.debug){ console.log('    INFO: Both values are same as current active, no render needed...', sphf.active[id]); }
4246			return;
4247		}
4248
4249		// Ak obe hodnoty slidra su rovnake odstranime aktivne
4250		if (typeof sphf.active[id] !== 'undefined' && slider_equal){
4251
4252			sphf.removeActive(id, 0);
4253		} else {
4254
4255			sphf.setActive(id, range);
4256		}
4257
4258		sphf.renderActive();
4259		sphf.changeFilter();
4260	},
4261	/**
4262	 * Resetovanie posuvnika na min - max hodnoty
4263	 * @param {string} id Group ID
4264	 * @param {boolean} set Nastavit hodnotu v poli active
4265	 */
4266	resetSlider: function(id, set){
4267		if (sphf.debug){ csstack('resetSlider', [id,set]); }
4268
4269		if (typeof sphf.elems.filter_group[id] == 'undefined') {
4270			return;
4271		}
4272
4273		var range = sphf.scaleMinMax(id);
4274
4275		sphf.setMinMax(id, range);
4276
4277		var current = (set === true && typeof sphf.active[id] !== 'undefined' ? sphf.active[id] : range);
4278
4279		if (sphf.debug) {
4280			console.log('setting values for slider ' + id + ' to:', current);
4281		}
4282		sphf.elems.filter_group[id].range_slider.slider("values", 0, current[0]);
4283		sphf.elems.filter_group[id].range_slider.slider("values", 1, current[1]);
4284
4285		sphf.elems.filter_group[id].find('.filter_selected').empty();
4286
4287		sphf.rangeText(0, id);
4288	},
4289	/**
4290	 * Resetovanie posuvnika na min - max hodnoty
4291	 * @param {string} id Group ID
4292	 * @param {object} range [min,max] hodnota
4293	 */
4294	setMinMax: function(id, range){
4295		if (sphf.debug){ csstack('setMinMax', [id,range]); }
4296
4297		if (typeof sphf.elems.filter_group[id] === 'undefined') {
4298			return;
4299		}
4300
4301		if (sphf.debug) {
4302			console.log('setting min-max for slider ' + id + ' to:', range);
4303		}
4304		sphf.elems.filter_group[id].range_slider.slider('option', 'min', range[0]);
4305		sphf.elems.filter_group[id].range_slider.slider('option', 'max', range[1]);
4306	},
4307	/**
4308	 * Ziska default hodnotu min a max posuvnika podla aktualne nastavenej scale
4309	 * @param {string} id Group ID
4310	 * @return {object}
4311	 */
4312	scaleMinMax: function (id) {
4313		if (sphf.debug) {csstack('scaleMinMax', [id]);}
4314
4315		var r = [sphf.groups[id].range.min, sphf.groups[id].range.max];
4316
4317		if (typeof sphf.scales[id] !== 'undefined' && sphf.scales[id] !== null) {
4318			r[0] = 0;
4319			r[1] = sphf.getMaxScaleKey(id);
4320		}
4321
4322		return r;
4323	},
4324	extend: function( elem ){
4325		if (sphf.debug){ csstack('extend'); }
4326
4327		var btn = jQuery(elem);
4328		var box = btn.closest('.filter_items');
4329
4330		if (box.hasClass('extended')){
4331
4332			btn.html(sphf.langs.more_results);
4333			box.css('height', sphf.setting.max_height).removeClass('extended');
4334		} else {
4335
4336			btn.html(sphf.langs.less_results);
4337			box.css('height', 'auto').addClass('extended');
4338		}
4339	},
4340	toggle: function( elem, event ){
4341		if (sphf.debug){ csstack('toggle', [event.type]); }
4342
4343		var box;
4344		var btn = jQuery(elem);
4345
4346		if (btn.hasClass('filter_group')) {
4347			box = btn;
4348		} else {
4349			box = btn.closest('.filter_group');
4350		}
4351
4352		if (box.hasClass('always_opened') || box.hasClass('parent_dependent')) {
4353			return;
4354		}
4355
4356		if (!box.hasClass('group_initialized')) {
4357			sphf.initGroup(box);
4358		}
4359
4360		if (!box.hasClass('facets_rendered')) {
4361			sphf.renderFacets(box);
4362		}
4363
4364		var opened = box.hasClass('opened');
4365
4366		// Ak sme dnu a opustame skupinu a ponuka je zatvorena, pravdepodobne sa zatvorila kliknutim
4367		if (typeof event !== 'undefined' && event.type === 'mouseleave' && !opened) {
4368			return;
4369		}
4370
4371		// Ak meme explicitne nastavene ze mame otvorit
4372		if (typeof event !== 'undefined' && event.type === 'mouseenter' && opened) {
4373			return;
4374		}
4375
4376		// Jedna skupina otvorena sucasne
4377		if (typeof event !== 'undefined' && event.type === 'click' && sphf.setting.one_at_time) {
4378
4379			sphf.obj.modul.find('.filter_group.opened').removeClass('opened').addClass('closed');
4380		}
4381
4382		box.addClass('animating '+(!opened ? 'is_opening' : 'is_closing'));
4383
4384		if (!opened){
4385			box.removeClass('closed').addClass('opened');
4386			box.trigger('afterShow.sphf');
4387		} else{
4388			box.addClass('closed').removeClass('opened');
4389			box.trigger('afterHide.sphf');
4390		}
4391
4392		sphf.isGroupOpened();
4393
4394		setTimeout(function(){ box.removeClass('animating '+(!opened ? 'is_opening' : 'is_closing')); } ,200);
4395	},
4396	isGroupOpened: function(){
4397
4398		var r = sphf.obj.modul.find('.filter_group.opened').length;
4399
4400		if ( typeof sphf.obj.activ !== 'undefined' && sphf.obj.activ.length ){
4401
4402			if (r) sphf.obj.activ.addClass('group_opened');
4403			else sphf.obj.activ.removeClass('group_opened');
4404		}
4405
4406		return r;
4407	},
4408	toggleStats: function( elem ){
4409		if (sphf.debug){ csstack('toggleStats'); }
4410
4411		var btn = jQuery(elem);
4412		if (btn.hasClass('opened')) btn.removeClass('opened').find('.content').hide();
4413		else btn.addClass('opened').find('.content').show();
4414
4415	},
4416	scrollWidth: function(){
4417		if (sphf.debug){ csstack('scrollWidth'); }
4418
4419		var outer = document.createElement("div");
4420		outer.style.visibility = "hidden";
4421		outer.style.width = "100px";
4422		outer.style.msOverflowStyle = "scrollbar";
4423
4424		document.body.appendChild(outer);
4425		var widthNoScroll = outer.offsetWidth;
4426		outer.style.overflow = "scroll";
4427
4428		var inner = document.createElement("div");
4429		inner.style.width = "100%";
4430		outer.appendChild(inner);
4431
4432		var widthWithScroll = inner.offsetWidth;
4433
4434		outer.parentNode.removeChild(outer);
4435
4436		return widthNoScroll - widthWithScroll;
4437	},
4438	openSetting: function(elem, type)
4439	{
4440		if (sphf.debug){ csstack('openSetting', [type]); }
4441
4442		let btn = jQuery(elem);
4443
4444		let group = '';
4445
4446		// Nastavenie pre skupinu
4447		if (type === 'group' || type === 'values'){
4448
4449			if (btn.is('.csi-cog, .filter_title')){
4450
4451				group = btn.closest('.filter_group').attr('id');
4452			} else {
4453
4454				group = btn.attr('id');
4455			}
4456		}
4457
4458		btn.addClass('working');
4459
4460		new AjaxRequest({
4461			'id': sphf.mid,
4462			'type': type,
4463			'group': group
4464		})
4465			.setController("Filter")
4466			.setAction('openSetting')
4467			.onSuccess(function (jsonData) {
4468
4469				btn.removeClass('working');
4470
4471				if (typeof jsonData.data !== 'undefined' && jsonData.data.content !== ''){
4472
4473					vex.open({
4474						content: jsonData.data.content,
4475						afterOpen: function(elem) {
4476
4477							sphf.editwrap = jQuery(elem).find('.sph_s_wrap');
4478
4479							if (type === 'ordering' || type === 'values'){
4480
4481								sphf.initSortValues();
4482							} else {
4483
4484								jQuery('.sph_part label').poshytip({
4485									className: 'tip-sphinx',
4486									alignTo: 'target',
4487									alignX: 'left',
4488									alignY: 'center',
4489									offsetX: 15,
4490									offsetY: 0,
4491									fade: true,
4492									slide: true,
4493									showTimeout: 25,
4494									hideTimeout: 25
4495								});
4496							}
4497
4498							// Bind pre zobrazenie specifickych sekcii nastaveni pri zmene volby
4499							if (type === 'group'){
4500
4501								jQuery('.sph_dynamic_pick').each(function(){
4502
4503									jQuery(this).on('change', function(){ sphf.updateSection(this); }).trigger('change');
4504								});
4505							}
4506
4507							// Kontrola beziaceho indexu
4508							let ibtn = jQuery('a.working');
4509							if (ibtn.length){ sphf.pingIndex(ibtn); }
4510						}
4511					});
4512				}
4513			})
4514			.onError(function (response) {
4515
4516				btn.removeClass('working');
4517				showNotification(response.errors.join("<br>"), false, 'error');
4518			})
4519			.send();
4520	},
4521	/**
4522	 * Ulozi nastavenie modulu
4523	 */
4524	save: function(elem, type){
4525		if (sphf.debug){ csstack('save', [type]); }
4526
4527		let id = parseInt(sphf.editwrap.data('module'));
4528		let data = {};
4529		let group = '';
4530		let filter_group;
4531
4532		// Ulozenie orderingu skupin alebo hodnot
4533		if (type === 'ordering' || type === 'values'){
4534
4535			group = sphf.editwrap.attr('data-id');
4536			sphf.editwrap.find('.sph_part').each(function(i, v){
4537
4538				let inp = jQuery(this);
4539
4540				data[i] = inp.attr('id');
4541			});
4542		} else {
4543			sphf.editwrap.find('.sph_setting').each(function(){
4544
4545				let inp = jQuery(this);
4546
4547				data[inp.attr('name')] = inp.val();
4548			});
4549		}
4550
4551		if (type === 'group'){
4552
4553			group = sphf.editwrap.data('id');
4554			filter_group = jQuery('.module.mp_id'+id+' #'+group);
4555		}
4556
4557		sphf.editwrap.find('.sph_s_btn .csi_icon').hide();
4558
4559		new AjaxRequest({
4560			'id': id,
4561			'type': type,
4562			'group': group,
4563			'data': JSON.stringify(data)
4564		})
4565			.setController("Filter")
4566			.setAction('saveSetting')
4567			.setMethod('POST')
4568			.onSuccess(function (jsonData) {
4569
4570				sphf.editwrap.find('.sph_s_btn .csi_icon').show();
4571				if (type === 'group') {
4572					if (jQuery.isEmptyObject(jsonData.data.group)) {
4573						filter_group.find('.ftr_setting').removeClass('has_setting').attr('title',sphf.langs.set_group);
4574					} else {
4575						filter_group.find('.ftr_setting').addClass('has_setting').attr('title',sphf.langs.has_setting);
4576					}
4577				}
4578				showNotification(jsonData.data.message, false, 'success');
4579			})
4580			.onError(function (response) {
4581
4582				sphf.editwrap.find('.sph_s_btn .csi_icon').show();
4583				showNotification(response.errors.join("<br>"), false, 'error');
4584			})
4585			.send();
4586	},
4587	/**
4588	 * Zobrazi sekcie pre nastavenie
4589	 */
4590	updateSection: function(elem){
4591		if (sphf.debug){ csstack('updateSection'); }
4592
4593		let btn = jQuery(elem);
4594		let target = btn.attr('name');
4595		let value = btn.val();
4596
4597		jQuery('.sph_part_section').hide();
4598		jQuery('.sph_ref_'+target+'[data-ref="'+value+'"]').show();
4599	},
4600	/**
4601	 * Resetne niektore nastavenia modulu
4602	 */
4603	reset: function(elem, type){
4604		if (sphf.debug){ csstack('reset', [type]); }
4605
4606		let id = parseInt(sphf.editwrap.data('module'));
4607		let btn = jQuery(elem);
4608		let group = '';
4609		let filter_group;
4610
4611		if (type === 'group') {
4612			group = sphf.editwrap.data('id');
4613			filter_group = jQuery('.module.mp_id'+id+' #'+group);
4614		}
4615
4616		sphf.editwrap.find('.sph_s_btn .csi_icon').hide();
4617
4618		new AjaxRequest({
4619			'id': id,
4620			'type': type,
4621			'group': group
4622		})
4623			.setController("Filter")
4624			.setAction('resetSetting')
4625			.onSuccess(function (jsonData) {
4626
4627				sphf.editwrap.find('.sph_s_btn .csi_icon').show();
4628				if (type === 'group') {
4629					filter_group.find('.ftr_setting').removeClass('has_setting').attr('title',sphf.langs.set_group);
4630				}
4631				showNotification(jsonData.data.message, false, 'success');
4632			})
4633			.onError(function (response) {
4634
4635				sphf.editwrap.find('.sph_s_btn .csi_icon').show();
4636				showNotification(response.errors.join("<br>"), false, 'error');
4637			})
4638			.send();
4639	},
4640	/**
4641	 * Backend: inicializacia sortovania pre nastavenie skupin
4642	 */
4643	initSortValues: function(){
4644		if (sphf.debug){ csstack('initSortValues'); }
4645
4646		sphf.sortbox = sphf.editwrap.find('.sph_s_box');
4647
4648		sphf.sortbox.sortable({
4649			placeholder: "ui-state-highlight",
4650			axis: "y",
4651			revert: true
4652		});
4653
4654		sphf.editwrap.find('.sortasc').on('click', function () {
4655			sphf.sortValue('asc');
4656		});
4657
4658		sphf.editwrap.find('.sortdesc').on('click', function () {
4659			sphf.sortValue('desc');
4660		});
4661	},
4662	/**
4663	 * Zosortuje hodnoty v skupine podla poziadavky
4664	 */
4665	sortValue: function(dir){
4666		if (sphf.debug){ csstack('initSortValues', [dir]); }
4667
4668		// Radit ako cisla
4669		let number = (!!sphf.editwrap.find('input[name="number"]').is(':checked'));
4670		let ignore = (!!sphf.editwrap.find('input[name="ignore"]').is(':checked'));
4671		let listitems = sphf.sortbox.children('.sph_part').get();
4672
4673		sphf.sortbox.html('');
4674
4675		listitems.sort(function (a, b) {
4676			a = jQuery(a).text().toUpperCase();
4677			b = jQuery(b).text().toUpperCase();
4678
4679			if (dir === 'asc') {
4680
4681				return a.localeCompare(b, {'kn': number}, {'numeric': number, 'ignore-Punctua-tion': ignore});
4682			} else {
4683
4684				return b.localeCompare(a, {'kn': number}, {'numeric': number, 'ignore-Punctua-tion': ignore});
4685			}
4686		});
4687
4688		jQuery.each(listitems, function (idx, itm) {
4689			sphf.sortbox.append(itm);
4690		});
4691	},
4692	/**
4693	 * Button v administracii pre indexovanie dat
4694	 */
4695	index: function(elem)
4696	{
4697		if (sphf.debug){ csstack('index'); }
4698
4699		let btn = jQuery(elem);
4700
4701		// Tuto kontrolu uz nepotrebujeme
4702		if (sphf.pinginterval > 0) {
4703			clearInterval(sphf.pinginterval);
4704			sphf.pinginterval = 0;
4705		}
4706
4707		sphf.checkIndexRun(function(running){
4708
4709			btn.addClass('working');
4710
4711			if (running) {
4712				showNotification('Akciu nie je možné vykonať, indexácia práve prebieha', false, 'error');
4713				return false;
4714			}
4715
4716			new AjaxRequest({
4717				'division': 'products',
4718				'products': {},
4719				'forced': true
4720			})
4721				.setController("Index")
4722				.setAction('indexUnit')
4723				.onSuccess(function (jsonData) {
4724					btn.removeClass('working');
4725					showNotification(jsonData.data.message, false, 'success');
4726				})
4727				.onError(function (response) {
4728					btn.removeClass('working');
4729					showNotification(response.errors.join("<br>"), false, 'error');
4730				})
4731				.send();
4732		});
4733	},
4734	checkIndexRun: function(callback){
4735		if (sphf.debug){ csstack('checkIndexRun'); }
4736
4737		new AjaxRequest({
4738			'division': 'products'
4739		})
4740			.setController("Index")
4741			.setAction('indexerWorking')
4742			.onSuccess(function (jsonData) {
4743				callback(jsonData.data.isLocked);
4744			})
4745			.onError(function (response) {
4746				callback(false);
4747			})
4748			.send();
4749	},
4750	/**
4751	 * Kontrola ci prave prebieha indexacia dat
4752	 */
4753	pingIndex: function(button){
4754		if (sphf.debug){ csstack('pingIndex'); }
4755
4756		if (sphf.pinginterval > 0) return;
4757
4758		sphf.pinginterval = setInterval(function(){
4759
4760			sphf.checkIndexRun(function(working){
4761
4762				if (!working) {
4763					button.removeClass('working');
4764					clearInterval(sphf.pinginterval);
4765					sphf.pinginterval = 0;
4766				}
4767			});
4768		}, 5000);
4769	},
4770	/**
4771	 * Zmaze cache filtra
4772	 * @param elem
4773	 * @returns {boolean}
4774	 * @uses \Classes\Controllers\FilterController::deleteCacheUnit()
4775	 */
4776	deleteCache: function(elem)
4777	{
4778		if (sphf.debug){ csstack('deleteCache'); }
4779
4780		let btn = jQuery(elem);
4781
4782		if (btn.hasClass('working')) {
4783			return false;
4784		}
4785
4786		btn.addClass('working');
4787
4788		new AjaxRequest({
4789			'division': 'products'
4790		})
4791			.setController("Filter")
4792			.setAction('deleteCacheUnit')
4793			.onSuccess(function (jsonData) {
4794				btn.removeClass('working');
4795				showNotification(jsonData.data.message, false, 'success');
4796			})
4797			.onError(function (response) {
4798				btn.removeClass('working');
4799				showNotification(response.errors.join("<br>"), false, 'error');
4800			})
4801			.send();
4802	},
4803	/**
4804	 * Vyhlada text {+} a zameni ho za value
4805	 */
4806	replacer: function(text, value){
4807		if (sphf.debug){ csstack('replacer'); }
4808
4809		var re = new RegExp('\\{\\+\\}', 'i');
4810
4811		if (typeof text == 'string'){
4812
4813			if (typeof value == 'undefined'){ value = ''; }
4814
4815			if (text.search(re) > -1){ return text.replace(re, value); }
4816			else { return text; }
4817		}
4818
4819		return text;
4820	},
4821	toggleRec: function(elem){
4822		if (sphf.debug){ csstack('toggleRec'); }
4823
4824		var btn = jQuery(elem);
4825		var box = btn.closest('.sph_part');
4826		var rec = box.find('.sph_last_rec');
4827
4828		if (rec.is(':visible')){
4829
4830			rec.hide();
4831		} else {
4832
4833			rec.show();
4834		}
4835	},
4836	pair: function(x, y){
4837
4838	  return (x >= y) ? (x * x + x + y) : (y * y + x);
4839	},
4840	unpair: function(z){
4841
4842	  var sqrtz = Math.floor(Math.sqrt(z));
4843	  var sqz = sqrtz * sqrtz;
4844	  return ((z - sqz) >= sqrtz) ? [sqrtz, z - sqz - sqrtz] : [z - sqz, sqrtz];
4845	},
4846	checkDebug: function(){
4847
4848		sphf.csuser = (typeof js_global_is_csu != 'undefined' && js_global_is_csu);
4849		sphf.debug = (typeof Cookies == 'function' && typeof Cookies.get('cs_whois') !== 'undefined' && Cookies.get('cs_whois') === 'sphfdev');
4850		sphf.quirk = !(typeof history !== 'undefined' && typeof history.replaceState !== 'undefined');
4851	},
4852	microtime: function (getAsFloat) {
4853
4854		var s;
4855		var now;
4856		if (typeof performance !== 'undefined' && performance.now) {
4857
4858			now = (performance.now() + performance.timing.navigationStart) / 1e3;
4859
4860			if (getAsFloat) { return now; }
4861
4862			s = now | 0;
4863
4864			return (Math.round((now - s) * 1e6) / 1e6) + ' ' + s;
4865		} else {
4866
4867			now = (Date.now ? Date.now() : new Date().getTime()) / 1e3;
4868
4869			if (getAsFloat) { return now; }
4870
4871			s = now | 0;
4872
4873			return (Math.round((now - s) * 1e3) / 1e3) + ' ' + s;
4874		}
4875	}
4876};

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.