PageSourceSearch

https://www.volkskundemuseum.at/jart/prj3/volkskundemuseum/indexes…/packages/Collections/Collections.js?v=9

js volkskundemuseum.at collected 2026-10-02 03:57:17 UTC 53,753 bytes, 1,542 lines download raw bytes

1/* js for package: Collections */
2
3console = console || {
4    log: function(){},
5    dir: function(){}
6};
7
8function getQueryVariable(variable){
9   var query = window.location.search.substring(1);
10   var vars = query.split("&");
11   for (var i=0;i<vars.length;i++) {
12           var pair = vars[i].split("=");
13           if(pair[0] == variable){return pair[1];}
14   }
15   return false;
16}
17
18
19
20/**
21 * 
22 * thesaurus item baum einausklappbar: 
23 * https://www.jstree.com/
24 * 
25 */
26
27var collections = (function () {
28    
29    function compare(a,b) {
30      if (a.name < b.name)   return -1;
31      if (a.name > b.name)   return 1;
32      return 0;
33    }
34    
35    //TODO get this url
36//    var baseUrl = "http://han.jart.at";
37 //   var contentId = 1440750162061; //XUZIHU:: use correct content-id vor han and xuzi
38 
39    
40    var thesCatDATEid = 47;
41    var thesCatSammlung;
42    
43    var $collectionDiv; //root of this application
44    var $thesDiv;
45    var $thesLoading;
46    var $itemContainer;
47    var $locationFilterContainer;
48    var $thesContainer;
49    var thes; //whole thesaurus
50    var filter = {};    //object holding current filter; that is thesaurus id grouped by thesaurus categories
51    
52    var loadingMore = false;
53    var currentPage = 1;
54    
55    //date filter
56    var $dtStart, $dtEnd;
57    
58    //location filter
59    var $showOnFilter, $showOnNoFilter;
60    var $clearLocationFilterBtn;
61    var $inputLat, $inputLon;
62    
63    var flatThesItemList = {};  //flat list of thesItems grouped by thesaurus category
64    
65    
66    function _div(sClass){
67        var div = $("<div></div>");
68        if (sClass){
69            div.addClass(sClass);
70        }
71        return div;
72    }
73    
74    
75    function _setBusy(isBusy){
76        if (isBusy){
77            $(".item-list").hide();
78            $(".busy").show();
79        }else{
80            $(".item-list").show();
81            $(".busy").hide();   
82        }
83    }
84    
85    function _initDomObjects(){
86        $collectionDiv = $(".collection");
87        $locationFilterContainer = $(".location-filter");
88        $clearLocationFilterBtn = $locationFilterContainer.find(".clear-location-filter");
89        $showOnFilter = $locationFilterContainer.find(".showOnLocationFilter");
90        $showOnNoFilter = $locationFilterContainer.find(".showOnNoLocationFilter");
91        $inputLat = $locationFilterContainer.find("#filterLatitude");
92        $inputLon = $locationFilterContainer.find("#filterLongitude");
93	    $thesContainer = $(".thesaurus-categories");  
94	    $itemContainer = $(".item-list");
95	    $thesDiv = $(".thesaurus");
96        $thesLoading = $(".thes-loading");
97        
98        $clearLocationFilterBtn.on("click", function(){
99            _clearLocationFilter();
100            _sendFilter();
101        });
102	}
103	
104	function _initInfiniteScroll(){
105	    var scrollDiv = $(document);
106        scrollDiv.bind('scroll', function(){
107            //$.log("height: " + ($(this).innerHeight() - 1500) + " || scrollTop: " + $(this).scrollTop());
108            
109            /*
110            if(loadingMore){
111                if($(this).scrollTop() >= ($(this).innerHeight() - 1500)){
112                    $(".loading-more-info").removeClass("hidden");
113                    loadingMore = false;
114                    _sendFilter(currentPage + 1);
115                }
116            }
117            */
118            
119            //scroll to top button
120            if ($(this).scrollTop() > 1400) {
121    			$('.scrollToTop').fadeIn();
122    		} else {
123    			$('.scrollToTop').fadeOut();
124    		}
125        });
126	}
127	
128	function _initPager() {
129	    var $pageLinks = $(".page-link");
130	    var totalCount = $pageLinks.length;
131	    var neighbourCount = 3; //how many neighbors besides the current active page-button should be shown
132	    
133	    $pageLinks.on("click", function(e){
134	        e.preventDefault();
135	        
136	        var page = $(this).data("page");
137//	        $.log("loading page: " + page);
138	        
139	        _sendFilter(page);
140	        
141	        //set active state for recently clicked page
142	        $pageLinks.removeClass("active");
143	        $(this).addClass("active");
144	        
145	        //update which pagers should be shown
146	        
147	        $pageLinks.each(function(i){
148	            $this = $(this);
149	            if(i == 0 ||
150	                i == totalCount -1 ||
151	                Math.abs(page - (i+1)) <= neighbourCount ){
152	               //show the link
153	               $this.removeClass("hidden");
154	           }else{
155	               $this.addClass("hidden");
156	           }
157	        });
158	        
159	        togglePageSeparators($pageLinks, neighbourCount);
160	        
161	        return false;
162	    });
163	    
164	    togglePageSeparators($pageLinks, neighbourCount);
165	    _updateUrl();
166	}
167	
168	/**
169	 * shows page-btn separators with some sophisticated logic.
170	 * first separator is shown if second page button is not visible
171	 * last separator ist shown if next to last page button is not visible
172	 */ 
173	function togglePageSeparators($pageLinks, neighbourCount){
174	    var totalCount = $pageLinks.length;
175	    var $sepFirst = $(".page-separator-first");
176	    var $sepLast = $(".page-separator-last");
177	    
178	    var maxPagesNoSeparators = neighbourCount * 2 + 1;
179	    if($pageLinks.length <= maxPagesNoSeparators){
180	        $sepFirst.addClass("hidden");
181	        $sepLast.addClass("hidden");
182	    }else{
183	        if($($pageLinks[1]).hasClass("hidden")){
184	            //second page-link is hidden
185	            $sepFirst.removeClass("hidden");
186	        }else{
187	            $sepFirst.addClass("hidden");
188	        }
189	        
190	        if($($pageLinks[totalCount - 2]).hasClass("hidden")){
191	            //next to last page-link is hidden
192	            $sepLast.removeClass("hidden");
193	        }else{
194	            $sepLast.addClass("hidden");
195	        }
196	    }
197	}
198	
199	function _initScrollTop(){
200    	//Click event to scroll to top
201    	$('.scrollToTop').click(function(){
202    		$('html, body').animate({scrollTop : 170},600);
203    		return false;
204    	});
205	}
206    
207    function _fetchData(params, datatype, cb){
208	    var url = "/jart/prj3/volkskundemuseum/main.jart?rel=de&content-id=" + contentId + "&reserve-mode=" + reserveMode;
209	    
210	    //no caching by sending some random value
211	    url = url + "&rnd=" + Math.random();
212	    
213	    return $.ajax({
214			url : url,
215			data: params,
216			dataType : datatype
217		}).done(function(data) {
218			cb(data);
219		}).fail(function(e) {
220			$.log(e);
221		});
222	}
223	
224	/**
225	 * hides thesaurus loading indication and shows the finally built thesaurus
226	 */
227	function _showTesaurus(){
228	    //TODO: some nice animation??
229	    $thesDiv.removeClass("hidden");
230	    $thesLoading.addClass("hidden");
231	    
232        //collapse thesaurus on mobile and show a collapse button	    
233	    if(window.matchMedia){
234	        var mq = window.matchMedia('all and (max-width: 991px)');
235	        toggleThesaurusCollapse(mq);
236	        mq.addListener(toggleThesaurusCollapse);
237	    }
238	}
239	
240	/**
241	 * on mobile devices thesaurus is hidden in a collapse and the collapse button is shown
242	 */ 
243	function toggleThesaurusCollapse(mq){
244	    if(mq.matches){
245            $(".toggle-thesaurus").removeClass("hidden");
246            $thesDiv.addClass("collapse");
247        }else{
248            $(".toggle-thesaurus").addClass("hidden");
249            $thesDiv.removeClass("collapse");
250        }
251	}
252	
253	/**
254	 * loads whole thesaurus tree we use to draw thesaurus
255	 * uses localstorage to cache thesaurus cause it changes only on new collections
256	 */
257	function _buildThesaurus(){
258        var storage = window.localStorage; //sessionStorage vs localStorage
259        var loadFromServer = true;
260        if(storage){
261            //test if thesaurus was cached already
262            var data = storage.getItem('thesaurus');
263            if(data){
264                var thesaurus = JSON.parse(data);
265                if(window.thesaurusVersion && thesaurusVersion != '' && thesaurus.created == thesaurusVersion){
266                    loadFromServer = false;
267                    //TODO check for newer version
268                    _onThesaurusLoaded(thesaurus);
269                }
270            }
271        }
272        
273        if(loadFromServer){
274            //get thesaurus from server and cache it in local storage
275            _fetchData({ajax:"getThesaurus"}, "json", function(data){
276                var thesaurus = data.ajax.thesaurus;
277                if(storage){
278                    storage.setItem('thesaurus', JSON.stringify(thesaurus));
279                }
280                _onThesaurusLoaded(thesaurus);
281            });
282        }
283	    
284	    
285	}
286	
287	function _onThesaurusLoaded(_thes){
288	        thes = _thes;
289//	        var json = data.ajax;
290//	        thes = json.thesaurus;
291	        for(var i=0; i<thes.thes_category.length; i++){
292	            var tc = thes.thes_category[i];
293	            filter[tc.thesaurus_category_id] = []; //init filter groups
294	            
295	            _buildThesCatElement(tc);
296	        }
297	        _buildDateFilter();
298	        
299	        _bindEvents();
300	        _buildSelect2Boxes();
301	        
302	        var $resetAllBtn = $(".clearAllFilter");
303//	        $thesContainer.prepend($resetAllBtn);
304	        $resetAllBtn.on("click", function(){
305	            $(".select2-box").val('').trigger("change");
306	            $(".thes-item-input").prop("checked", false);
307	            $dtStart.val("");
308                $dtEnd.val("");
309                _clearLocationFilter();
310	            _recreateFilter();
311	            _sendFilter();
312	        });
313	        
314	        _buildThesItemFilterBySammlung(thes);
315	        _hideAlwaysHiddenThesItems(); // NEU
316	        _preselectCollection();
317	        _showTesaurus();
318	        
319	        //infinitescroll is only active after thesaurus is loaded
320	        loadingMore = true;
321	}
322	
323	
324	
325	function _buildDateFilter(){
326	    var tcd = $('.thes-cat[data-thes-id="' + thesCatDATEid + '"]');//thesaurus category date
327	    var div = $('<div class="thes-cat date-filter">' +
328	                    '<h3>Zeitraum</h3>' +
329	                    '<div class="filter-block"><div class="element"><label for="dt_start">Von</label>' +
330	                    '<input type="text" maxlength="10" id="dt_start"></input></div>' +
331	                    '<div class="element"><label for="dt_end">Bis</label>' +
332	                    '<input type="text" maxlength="10" id="dt_end"></input></div>' +
333	                    '<span class="dt-format">Format: (DD.MM.YYYY)</span></div>' + 
334	               '</div');
335	   
336	   $dtStart = div.find("#dt_start")
337	   $dtEnd = div.find("#dt_end");
338	   
339	   div.find("#dt_start, #dt_end").keyup(function(e) {
340            if (e.which == 13) // Enter key
341                $(this).blur(); //delegate to blur impl
342        }).blur(function() {
343            //TODO validate, if not valid, focus field
344            var valid = true;
345            
346            if (!valid){
347            //    console.log("setting focus again");
348                $(this).focus();   
349            }else{
350                _sendFilter();    
351            }
352        });
353	        
354	    var $resetBtn = $("<a class='del-filter'>Filterung aufheben<a/>");
355        $resetBtn.on("click", function(){
356            //clear input fields
357            $dtStart.val("");
358            $dtEnd.val("");
359            _sendFilter();
360        });     
361        div.find("h3").after($resetBtn);
362	        
363	    tcd.after(div);
364	}
365	
366	function _buildThesCatElement(tc){
367	    flatThesItemList[tc.thesaurus_category_id] = {
368	        tc: tc,
369	        tiList: []
370	    };
371	    
372	    var div = _div("thes-cat").attr("data-thes-id", tc.id);
373	    div.append($("<h3></h3>").text(tc.category_name));
374        _buildThesItemList(tc.thesaurus_item, div);
375	    
376	    tc.elem = div;
377	    $thesContainer.append(div);
378	}
379	
380	/**
381	 * builds a list of thesaurus item elements and adds it to the given parent dom element (pElem) 
382	 */
383	function _buildThesItemList(tiList, pElem){
384	    if (tiList){
385    	    var ul = $("<ul class='object-selector'></ul>").appendTo(pElem);
386    	    if ($.isArray(tiList)){
387    	        
388    	        for (var i=0; i<tiList.length; i++){
389    	            _buildThesItem(tiList[i], ul);   
390    	        }
391    	    }else{
392    	        _buildThesItem(tiList, ul);
393    	    }
394	    }
395	}
396	
397	function _isRootItem(ti){
398	    return ti.parent_thesaurus_item_id == null;
399	}
400	
401	function _getThesItemLabel(ti){
402	    var label = "";
403	    if (!_isRootItem(ti)){
404	        label = ti.name;
405    	    if(ti.synonym){
406    	        label = label + "<br> ["
407    	        if(ti.synonym.length){
408    	            for(var i=0; i<ti.synonym.length; i++){
409    	                if(i>0){
410    	                    label = label + " | <br>";
411    	                }
412    	                label = label + ti.synonym[i].name;
413    	            }
414    	        }else{
415    	            label = label + ti.synonym.name;
416    	        }
417    	        label = label + "]";
418    	    }    
419	    }else{
420	        //use category name as root?
421	        //var tc = flatThesItemList[ti.thesaurus_category_id]; auskommentiert Michael 15.4.2024
422//	        label = tc.tc.category_name;
423	        label = "Gesamt";
424//	        label = ti.name;
425	    }
426	    return label;
427	}
428	
429	/**
430	 * builds a single thesaurus item and adds it to the given parent dom element (pElem) 
431	 */
432	function _buildThesItem(ti, pElem){
433	    //flatThesItemList[ti.thesaurus_category_id].tiList.push(ti); auskommentiert Michael 15.4.2024
434	    
435	    var li = $("<li></li>").appendTo(pElem);
436	    
437	    var label;
438	    if (_isRootItem(ti)){
439	        label = $('<span>' + _getThesItemLabel(ti) + " [" + ti["linked-objects"] + "]" + '</span>');
440	    }else{
441	        label = $('<label>' + _getThesItemLabel(ti) + " [" + ti["linked-objects"] + "]" + '</label>').attr("for", ti.thesaurus_item_id);
442	        //only non-root items get a checkbox
443	        var chkbx = $('<input type="checkbox" name="thes-item" value="' + ti.thesaurus_item_id + '">')
444    	        .attr("id", ti.thesaurus_item_id)
445    	        .addClass("thes-item-input")
446    	        .data({
447    	            tiId: ti.thesaurus_item_id,
448    	            tcId: ti.thesaurus_category_id 
449    	        });
450    	    li.append(chkbx);
451	    }
452	    
453	    li.append(label);
454	    
455	    if (ti.thesaurus_item){
456	        li.append(
457	            $("<span> <img src='/jart/prj3/volkskundemuseum/indexes/main/resources/img/arrow_right.png' class='ico' alt='aufklappen' /> </span>").addClass("open-toggle")
458	       );
459	        
460            li.addClass("closed");    
461	    }
462	    
463
464	    _buildThesItemList(ti.thesaurus_item, li);
465	    
466	    ti.elem = li;
467	    
468	}
469	
470	/**
471	 * creates select2 boxes for quick accessing thesaurus items in a single category
472	 */ 
473	function _buildSelect2Boxes(){
474	    $.each(/*flatThesItemList, auskommentiert Michael 17.4. */function( key, value ) {
475	        var $select = $("<select></select>").attr("multiple", "multiple").css("width", "100%").addClass("select2-box").attr("data-placeholder", value.tc.category_name + " auswählen");
476	        
477	        value.tiList.sort(compare);
478	        
479	        for (var i=0; i<value.tiList.length; i++){
480	            var ti = value.tiList[i];
481	            if (!_isRootItem(ti)){
482	                $select.append($("<option value='" + ti.thesaurus_item_id + "'>" + _getThesItemLabel(ti) + "</option>"));
483	            }
484	        }
485	        
486	        
487	        //append select box, create select2 out of it and bind select/unselect events to keep the selection in sync with the tree
488	        value.tc.elem.find("h3").after($select);
489	        $select.select2({
490	            sorter: _select2Sorter
491	        });
492	        $select.on("select2:select", _onSelect2Select);
493            $select.on("select2:unselect", _onSelect2Unselect);
494	        
495	        var $resetBtn = $("<a class='del-filter'>Filterung aufheben<a/>");
496	        $resetBtn.on("click", function(){
497	            $select.val('').trigger("change");
498	            //clear select boxes
499	            value.tc.elem.find(".thes-item-input").prop("checked", false);
500	            _recreateFilter();
501	            _sendFilter();
502	        });
503	        value.tc.elem.find("h3").after($resetBtn);
504	    });
505	    
506	    //aria labels for select2
507        $(".select2-search__field").each(function(){        //, .select2-selection
508          $(this).attr("aria-label", $(this).closest(".thes-cat").find("h3").text() + " Filter");
509           // $(this).attr("title", $(this).attr("aria-label"));
510        });
511	}
512	
513	function _select2Sorter(data){
514	    data.sort(function(a,b){
515            return a.text.localeCompare(b.text, 'de');  //localCompare takes umlaute into account!
516	    });
517	    return data;
518	}
519    	
520    	/*
521    	var customSorter = function(data) {
522         return data.sort(function(a,b){
523             a = a.text.toLowerCase();
524             b = b.text.toLowerCase();
525             if(a > b) {
526                 return 1;
527             } else if (a < b) {
528                 return -1;
529             }
530             return 0;
531         });
532        };
533        */
534	
535	/*
536	recreates the filterobject from the current checkbox selection. this function may be used to created a totally synced filter object based on user selection
537	*/
538	function _recreateFilter(){
539	    $.each(filter, function( key, value ) {
540	        value.length=0;
541	    });
542	    
543	    $(".thes-item-input:checked").each(function(){
544	        $ti = $(this);   
545	        filter[$ti.data("tcId")].push($ti.data("tiId"));
546	    });
547	    
548	    _filterThesItems();
549	}
550	
551	function _onSelect2Select(e){
552	    var id = e.params.data.id;
553	    var opt = $thesContainer.find("input[value='" + id + "']");
554	    opt.prop("checked", true).change();
555	    
556//	    console.log($(this).val());
557	}
558	
559	function _onSelect2Unselect(e){
560	    var id = e.params.data.id;
561	    var opt = $thesContainer.find("input[value='" + id + "']");
562	    opt.prop("checked", false).change();
563	}
564	
565	/*
566	function _updateCollectionItems(items){
567	    
568	    $itemContainer.empty();
569	    for(var i=0; i<items.length; i++){
570	        item = items[i];
571            
572            var itemElem = $('<div class="item-teaser"><div class="item-image"></div><div class="inventarnummer">' + item.inventarnummer_online + '</div><h2>' + item.titel + '</h2><div class="link"><a href="/jart/prj3/volkskundemuseum/main.jart?rel=de&amp;reserve-mode=reserve&amp;content-id=' + contentId + '&amp;item_id=' + item.collection_item_id + '">_Mehr</a></div></div>');
573            if (item.image){
574                var src = baseUrl + ($.isArray(item.image) ? item.image[0]["image-url"] : item.image["image-url"]);
575                itemElem.find(".item-image").append($("<img></img>").attr("src", src));
576            }
577            
578            $itemContainer.append(itemElem);            
579        }
580	}
581	*/
582	
583	function _sendFilter(page){
584	    //send filter to server to retrieve new item list
585        
586        var pageGiven = typeof page !== "undefined"; //important to now later what to add to DOM from ajax response
587        if(!pageGiven){
588            currentPage = 1;
589            loadingMore = true;
590        }else{
591            currentPage = page;
592        }
593        
594        var params = {
595            groups:[],
596            'collection-page':currentPage
597        };
598        $.each(filter, function( key, value ) {
599            if (value.length > 0){
600                params.groups.push(key); //collect group id
601                params["grp_"+key] = value.join(); //serialize item-ids
602            }
603        });
604        
605        if (params.groups){
606            params.groups = params.groups.join();
607        }
608        
609        params["get-filtered-items"] = "yes";
610        
611        params["dt_start"] = $dtStart.val();
612        params["dt_end"] = $dtEnd.val();
613        
614        //set location filter
615        params["lat"] = $inputLat.val();
616        params["lon"] = $inputLon.val();
617        
618        //console.log(params);
619        
620        if(pageGiven){
621            $(".real-item-list").empty();
622            $(".loading-more-info").removeClass("hidden");
623        }else{
624            //TODO small loading more animation
625            _setBusy(true);
626        }
627        
628        _updateUrl();
629        
630        _fetchData(params, "html", function(data){
631            
632            //extract itemlist and set it into dom
633            
634            if(pageGiven){
635                //response cause of pager link. only swap the items
636                
637                var newItemList = $(data).find(".real-item-list .item-teaser");
638                $(".loading-more-info").addClass("hidden");
639                $(".real-item-list").empty().append(newItemList);
640                
641            }else{
642                //response cause of some filter change. add whole item-list which includes also new pager links
643                var newItemList = $(data).find(".item-list");
644                $(".item-list").before(newItemList).remove();
645                
646                //init pager links
647                _initPager();
648                _setBusy(false);
649            }
650            
651            /*
652            
653            if(currentPage == 1){
654                //set itemlist with headline
655                var newItemList = $(data).find(".item-list");
656                $(".item-list").before(newItemList).remove();
657                
658                //init pager links
659                _initPager();
660                
661            }else{
662                //append new items
663                var newItemList = $(data).find(".real-item-list .item-teaser");
664                $(".loading-more-info").addClass("hidden");
665                $(".real-item-list").append(newItemList);
666                if(newItemList.length > 0){
667                    loadingMore = true;
668                }
669            }
670            
671            */
672            
673            
674            
675       //     console.log(itemList.html());
676            
677            //_updateCollectionItems(data.collection_item);
678        });    
679	}
680    
681    function _bindEvents(){
682        //console.log("binding events, " + $(".thes-item-input").length);
683        //console.dir(filter);
684        
685        $(".thes-item-input").on("change", function(){
686            $ti = $(this);
687            $select2 = $ti.closest(".thes-cat").find(".select2-box");
688            
689          //  console.log("tiId: " + $ti.data("tiId") + "; tcId: " + $ti.data("tcId"));
690            if (this.checked){
691                //add to filter
692                filter[$ti.data("tcId")].push($ti.data("tiId"));
693                //add value to select2 box
694                var values = $select2.val();
695                if (!values){
696                    values = [];
697                }
698                values.push($ti.val());
699                $select2.val(values).trigger("change");
700            }else{
701                var tiId = $ti.data("tiId");
702                filter[$ti.data("tcId")] = $.grep(filter[$ti.data("tcId")], function(value) {
703                  return value != tiId;
704                });
705                
706                var values = $select2.val();
707                if (values){
708                    values = $.grep(values, function(value) {
709                      return value != tiId;
710                    });
711                }
712                $select2.val(values).trigger("change");
713            }
714            
715            //console.log(filter[$ti.data("tcId")]);
716            _sendFilter();
717        }); 
718        
719        $(".open-toggle").on("click", function(){
720            $me = $(this);
721            $me.parent().toggleClass("closed");
722            if($me.parent().hasClass("closed")){
723                $me.html(" <img src='/jart/prj3/volkskundemuseum/indexes/main/resources/img/arrow_right.png' class='ico' alt='aufklappen' /> ");
724                
725                //close child elements too
726                var $childToggles = $me.parent().find(".open-toggle");
727                $childToggles.html(" <img src='/jart/prj3/volkskundemuseum/indexes/main/resources/img/arrow_right.png' class='ico' alt='aufklappen' /> ");
728                $childToggles.parent().addClass("closed");
729            }else{
730                $me.html(" <img src='/jart/prj3/volkskundemuseum/indexes/main/resources/img/arrow_down.png' class='ico' alt='zuklappen' />");
731            }
732        });
733    }
734    
735    
736    var alwaysHiddenThesItemIds = ['1599292138284', '1599292138037']; //Kochbücher Petersmann, Forstner
737    function _hideAlwaysHiddenThesItems(){
738        for(var i=0; i<alwaysHiddenThesItemIds.length; i++){
739            var el = document.getElementById(alwaysHiddenThesItemIds[i]);
740            if(el){
741                var li = el.closest('li');
742                if(li){
743                    li.style.setProperty('display', 'none', 'important');
744                }
745            }
746        }
747    }
748    
749    
750    
751    
752    function _buildThesItemFilterBySammlung(thes){
753        var sids = thes["thesIds-by-Sammlung"].sids.split(",");
754        
755        //$(".thes-item-input").parent().hide();
756        //collection checkboxes are binded with there special logic about showing only there own thesaurus items
757        for(var i=0; i<sids.length; i++){
758            //special class for thesaurus items which are a Collection (Sammlung) so that these items are never hidden
759            $("#" + sids[i]).addClass("ti-collection");
760            $("#" + sids[i]).closest(".thes-cat").find(".select2-box").addClass("ti-collection");
761            
762            $("#" + sids[i]).on("change", function(){
763                _filterThesItems();
764            });
765        }
766        
767     //   console.dir(thesIdsByCollection);
768    }
769    
770    function _filterThesItems(){
771        var sids = thes["thesIds-by-Sammlung"].sids.split(",");
772        var thesIdsByCollection = {};
773        for(var i=0; i<sids.length; i++){
774            thesIdsByCollection[sids[i]] = [];
775        }
776        $.each(thes["thesIds-by-Sammlung"], function(key, val){
777           if (key != "sids" && key != "ids"){
778                var sids = (""+val).split(",");
779                var thesId = key.substring(2, key.length);
780                for(var i=0; i<sids.length; i++){
781                    try{
782                        thesIdsByCollection[sids[i]].push(thesId);
783                    }catch(e){
784                        $.log("ERROR: " + e);
785                        $.log(sids[i]);
786                    }
787                }
788           }
789        });
790        
791        //find all selected sammlungen
792        var selectedCol = [];
793        for(var j=0; j<sids.length; j++){
794            if($("#" + sids[j] + ":checked").length>0){
795                selectedCol.push(sids[j]);
796            }   
797        }
798        
799        //initially show all open-toggles
800        $(".open-toggle").show();
801        
802        if(selectedCol.length == 0 ||
803            selectedCol.length == sids.length){
804            //show all thesaurus checkboxes
805            $(".thes-item-input").parent().show();
806            //enable all thesaurus select2 options
807            $(".select2-box option").removeAttr("disabled");
808        }else{
809            $(".thes-item-input:not(.ti-collection)").parent().hide();
810            $(".select2-box:not(.ti-collection) option").attr("disabled", "disabled");
811            
812            /*
813            $(".select2-box option").each(function(){
814                var $this = $(this);
815                var d = $this.parent().data('selectOptions') || {};
816                d[$this.attr("value")] = $this.detach();
817                $this.parent().data('selectOptions', d);
818            });
819            */
820            
821            for(var x=0; x<selectedCol.length; x++){
822                var thesIds = thesIdsByCollection[selectedCol[x]];
823                for(var y=0; y<thesIds.length; y++){
824                    $("#" + thesIds[y]).parent().show();
825                    
826                    
827                    //show select2-box options
828                    $('.select2-box option[value="' + thesIds[y] + '"').removeAttr("disabled");
829                    
830                    //TODO: show all parents too??
831                } 
832            }
833            
834            //hide open-toggler if no children are visible
835            $(".open-toggle").each(function(){
836                $objSel = $(this).parent().find(">.object-selector");
837                
838                var LIs = $objSel.children();
839                var allHidden = true;
840                for(var i=0; i<LIs.length; i++){
841                    if($(LIs[i]).css("display") != "none"){
842                        allHidden = false;
843                        break;
844                    }
845                }
846                if(allHidden){
847                    $(this).hide();
848                }
849            });
850        }
851        
852         _hideAlwaysHiddenThesItems();   // NEU &#150; erzwingt erneutes Verstecken nach jedem Filterdurchlauf
853    }
854    
855    
856    /**
857     * updates the url based on the current result-page
858     * 
859     * TODO: later: the url should also contain all information about the current active filter for:
860     *   *) sharing the current filter
861     *   *) navigating back from the detail page should restore the filter 
862     */ 
863    function _updateUrl(){
864        var params = location.search;
865        
866        //remove old collection-page param
867        params = params.replace(/([\?&]collection-page=\d*)/, '');
868        
869        if(params === ""){
870            //
871            params = "?collection-page=" + currentPage;
872        }else{
873            params = params + "&collection-page=" + currentPage;
874        }
875        
876        //TODO: later: add filter params here too
877        
878        var newUrl = location.pathname + params;
879//        $.log(newUrl);
880        
881        history.replaceState({}, '', newUrl);
882    }
883    
884    
885    
886    /**
887     * for pre-selecting into a collection: checkbox of collection is checked and the select2 box filled with the collection
888     * 
889     * --> NEW: not only collections can be preselected, but all thesaurus items. this is done by linking from the details page.
890     * 
891     */  
892    function _preselectCollection(){
893        var colId = $collectionDiv.data("collection-id"); //the parameter is called collection-id, but it can be ANY thesaurus_item_id!!
894        if(colId){
895            //check checkbox
896            var $thesCkbx = $("#" + colId);
897	        $thesCkbx.prop("checked", true);
898	        
899	        //add value to select2box
900	        $select2 = $thesCkbx.closest(".thes-cat").find(".select2-box");
901            $select2.val(colId).trigger("change");
902	        
903	        //open collections
904	        //$thesCkbx.parent().parent().parent().removeClass("closed");
905	        /*
906	        var closedLi = $thesCkbx.parent(); //.parent().parent().removeClass("closed");
907	        while(closedLi.closest("li.closed").length > 0){
908	            closedLi = closedLi.closest("li.closed");
909	            closedLi.removeClass("closed");
910	        }
911	        
912	        */
913	        
914	        var breakCounter = 10;
915	        var elem = $thesCkbx; //.parent().parent().removeClass("closed");
916	        while(elem.parent().closest("ul.object-selector").length > 0){
917	            elem = elem.parent().closest("ul.object-selector");
918	            elem.siblings(".open-toggle").click();
919	            
920//	            closedLi.removeClass("closed");
921                if(breakCounter-- < 0){
922                    console.log("breakcounter reached, breaking loop now");
923                    break;
924                }
925	        }
926	        
927	        //hide thesaurus items from other collections
928	        _filterThesItems();
929	        
930	        //add it as filter
931	        _recreateFilter();
932        }
933    }
934    
935    function _setLocationFilter(lat, lon, ortsangabe){
936        
937        $showOnFilter.removeClass("hidden");
938        $showOnNoFilter.addClass("hidden");
939        
940        //TODO: add some animation so that the user sees this filter was applied
941        $locationFilterContainer.find(".ortsangabe").text(ortsangabe);
942        $inputLat.val(lat);
943        $inputLon.val(lon);
944        
945        _sendFilter();
946    }
947    
948    function _clearLocationFilter(){
949        
950        $showOnFilter.addClass("hidden");
951        $showOnNoFilter.removeClass("hidden");
952        
953        $locationFilterContainer.find(".ortsangabe").text("");
954        $inputLat.val("");
955        $inputLon.val("");
956    }
957    
958    function _init(){
959        _initDomObjects();
960        _buildThesaurus();
961        _initScrollTop();
962        _initInfiniteScroll();
963        //_preselectCollection();
964        _initPager();
965	}
966
967    return {
968        init: _init,
969        setLocationFilter: _setLocationFilter,
970        _hideAlwaysHiddenThesItems: _hideAlwaysHiddenThesItems   // NEU
971    };
972    
973    
974})();
975
976
977/**
978 * map drawing methods
979 * 
980 * 
981 * cluster references:
982 * https://unpkg.com/[email protected]/dist/supercluster.js
983 * https://github.com/nitaliano/react-native-mapbox-gl/issues/1069
984 * https://stackoverflow.com/questions/51033188/how-to-use-supercluster
985 * 
986 * 
987 * 
988 */
989
990var collectionMap = (function () {
991    
992    //both taken from ginas map box account!
993    var accessToken = 'pk.eyJ1IjoiaGFyZSIsImEiOiJjanNibTJoNWUwYTF4M3lteWVzbzNrcjR4In0.rrqGMzzUvTx1g1owCJtsFg';
994    var mapStyle = "mapbox://styles/hare/cjsps7smi26wi1fpkly4pwht4";
995    var map = null; //mapbox map
996    var _mapData; //json data
997    var $itemContent = $("#item-content"); //content of clicked items is rendered here
998    var useClusterMode = false;
999    var groupedLocations;
1000    
1001    function _initMap(){
1002        if(mapData){
1003            _mapData = _processMapData(mapData.collection_item);
1004        }
1005        
1006        if(getQueryVariable("useClusterMode") == "true"){
1007            useClusterMode = true;
1008        }
1009        
1010        //always use clustermode; later on, remove this branch
1011        useClusterMode = true;
1012        
1013        $('.collection-tabs a[data-toggle="tab"]').on('show.bs.tab', function (e) {
1014            //tab will be shown
1015            if(_isMapTab(e.target)){
1016                _unselectMap();
1017            }
1018            
1019        }).on('shown.bs.tab', function (e) {
1020            //tabis shown
1021            if(_isMapTab(e.target)){
1022                if(map == null){
1023                    //map was not draw already
1024                    _drawMap('item-map');
1025                }
1026            }
1027        })
1028    }
1029    
1030    /*
1031        duplicates items with a second location
1032    */
1033    function _processMapData(ciList){
1034        
1035        //items with latitude2 and longitude2 are duplicated. latitude2 and logitude2 means that there is a second location for this object
1036        var duplicatedItems = ciList.filter(function(ci){
1037            return ci.latitude2 != '' && ci.longitude2 != '';
1038        }).map(function (ci){
1039            //clone the object, otherwhise we could change the original one later on
1040            return $.extend(true, {}, ci);
1041        });
1042        
1043        duplicatedItems.forEach(function(ci){
1044            //set second location as first one to only use latitude-/longitude-/ortsangabe-1 in further code
1045            ci.latitude1 = ci.latitude2;
1046            ci.longitude1 = ci.longitude2;
1047            ci.ortsangabe1 = ci.ortsangabe2;
1048            ci.isDuplicate = true; //never used at the moment, but useful for finding bugs
1049        });
1050        
1051        //merge duplicated list into original one;
1052        $.merge(ciList, duplicatedItems);
1053        
1054        return ciList;
1055    }
1056    
1057    function _isMapTab(tab){
1058        return tab.href.indexOf("collection-map") !== -1;
1059    }
1060    
1061    function _drawMap(mapElementId){
1062        
1063        mapboxgl.accessToken = accessToken;
1064        
1065        map = new mapboxgl.Map({
1066          container: mapElementId,
1067          style: mapStyle,
1068          center: [52.93934616896888, 39.39714943204433],
1069          zoom: 2.022485356759363,
1070          minZoom:1.2,
1071          maxZoom:17.7
1072        });
1073
1074        map.on('zoomend', function(e){
1075            console.log("zoom-level: " + map.getZoom());
1076        }).on('moveend', function(e){
1077            console.log("center: " + map.getCenter());
1078        });
1079        
1080        //detect if something was clicked on the map
1081        map.on('click', function(e) {
1082            
1083            //unclusterd data point clicked?
1084          var features = map.queryRenderedFeatures(e.point, { layers: ['unclustered-point'] });
1085        
1086          if (features.length) {
1087            var clickedPoint = features[0];
1088            
1089 //           $.log("clicked point: ");
1090 //           $.log(clickedPoint);
1091            
1092            //get group of clicked point and show its collection items
1093            var gName = clickedPoint.properties.gName;
1094            var group = groupedLocations[gName];
1095            _drawCollectionItmesForMarker(gName, group);
1096            
1097            /*
1098            map.flyTo({
1099              center: clickedPoint.geometry.coordinates,
1100              zoom: 15,
1101              speed: .75
1102            });
1103            */
1104          }else{
1105              _unselectMap();
1106          }
1107        });
1108        
1109        
1110        if(_mapData){
1111  //          $.log(_mapData);
1112            
1113            
1114            //group locations by exact coordinates
1115            groupedLocations = _mapData.reduce(function(grouped, ci){
1116                var gName = ci.latitude1 +","+ci.longitude1;
1117                ci.gName = gName;
1118                typeof grouped[gName] !== 'undefined' ? (grouped[gName].push(ci)) :  (grouped[gName] = [ci]); 
1119                return grouped;
1120            },{});
1121            
1122  //          $.log("grouped locations");
1123//            $.log(groupedLocations);
1124            
1125            drawCluster();
1126            
1127            /*
1128            
1129            if(useClusterMode){
1130                //draw clustered data
1131                
1132                clusterDemo();
1133            }else{
1134                //draw unclustered data
1135                Object.keys(groupedLocations).forEach(function(key) {
1136                    _drawMarker(key, groupedLocations[key]);
1137                });
1138            }
1139            */
1140        }
1141    }
1142    
1143    
1144    
1145    
1146    function _mapToGeoJson(){
1147        var geoJson = {
1148            "type": "FeatureCollection",
1149            "crs": { "type": "name", "properties": { "name": "Volkskundemuseum Sammlungsobjekte" } },
1150        };
1151        geoJson.features = _mapData.map(_itemToGeoJSONPoint);
1152        return geoJson;
1153    }
1154    
1155    function _itemToGeoJSONPoint(ci){
1156        return {
1157            type: "Feature",
1158            geometry: {
1159                type: "Point",
1160                coordinates: [ci.longitude1.replace(",", "."), ci.latitude1.replace(",", "."), 0]
1161            },
1162            properties: {
1163                ci: ci,
1164                inventarnummer_online: ci.inventarnummer_online,
1165                collection_item_id: ci.collection_item_id,
1166                gName:ci.gName, //groupname the marker belongs to
1167                itemCount: groupedLocations[ci.gName].length
1168            }
1169        };
1170    }
1171    
1172    
1173    
1174    
1175    
1176    
1177    
1178    
1179    /*
1180        when a marker is clicked, this function draws all collection items in the marker group into itemContent
1181    */
1182    function _drawCollectionItmesForMarker(grpName, ciList){
1183        var title = ciList.length + (ciList.length === 1 ? " Objekt" : " Objekte");
1184        var ortsangabe = ciList[0].ortsangabe1 != '' ? ciList[0].ortsangabe1 : '(' + ciList[0].latitude1 + ", " + ciList[0].longitude1 + ')'; //take either ortsangabe1 or coordinates
1185        var lat = ciList[0].latitude1;
1186        var lon = ciList[0].longitude1;
1187        var filterBtn = 
1188            '<div class="filter-btn">' + 
1189                '<a class="btn btn-secondary locationFilterBtn" href="#" data-lat="' + lat + '" data-lon="' + lon + '" data-ortsangabe="' + ortsangabe + '">' + 
1190                    '<i class="fal fa-filter"> </i>Filtern' + 
1191                '</a>' + 
1192                '<p class="help-block">Filtert Objekte für diese Ortsangabe</p>'
1193                '<hr>' +
1194            '</div>';
1195        var ciListHtml = ciList.map(function(ci){
1196            
1197            var href = "/jart/prj3/volkskundemuseum/main.jart?rel=de&reserve-mode=" + reserveMode + "&content-id=1440750162061&nice_url=" + ci.nice_url;
1198            var link = '<div class="link"><a class="detail-link" href="' + href + '" target="_objektdetail">zum Objekt</a></div>';
1199            
1200            var img = "";
1201            if(ci.collection_item_image){
1202                var filepath = ci.collection_item_image[0].filename;
1203                img =
1204                    '<div class="item-image">' + 
1205                        '<div class="inner">' + 
1206                            '<a href="' + href + '" target="_objektdetail">' + 
1207                                '<img src="/jart/pub-prc/img.jart?base=/prj3/volkskundemuseum&img=' + filepath + '&mode=version&v=Gallery-Thumbnail" />' +
1208                            '</a>' +
1209                        '</div>' +
1210                    '</div>';
1211                
1212                //preload image
1213                /*
1214                var tmp = new Image();
1215				tmp.src = '/prj3/volkskundemuseum&img=' + filepath + '&mode=version&v=Gallery-Thumbnail';
1216				*/
1217            }
1218            
1219            var content =  
1220                img + 
1221                '<div class="inventar-nummer">' + ci.inventarnummer_online + "</div>" + 
1222                '<h2>' + ci.titel + '</h2>' +
1223                link;
1224                
1225            return '<div class="ci-item">' + content + '</div>';
1226            
1227        }).join('');
1228        
1229        var sClass = "popup_" + grpName.replace(/,/g, "_");
1230        
1231   //     $.log(sClass);
1232        
1233        var popupHtml = 
1234            '<div class="' + sClass + '">' + 
1235              '<h3>' + title + '</h3>' + 
1236              '<div class="ortsangabe">' + (ortsangabe && ortsangabe != '' ? ortsangabe : '') + '</div>' +
1237              filterBtn + 
1238              '<div class="ci-item-list">' +ciListHtml + '</div>' + 
1239            '</div>';
1240            
1241        $itemContent.html(popupHtml);
1242        $itemContent.find(".locationFilterBtn").on("click", function(e){
1243            e.preventDefault();
1244            
1245            var $this = $(this);
1246            _filterByCoordinates($this.data("lat"), $this.data("lon"), $this.data("ortsangabe"));
1247            
1248            return false;
1249        });
1250    }
1251    
1252    /*
1253    function _drawMarker(grpName, ciList){
1254        var lat = ciList[0].latitude1.replace(",", ".");
1255        var lon = ciList[0].longitude1.replace(",", ".");
1256        
1257        var mElem = $('<div class="marker">' + ciList.length + '</div>')
1258            .on('click', function() {
1259                $.log("markergroup clicked: elements: " + ciList);
1260                
1261                _unselectMap();
1262                
1263                //highlight marker
1264                $(this).addClass("selected");
1265                _drawCollectionItmesForMarker(grpName, ciList);
1266            });
1267            
1268        var marker = new mapboxgl.Marker({
1269            element:mElem[0],
1270            color: '#aeaeae'
1271        }).setLngLat({lon: lon, lat: lat})
1272          .addTo(map);
1273          
1274          
1275        return;
1276    }
1277    */
1278    
1279    function _unselectMap(){
1280        $("#item-map .marker").removeClass("selected");
1281        $itemContent.empty(); //clear selection
1282    }
1283    
1284    function _filterByCoordinates(lat, lon, ortsangabe){
1285        //1. show ergebnislisten tab
1286        $('a[href="#collection-results"]').tab('show');
1287        
1288        //2. set location filter
1289        collections.setLocationFilter(lat, lon, ortsangabe);
1290    }
1291    
1292    
1293    
1294    /*
1295    TODO: generate custom markers for
1296     *) cluster
1297     *) unclustered points
1298     
1299    https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/
1300    
1301    SO MACHEN:!!!
1302    Clustering Properties with Mapbox and HTML markers
1303    https://blog.mapbox.com/clustering-properties-with-mapbox-and-html-markers-bb353c8662ba
1304    
1305    */
1306    
1307    function drawCluster(){
1308        this._geoJsonData = _mapToGeoJson();
1309        
1310        map.on('load', function() {
1311            map.addSource("collection_items", {
1312                type: "geojson",
1313                data: _geoJsonData, // "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson",
1314                cluster: true,
1315                clusterMaxZoom: 12, // Max zoom to cluster points on
1316                clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
1317            });
1318        
1319            map.addLayer({
1320                id: "clusters",
1321                type: "circle",
1322                source: "collection_items",
1323                filter: ["has", "point_count"],
1324                paint: {
1325                    // Use step expressions (https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
1326                    // with three steps to implement three types of circles:
1327                    //   * Blue, 20px circles when point count is less than 100
1328                    //   * Yellow, 30px circles when point count is between 100 and 750
1329                    //   * Pink, 40px circles when point count is greater than or equal to 750
1330                    "circle-color": [
1331                        "step",
1332                        ["get", "point_count"],
1333                        "#51bbd6",
1334                        100,
1335                        "#f1f075",
1336                        750,
1337                        "#f28cb1"
1338                    ],
1339                    "circle-radius": [
1340                        "step",
1341                        ["get", "point_count"],
1342                        20,
1343                        100,
1344                        30,
1345                        750,
1346                        40
1347                    ]
1348                }
1349            });
1350        
1351            map.addLayer({
1352                id: "cluster-count",
1353                type: "symbol",
1354                source: "collection_items",
1355                filter: ["has", "point_count"],
1356                layout: {
1357                    "text-field": "{point_count_abbreviated}",
1358                    "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
1359                    "text-size": 12
1360                }
1361            });
1362            
1363            map.addLayer({
1364                id: "unclustered-point-outer",
1365                type: "circle",
1366                source: "collection_items",
1367                filter: ["!", ["has", "point_count"]],
1368                paint: {
1369                    "circle-color": "#ffffff",
1370                    "circle-radius": 20,
1371                    "circle-stroke-width": 1,
1372                    "circle-stroke-color": "#000000"
1373                }
1374            });
1375            map.addLayer({
1376                id: "unclustered-point",
1377                type: "symbol",
1378                source: "collection_items",
1379                filter: ["!", ["has", "point_count"]],
1380                layout:{
1381                    "text-field": ['get', 'itemCount'], //weird notation to access geojson-features properties (which we have set before); https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-feature-data
1382                    "text-size": 20
1383                }
1384            });
1385            
1386        
1387            // inspect a cluster on click
1388            map.on('click', 'clusters', function(e) {
1389                var features = map.queryRenderedFeatures(e.point, {
1390                    layers: ['clusters']
1391                });
1392                var clusterId = features[0].properties.cluster_id;
1393                map.getSource('collection_items').getClusterExpansionZoom(clusterId, function(err, zoom) {
1394                    if (err)
1395                        return;
1396        
1397                    map.easeTo({
1398                        center: features[0].geometry.coordinates,
1399                        zoom: zoom
1400                    });
1401                });
1402            });
1403        
1404            map.on('mouseenter', 'clusters', function() {
1405                map.getCanvas().style.cursor = 'pointer';
1406            });
1407            map.on('mouseleave', 'clusters', function() {
1408                map.getCanvas().style.cursor = '';
1409            });
1410        });
1411    }
1412    
1413    
1414    
1415    return {
1416        initMap: _initMap,
1417        drawMap:_drawMap
1418    };
1419    
1420})();
1421
1422
1423
1424
1425$( document ).ready(function() {
1426    
1427    $origDld = $('.original-image a');
1428    
1429    function initPanZoom(){
1430        $section = $('#inverted-contain');
1431        $section.find('.panzoom').panzoom({
1432            $zoomIn: $section.find(".zoom-in"),
1433            $zoomOut: $section.find(".zoom-out"),
1434            $zoomRange: $section.find(".zoom-range"),
1435            $reset: $section.find(".reset"),
1436            startTransform: 'scale(1.0)',
1437            increment: 0.1,
1438            minScale: 1
1439          });
1440          //.panzoom('zoom');    
1441    }
1442    
1443    
1444    if($(".item-list").length > 0){
1445        collections.init();
1446        collectionMap.initMap();
1447        
1448    }else{
1449        /***  DETAILSEITE ***/
1450        
1451        initPanZoom(); 
1452        
1453        $(".thumbs .thumb").on("click", function(){
1454            $section.find('.panzoom').panzoom("reset", false);
1455            $section.find('.panzoom').attr("src", this.src);
1456            $section.find('.panzoom').attr("alt", this.alt);  
1457            $origDld.attr("href", this.src);
1458        });
1459        
1460        //add querystring to anchor links; if there is no querystrings, nothing to do here
1461        //var queryString = window.location.search;
1462        var queryString = window.location;
1463        if(queryString && queryString != ""){
1464            $("a.footnote-link").each(function(){
1465                //this.href = queryString + this.href.substring(this.href.indexOf("#"), this.href.length);
1466                this.href = queryString.origin + queryString.pathname + this.href.substring(this.href.indexOf("#"), this.href.length);
1467            });
1468        }
1469        
1470        
1471        //kommentar functions
1472        $('#comment-modal').on('shown.bs.modal', function (event) {
1473            $('#name').focus();
1474        });
1475        $('#comment-modal').on('show.bs.modal', function (event) {
1476            //init
1477            $(".modal-form").removeClass("hidden");
1478            $(".modal-feedback").addClass("hidden");
1479            $(".saveComment").removeClass("hidden");
1480            $(".closeModal").removeClass("hidden");
1481            $(".clear-on-init").val("");
1482            $(".upload_link").empty();
1483            
1484          var button = $(event.relatedTarget) // Button that triggered the modal
1485          var modal = $(this);
1486          
1487          modal.find("input[name='collection_item']").attr("value", $(this).data("uuid"));
1488          modal.find("input[name='replied_to']").attr("value", button.data("replied_to"));
1489        });
1490        
1491        $(".saveComment").on("click", function(e){
1492            e.preventDefault();
1493            //trigger vlaidation on riquired filds
1494            $(".jv\\[required\\]").trigger("blur");
1495            if($(".comment-form .has-error").length > 0){
1496                //validation errors 
1497                return;
1498            }
1499            
1500           var $this = $(this);
1501           var data = $(".comment-form").serialize() + "&addComment=yes";
1502           var url = $(".comment-form").attr("action");
1503           
1504           //data = new FormData($("#comment-form")[0]);
1505           //saving text
1506           
1507            $this.button('loading');
1508            $(".closeModal").addClass("hidden");
1509           
1510           $.ajax({
1511              url: url,
1512              method: "POST",
1513              data: data
1514//              contentType: 'multipart/form-data',      // The content type used when sending data to the server.
1515//                cache: false,             // To unable request pages to be cached
1516//                processData:false,        // To send DOMDocument or non processed data file it is set to false
1517            }).done(function() {
1518                $this.button('reset');
1519                $(".modal-form").addClass("hidden");
1520                $(".modal-feedback").removeClass("hidden");
1521                $(".saveComment").addClass("hidden");
1522                $(".closeModal").removeClass("hidden");
1523            });
1524        });
1525        
1526        
1527    }
1528    
1529//document.getElementById('1599292138284') ?.closest('li') ?.style.setProperty('display', 'none', 'important'); //Ausblenden Kochbücher Petersmann in Sammlung-Filter
1530//document.getElementById('1599292138037') ?.closest('li') ?.style.setProperty('display', 'none', 'important'); //Ausblenden Forstner in Sammlung-Filter
1531    
1532    if(typeof collections !== "undefined" && collections._hideAlwaysHiddenThesItems){
1533        collections._hideAlwaysHiddenThesItems();
1534    }
1535    
1536});
1537
1538
1539
1540
1541
1542

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.