PageSourceSearch

https://www.norrtalje.se/Static/js/Abou.listnewsfilter.js?v=639258509620000000

js norrtalje.se collected 2026-10-02 10:29:00 UTC 17,992 bytes, 410 lines download raw bytes

1// Example of js-plugin; How to extend the Abou namespace
2; (function (window, document, Abou, $, undefined) {
3
4    /*
5        Overview: 
6        
7    */
8    var hasMobilePosition = !$(".filter-options").has("div");
9
10    Abou.listnewsfilter = (function () {
11
12
13        var filterViewModel = function (filterText, targetGroups, fromDate, toDate) {
14            var self = this;
15            self.filterText = ko.observable(filterText);
16            self.targetGroups = ko.observableArray(targetGroups);
17            self.fromDate = ko.observable(fromDate);
18            self.fromDateAsMoment = ko.computed(function () {
19                return moment(self.fromDate());
20            });
21            self.toDate = ko.observable(toDate);
22            self.toDateAsMoment = ko.computed(function () {
23                return moment(self.toDate());
24            });
25        };
26
27        var newsItemModel = function () {
28            var self = this;
29            self.id = 0;
30            self.name = "";
31            self.intro = "";
32            self.incident = false;
33            self.imageUrl = "";
34            self.epiUrl = "";
35            self.imageUrl = "";
36            self.date = null;
37            self.targetGroups = [];
38        };
39
40        var initFilterViewModel = function () {
41            var filterText = $("#NewsListPage [name=query]").val();
42            var targetGroups = [];
43            $("#NewsListPage [name=tgid]:checked").each(function () {
44                targetGroups.push($(this).val());
45            });
46            var fromDateText = $("#NewsListPage [name=fromDate]").val();
47            var toDateText = $("#NewsListPage [name=toDate]").val();
48
49            return new filterViewModel(filterText, targetGroups, fromDateText, toDateText);
50        };
51
52        var NewsListViewModel = function (newsItems) {
53            var self = this;
54            self.newsItems = newsItems;
55            self.newsItems.sort(function (a, b) {
56                if (a.date.isAfter(b.date)) return -1;
57                if (a.date.isBefore(b.date)) return 1;
58                return 0;
59            });
60
61            self.filters = initFilterViewModel();
62
63            self.filterOnText = function (newsItemsToFilter) {
64                var filterText = self.filters.filterText();
65                if (!filterText) {
66                    return newsItemsToFilter;
67                }
68                var result = [];
69
70                //Regexp created once for performance reasons.
71                //Note: Js has trouble with word boundaries and 'åäö' the current solution gives false positives for words when 
72                // search phrase begins with åäö. Ie: searching for "äga" matches "säga". This seems however to be the least bad solution.
73                var textRegExp = new XRegExp('\\p{Separator}' + filterText, 'i');
74                $.each(newsItemsToFilter, function (index, newsItem) {
75                    var textToTest = ' ' + newsItem.name + ' ' + newsItem.intro;
76                    if (textRegExp.test(textToTest)) {
77                        result.push(newsItem);
78                    }
79                });
80                return result;
81            };
82
83            self.filterOnTargetGroups = function (newsItemsToFilter) {
84                var activeTargetGroups = self.filters.targetGroups();
85
86                self.displayActiveTargetGroups(activeTargetGroups);
87
88                if (!activeTargetGroups || !activeTargetGroups.length) {
89                    return newsItemsToFilter;
90                }
91                var result = [];
92
93                $.each(newsItemsToFilter, function (index, newsItem) {
94                    var hit = false;
95                    $.each(newsItem.targetGroups, function (index, eventTg) {
96                        if ($.inArray(eventTg.pageId, activeTargetGroups) > -1) {
97                            hit = true;
98                        }
99                    });
100                    if (hit) {
101                        result.push(newsItem);
102                    }
103                });
104
105                return result;
106            };
107            self.displayActiveTargetGroups = function (targetGroups) {
108                var selectedTargetGroupText = $(".current-target-group");
109                var newSelectedTargetGroups = "";
110                if (targetGroups.length == 0) {
111                    newSelectedTargetGroups = "För vem?";
112                }
113                else if (targetGroups.length == 1) {
114                    newSelectedTargetGroups = $("#NewsListPage [name=tgid]:checked + label .target-group-name").text();
115                }
116                else {
117                    newSelectedTargetGroups = "För vem? (" + targetGroups.length + "st)";
118                }
119                selectedTargetGroupText.text(newSelectedTargetGroups);
120            }
121
122            self.filterOnDates = function (newsItemsToFilter) {
123                var fromDateAsMoment = self.filters.fromDateAsMoment();
124                var toDateAsMoment = self.filters.toDateAsMoment();
125                if (!fromDateAsMoment.isValid() && !toDateAsMoment.isValid()) {
126                    return newsItemsToFilter;
127                }
128                var partResult = newsItemsToFilter;
129                if (fromDateAsMoment.isValid()) {
130                    partResult = [];
131                    $.each(newsItemsToFilter, function (index, newsItem) {
132                        if (newsItem.date.isValid() && newsItem.date.isAfter(fromDateAsMoment)) {
133                            partResult.push(newsItem);
134                        }
135                    });
136                }
137                var result = partResult;
138                if (toDateAsMoment.isValid()) {
139                    result = [];
140                    toDateAsMoment = toDateAsMoment.add(1, 'days'); //Add one day to achieve 'including' selection
141                    $.each(partResult, function (index, newsItem) {
142                        //firstly check toDate. Todate can be null, if so check against fromdate instead.
143                        if ((newsItem.date.isValid() && newsItem.date.isBefore(toDateAsMoment))
144                            || (newsItem.date.isValid() && newsItem.date.isBefore(toDateAsMoment))) {
145                            result.push(newsItem);
146                        }
147                    });
148                }
149                return result;
150            };
151
152            self.resetDateFilters = function () {
153                self.filters.fromDate("");
154                self.filters.toDate("");
155
156                updateSelectedDates();
157
158                $(".chosen-dates").text("Datum");
159
160                $(".hasDatepicker").datepicker('setDate', null);
161                $(".hasDatepicker").datepicker('setDate', null);
162
163                self.filters.filterText("");
164            };
165
166            self.resetTargetGroupsFilters = function () {
167                self.filters.targetGroups.removeAll();
168
169                self.filters.filterText("");
170            }
171
172            self.hitNewsItems = ko.computed(function () {
173                var hitNewsItems = self.filterOnText(self.newsItems);
174                hitNewsItems = self.filterOnTargetGroups(hitNewsItems);
175                //hitOccasions = self.filterOnCategories(hitOccasions);
176                hitNewsItems = self.filterOnDates(hitNewsItems);
177
178                return hitNewsItems;
179            });
180
181            self.pageSize = 5;
182            self.visibleCount = ko.observable(self.pageSize);
183            self.visibleNewsItems = ko.computed(function () {
184                return self.hitNewsItems().slice(0, self.visibleCount());
185            });
186
187            var clickCount = 1;
188            var clickCountInQuery = Number(getUrlVars()["view_more"]);
189            if (clickCountInQuery > 1) {
190                clickCount = clickCountInQuery;
191            }
192            $(document).ready(function () {
193                self.visibleCount(clickCount * self.pageSize)
194            });
195            self.showMore = function () {
196                var currentLoc = window.location.href;
197                clickCount++;
198                window.history.pushState("", "", updateQueryStringParameter(currentLoc, 'view_more', clickCount));
199                self.visibleCount(clickCount * self.pageSize)
200            }
201        };
202
203        var toggleDisplay = function (event) {
204            //toggle class on parent element
205            $("#FilteredNewsList").toggleClass("displayFiltersInMobile");
206            event.preventDefault();
207        };
208
209        var closeDisplay = function (e) {
210            e.preventDefault();
211            $(".option:visible").slideUp();
212            $(".filter-action-button.active").focus();
213            $(".filter-action-button.active").attr('aria-expanded', 'false');
214            $(".filter-action-button.active").removeClass("active");
215        }
216
217        var setupToggleFunction = function () {
218            var activeOption;
219            $(".filter-action-button").each(function () {
220                var targetId = $(this).attr('aria-controls');
221                $(this).on("click", function (e) {
222                    if ($(this).hasClass("active")) {
223                        $(this).toggleClass("active");
224                        $(this).attr('aria-expanded', 'false');
225                    } else {
226                        $(".filter-action-button.active").removeClass("active");
227                        $(this).toggleClass("active");
228                        $(this).attr('aria-expanded', 'true');
229
230                        var that = this;
231                        setTimeout(function () {
232                            if ($(that).attr('data-action-target') == 'date') {
233                                $('.from-date-holder').find('.ui-datepicker-next').focus();
234                            }
235                            else {
236                                $('#' + targetId).find('input:first-of-type').focus();
237                            }
238                        }, 200);
239                    }
240                    e.preventDefault();
241                    activeOption = $(this).data("action-target");
242
243                    if ($(".option:visible").hasClass(activeOption)) {
244                        $(".option." + $(this).data("action-target")).slideToggle("fast");
245                    }
246                    else if ($(".option:visible").length > 0) {
247                        if (!Abou.common.isBelowMobileMode()) {
248                            $(".option:visible").toggle();
249                            $(".option." + $(this).data("action-target")).toggle();
250                        }
251                        else {
252                            $(".option." + $(this).data("action-target")).slideToggle("fast");
253                        }
254                    }
255                    else {
256                        $(".option." + $(this).data("action-target")).slideToggle("fast");
257                    }
258                });
259                if (targetId === "eventList-filter-date") {
260                    $('.from-date-holder').find('.ui-datepicker-next').on("keydown", function(e) {
261                        if ((e.key === 'Tab' || e.keyCode === 9) && e.shiftKey) {
262                            closeDisplay(e);
263                        }
264                    })
265                }
266                else {
267                    $('#' + targetId).find('input:first-of-type').on("keydown", function(e)
268                    {
269                        if ((e.key === 'Tab' || e.keyCode === 9) && e.shiftKey) {
270                            closeDisplay(e);
271                        }
272                    })
273                }
274            });
275        };
276        var updateSelectedDates = function () {
277            
278            var fromDate = moment($(".from-date-place-holder").text());
279            var toDate = moment($(".to-date-place-holder").text());
280            var selecteDateString = "";
281
282            if (fromDate.isValid()) {
283                selecteDateString += fromDate.format("DD") + " " + fromDate.format("MMM");
284            }
285            if (toDate.isValid()) {
286                selecteDateString += " till " + toDate.format("DD") + " " + toDate.format("MMM");
287            }            
288            $(".chosen-dates").text(selecteDateString);
289        };
290        
291        var setToggleOptionsPosition = function () {
292            
293            if (Abou.common.isBelowMobileMode() && !hasMobilePosition) {
294                hasMobilePosition = !hasMobilePosition;
295                $("#FilteredNewsList .filter-action-button").each(function () {
296                    activeOption = $(this).data("action-target");
297                    $(this).after($(".option." + activeOption).detach());
298                });
299            }
300            else if (hasMobilePosition && !Abou.common.isBelowMobileMode()) {
301                hasMobilePosition = !hasMobilePosition;
302                $(".filter-options").append($(".option").detach());
303            }
304        }
305
306        // Public properties
307        return {
308            init: function () {
309                $(".searchForm [type=text][name=fromDate], .searchForm [type=text][name=toDate]").prop('disabled', false);
310                $(".filterWrapper .filters .dateFilters").show();
311
312                var datePickerOptionsFrom = {
313                    dateFormat: "yy-mm-dd",
314                    minDate: "-2y",
315                    maxDate: "0",
316                    defaultDate: "-1m",
317                    onSelect: function (date) {                        
318                        $(".from-date-place-holder").text(date);
319                        $(".from-date-place-holder").val(date);
320                        $(".from-date-place-holder").change();
321                        updateSelectedDates();
322                    }
323                };
324
325                var datePickerOptionsTo = {
326                    dateFormat: "yy-mm-dd",
327                    minDate: "-2y",
328                    maxDate: "0",
329                    onSelect: function (date) {
330                        $(".to-date-place-holder").text(date);
331                        $(".to-date-place-holder").val(date);
332                        $(".to-date-place-holder").change();
333                        updateSelectedDates();
334                    }
335                };
336                
337                var fromDatePicker = $(".from-date-holder").datepicker(datePickerOptionsFrom);
338                var toDatePicker = $(".to-date-holder").datepicker(datePickerOptionsTo);
339                
340                //update datepickers depending on others value
341                $(".searchForm [type=text][name=fromDate]").change(function (event) {
342                    var currentFromDate = fromDatePicker.datepicker("getDate");
343                    var minDate = !!currentFromDate ? currentFromDate : "-1m";
344                    toDatePicker.datepicker("option", "minDate", minDate);
345                });
346                $(".searchForm [type=text][name=toDate]").change(function (event) {
347                    var currentToDate = toDatePicker.datepicker("getDate");
348                    var maxDate = !!currentToDate ? currentToDate : "0";
349                    fromDatePicker.datepicker("option", "maxDate", maxDate);
350                });
351                //}
352
353                if ($("input.jsonNewsItems").length) {
354                    var newsItemsJson = JSON.parse($("input.jsonNewsItems").val());
355                    var newsItemModels = [];
356                    $.each(newsItemsJson, function (index, jsonNewsItem) {
357                        var newsModel = new newsItemModel();
358                        newsModel.id = jsonNewsItem.Id;
359                        newsModel.name = jsonNewsItem.Name;
360                        newsModel.intro = jsonNewsItem.Intro;
361                        newsModel.incident = jsonNewsItem.Incident;
362                        newsModel.imageUrl = jsonNewsItem.ImageUrl;
363                        newsModel.epiUrl = jsonNewsItem.EpiUrl;
364                        newsModel.imageUrl = jsonNewsItem.ImageUrl;
365                        newsModel.date = moment(jsonNewsItem.Date);
366                        newsModel.targetGroups = [];
367                        $.each(jsonNewsItem.TargetGroups, function (index, targetGroup) {
368                            newsModel.targetGroups.push({
369                                pageId: targetGroup.PageId,
370                                iChar: !!targetGroup.Char ? "&#x" + targetGroup.Char + ";" : "",
371                                color: targetGroup.Color
372                            });
373                        });
374
375                        newsItemModels.push(newsModel);
376                    });
377
378                    var newsListViewModel = new NewsListViewModel(newsItemModels);
379                    ko.applyBindings(newsListViewModel, document.getElementById("FilteredNewsList"));
380                }
381
382                $(".filterLink").click(toggleDisplay);
383                $(".close-options-button").click(closeDisplay);
384
385                $(".close-options-button").on("keydown", function(e) {
386
387                    if (e.key === 'Tab' || e.keyCode === 9) {
388                        if (!e.shiftKey) {
389                            closeDisplay(e);
390                        }
391                    }
392                })
393
394                $("#newsListForm").submit(function (e) {
395                    e.preventDefault();
396                });
397
398                setupToggleFunction();
399
400                $(window).on("resize", function ()
401                {
402                    setToggleOptionsPosition();
403                });
404
405                setToggleOptionsPosition();
406            }
407        };
408    }());
409
410}(this, this.document, window.Abou = window.Abou || {}, jQuery));

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.