1class EventCalendar { 2 currentDate = new Date(); 3 id = 'events-calendar'; 4 lang = 'lt'; 5 tags = []; 6 events = []; 7 typesDictionary = {}; 8 constructor(id, lang, typesDictionary) { 9 this.id = '#' + id; 10 this.lang = lang; 11 this.typesDictionary = typesDictionary; 12 } 13 14 init() { 15 var self = this; 16 var eventTypes = Object.keys(this.typesDictionary); 17 for (var i = 0; i < eventTypes.length; i++) { 18 var eventType = eventTypes[i]; 19 var eventTypeName = this.typesDictionary[eventType]; 20 var template = '<a href="#" class="w-dropdown-link dd-tag" data="' + eventType + '">' + eventTypeName + '</a>'; 21 $('.events-tag-list').append(template); 22 } 23 24 $(this.id).find('.calendar-month-icon-left').on('click', function () { 25 self.currentDate.setMonth(self.currentDate.getMonth() - 1); 26 self.displayMonth(); 27 }); 28 29 $(this.id).find('.calendar-month-icon-right').on('click', function () { 30 31 self.currentDate.setMonth(self.currentDate.getMonth() + 1); 32 self.displayMonth(); 33 }) 34 this.displayMonth(); 35 36 $('.dd-tag').on('click', function (e) { 37 //e.preventDefault(); 38 $(this).addClass('selected'); 39 const tag = $(this).attr('data'); 40 self.addTag(tag); 41 return false; 42 }); 43 } 44 45 setButtonVisibility() { 46 var today = new Date(); 47 if (this.currentDate.getFullYear() > today.getFullYear() || 48 this.currentDate.getMonth() > today.getMonth()) { 49 $(this.id).find('.calendar-month-icon-left img').show(); 50 } else { 51 $(this.id).find('.calendar-month-icon-left img').hide(); 52 } 53 } 54 55 addTag(tag) { 56 if (this.tags.includes(tag)) { 57 return; 58 } 59 this.tags.push(tag); 60 var template = $('#tag-template').html(); 61 template = template.replace('[id]', tag); 62 template = template.replace('[name]', this.typesDictionary[tag]); 63 $('.selected-tags').append(template); 64 var self = this; 65 66 $('.tag-remove').on('click', (e) => { 67 const tag = $(e.currentTarget).prev().attr('data'); 68 self.removeTag(tag); 69 }); 70 this.displayEvents(); 71 72 } 73 74 removeTag(tag) { 75 for (var i = 0; i < this.tags.length; i++) { 76 if (this.tags[i] == tag) { 77 this.tags.splice(i, 1); 78 break; 79 } 80 } 81 $('.selected-tags').find("[data='" + tag + "']").parent().remove(); 82 $('.dd-tag[data="' + tag + '"]').removeClass('selected'); 83 this.displayEvents(); 84 85 } 86 87 //firstDayOffset 88 displayMonth() { 89 this.setButtonVisibility(); 90 var self = this; 91 var month = dict[this.lang].months[this.currentDate.getMonth()]; 92 $(this.id).find('.t-calendar-month').text(month + ", " + this.currentDate.getFullYear()); 93 var firstDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1); 94 var lastDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0); 95 96 var lastMonthLastDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 0); 97 var lastDayNumber = lastMonthLastDay.getDay(); 98 if (lastDayNumber == 0) { lastDayNumber = 7; } 99 100 const firstDayOffset = lastDayNumber == 7 ? 0 : lastDayNumber; 101 102 $(this.id).find('.calendar-block').remove(); 103 $(this.id).find('.calendar-block-outside').remove(); 104 $(this.id).find('.calendar-event').remove(); 105 $(this.id).find('.calendar-block-past').remove(); 106 //var totalDays = (firstDayOffset + lastDay.getDate()) <= 35 ? 35 : 42; 107 var totalDays = 42; 108 var today = new Date(); 109 110 for (var i = 0; i < totalDays; i++) { 111 var day = i - firstDayOffset; 112 var dayOutside = false; 113 var pastDay = false; 114 if (day < 0) { 115 day = lastMonthLastDay.getDate() + day; 116 dayOutside = true; 117 } else if (day >= lastDay.getDate()) { 118 dayOutside = true; 119 } 120 pastDay = today.getMonth() == this.currentDate.getMonth() && day < today.getDate() - 1; 121 122 if (pastDay) {
123 $(this.id).find('.calendar-wrap').append('<div class="calendar-block past"><div class= "t-calendar-day">' + (day + 1) + '</div></div>'); 124 125 } else if (!dayOutside) { 126 $(this.id).find('.calendar-wrap').append('<div class="calendar-block" data-day="' + (day + 1) + '"><div class= "t-calendar-day">' + (day + 1) + '</div></div>'); 127 } 128 else { 129 $(this.id).find('.calendar-wrap').append('<div class="calendar-block-outside"></div>'); 130 } 131 } 132 133 $.getJSON('/api/events?year=' + this.currentDate.getFullYear() + "&month=" + (this.currentDate.getMonth() + 1) + "&lang=" + self.lang, function (events) { 134 self.events = events; 135 self.displayEvents(); 136 }); 137 } 138 139 eventItemIncludesTag(eventItem) { 140 if (this.tags.length == 0) { 141 return true; 142 } 143 for (var t = 0; t < this.tags.length; t++) { 144 var tag = this.tags[t]; 145 if (eventItem['tags'].includes(tag)) { 146 return true; 147 } 148 } 149 return false; 150 } 151 152 displayEvents() { 153 $('.calendar-events').empty(); 154 $('.calendar-block').removeClass('has-event'); 155 $('.calendar-block').off('click'); 156 var dayEvents = []; 157 for (var i = 0; i < this.events.length; i++) { 158 var eventItem = this.events[i]; 159 if (!this.eventItemIncludesTag(eventItem)) { 160 continue; 161 } 162 163 var dates = eventItem['dates']; 164 if (!dates || dates.length == 0) { 165 continue; 166 } 167 var date = dates[0]; 168 var dateParts = date['date'].split('-'); 169 170 var month = dateParts[1]; 171 var day = dateParts[2]; 172 if ((this.currentDate.getMonth() + 1) != month) { 173 return; 174 } 175 var scrollToId = 'ce_' + day; 176 const searchBlock = ".calendar-block[data-day='" + parseInt(day) + "']"; 177 var eventBlock = $(this.id).find(searchBlock)[0]; 178 $(eventBlock).addClass('has-event'); 179 $(eventBlock).find('.t-calendar-day').addClass('has-event'); 180 if (!dayEvents.includes(day)) { 181 $(eventBlock).on('click', function () { 182 var sId = '#ce_' + $(this).attr('data-day').padStart(2, '0'); 183 $([document.documentElement, document.body]).animate({ 184 scrollTop: $(sId).offset().top 185 }, 500); 186 187 }); 188 } 189 dayEvents.push(day); 190 191 var template = $('#calendar-event-template').html(); 192 template = template.replace('[imgSrc]', eventItem['imageUrl']); 193 template = template.replace('[name]', eventItem['name']); 194 template = template.replace('[subtitle]', eventItem['subtitle'] ? eventItem['subtitle'] : ''); 195 var datesStr = ''; 196 for (var q = 0; q < dates.length; q++) { 197 var d = dates[q]; 198 datesStr = datesStr + (datesStr.length > 0 ? '<br/>' : '') + d['date'] + ' ' + d['time']; 199 } 200 template = template.replace('[date]', datesStr); 201 template = template.replace('[duration]', eventItem['duration'] > 0 ? minutesToTime(eventItem['duration']) : ''); 202 template = template.replace('[link]', eventItem['url']); 203 template = template.replace('[id]', scrollToId); 204 var tagsHtml = ''; 205 if (eventItem['tags'] && eventItem['tags'].length > 0) { 206 for (var t = 0; t < eventItem['tags'].length; t++) { 207 var tag = eventItem['tags'][t]; 208 var tagName = this.typesDictionary[tag] ? this.typesDictionary[tag] : tag; 209 tagsHtml += '<div class="calendar-event-tag">' + tagName + '</div> '; 210 } 211 } 212 template = template.replace('[tags]', tagsHtml); 213 $('.calendar-events').append(template); 214 } 215 } 216} 217function minutesToTime(mins) { 218 let h = Math.floor(mins / 60); 219 let m = mins % 60; 220 221 m = m < 10 ? '0' + m : m; 222 return `${h} val. ${m} min.`; 223}
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.