1/* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6var ra, FullCalendar, displayGradesRowClass, displayTableRowClass, displayListRowClass; 7 8if (typeof (ra) === "undefined") { 9 ra = {}; 10} 11if (typeof (ra.display) === "undefined") { 12 ra.display = {}; 13} 14ra.display.walksTabs = function (mapOptions, data) { 15 this.events = new ra.events(); 16 this.map = null; 17 this.lmap = null; 18 this.cluster = null; 19 this.elements = null; 20 this.settings = { 21 walkClass: "walk", 22 displayClass: "detailsView", 23 displayStartTime: true, 24 displayStartDescription: true, 25 displayDetailsPrompt: true, 26 tabOrder: ["Grades", "Table", "List", "Calendar", "Map"], 27 tableFormat: [{"title": "Date", "items": ["{dowddmm}"]}, {"title": "Meet", "items": ["{meet}", "{,meetGR}", "{,meetPC}"]}, {"title": "Start", "items": ["{start}", "{,startGR}", "{,startPC}"]}, {"title": "Title", "items": ["{title}", "{mediathumbr}"]}, {"title": "Difficulty", "items": ["{difficulty+}"]}, {"title": "Contact", "items": ["{contact}"]}], 28 listFormat: ["{dowdd}", "{,meet}", "{,start}", "{,title}", "{,distance}", "{,contactname}", "{,telephone}"], 29 gradesFormat: ["{gradeimg}", "{dowddmm}", "{,title}", "{,distance}", "{,contactname}"], 30 calendarFormat: ["{gradeimgMiddle}", "{title}", "{,distance}", ",", " ", "{meetTime}", "{< or >startTime}"], 31 withMonth: ["{dowShortddmm}", "{dowddmm}", "{dowddmmyyyy}"], 32 itemsPerPage: 20, 33 options: null, 34 displayBookingsTable: false 35 }; 36 this.paginationOptions = {pagination: { 37 "10 per page": 10, 38 "20 per page": 20, 39 "25 per page": 25, 40 "50 per page": 50, 41 "100 per page": 100, 42 "View all": 0 43 }, 44 itemsPerPage: 25, 45 currentPage: 1 46 }; 47 this.optionTag = {}; 48 this.printContent = null; 49 this.mapOptions = mapOptions; 50 if (data.customTabOrder !== null) { 51 this.settings.tabOrder = data.customTabOrder; 52 } 53 if (data.customGradesFormat !== null) { 54 this.settings.gradesFormat = data.customGradesFormat; 55 } 56 if (data.customListFormat !== null) { 57 this.settings.listFormat = data.customListFormat; 58 } 59 if (data.customTableFormat !== null) { 60 this.settings.tableFormat = data.customTableFormat; 61 } 62 if (data.customCalendarFormat !== null) { 63 this.settings.CalendarFormat = data.customCalendarFormat; 64 } 65 this.legendposition = data.legendposition; 66 if (data.displayClass !== "") { 67 this.settings.displayClass = data.displayClass; 68 } 69 this.settings.displayBookingsTable = data.displayBookingsTable; 70 71 data.walks.forEach(phpwalk => { 72 var newEvent = new ra.event(); 73 newEvent.convertPHPWalk(phpwalk); 74 this.events.registerEvent(newEvent); 75 ra.walk.registerEvent(newEvent); 76 }); 77 data.walks = null; 78 ra.walk.displayUrlWalkPopup(); 79 this.load = function () { 80 81 var tags = [ 82 {name: 'walksFilter', parent: 'root', tag: 'div', attrs: {class: 'walksFilter'}}, 83 {name: 'clear', parent: 'root', tag: 'div', attrs: {class: 'clear'}}, 84 {name: 'tabs', parent: 'root', tag: 'div'}, 85 {name: 'bookings', parent: 'root', tag: 'div'} 86 ]; 87 this.masterdiv = document.getElementById(this.mapOptions.divId); 88 this.elements = ra.html.generateTags(this.masterdiv, tags); 89 this.events.setAllWalks(); 90 this.events.setFilters(this.elements.walksFilter); 91 var _this = this; 92 this.addTabs(); 93 if (this.settings.displayBookingsTable) { 94 var book = new ra.bookings.displayEvents(); 95 book.display(this.elements.bookings); 96 } 97 document.addEventListener("reDisplayWalks", function () { 98 _this.events.setDisplayFilter(); 99 _this.displayWalks(); 100 }); 101 102 }; 103 this.addTabs = function () { 104 var _this = this; 105 var options = {tabClass: 'walksDisplay', 106 tabs: {}}; 107 this.settings.tabOrder.forEach(function (value, index, array) { 108 options.tabs[value] = {title: value}; 109 }); 110 this.elements.tabs.addEventListener("displayTabContents", function (e) { 111 _this.option = e.tabDisplay.tab; 112 _this.displayTag = e.tabDisplay.displayInElement; 113 _this.displayWalks(); 114 }); 115 var tabs = new ra.tabs(this.elements.tabs, options); 116 tabs.display(); 117 }; 118 119 this.displayWalks = function () { 120 var tag = this.displayTag; 121 tag.innerHTML = ''; 122 this.printContent = null; 123 if (this.events.length() === 0) { 124 tag.innerHTML = '<h3>Sorry there are no walks at the moment.</h3>'; 125 return; 126 } 127 if (this.events.getNoEventsToDisplay() === 0) { 128 tag.innerHTML = "<h3>Sorry, but no walks meet your filter search.</h3>"; 129 return; 130 } 131 switch (this.option) { 132 case "Grades": 133 this.displayWalksGrades(tag); 134 break; 135 case "List": 136 this.displayWalksList(tag); 137 break; 138 case "Table": 139 this.displayWalksTable(tag); 140 break; 141 case "Calendar": 142 this.displayWalksCalendar(tag); 143 break; 144 case "Map": 145 this.displayMap(tag); 146 break; 147 case "Contacts": 148 this.displayContacts(tag); 149 break; 150 } 151 }; 152 153 154 this.displayWalksGrades = function (tag) { 155 var tags = [ 156 {name: 'legend', parent: 'root', tag: 'div'}, 157 {name: 'content', parent: 'root', tag: 'div'} 158 ]; 159 var self = this; 160 var elements = ra.html.generateTags(tag, tags); 161 elements.legend.innerHTML = "<p class='noprint'>Click on item to display full details of walk</p>"; 162 elements.content.addEventListener('reportPagination', function (e) { 163 self.paginationOptions.itemsPerPage = e.cvList.itemsPerPage; 164 self.paginationOptions.currentPage = e.cvList.currentPage; 165 }); 166 this.addPrintButton(elements.legend); 167 this.addToDiaryButton(elements.legend);
168 var month = ""; 169 var div; 170 var should = this.shouldDisplayMonth('Grades'); 171 var list = new ra.paginatedList(elements.content, this.paginationOptions); 172 this.events.forEachFiltered($walk => { 173 var displayMonth = month !== $walk.getIntValue("basics", "displayMonth") && should; 174 div = this.displayWalk_Grades($walk, displayMonth); 175 list.listItem(div); 176 month = $walk.getIntValue("basics", "displayMonth"); 177 }); 178 list.listEnd(); 179 this.printContent = list; 180 }; 181 this.displayWalksList = function (tag) { 182 var div; 183 var self = this; 184 var month = ""; 185 var should = this.shouldDisplayMonth('List'); 186 var tags = [ 187 {name: 'legend', parent: 'root', tag: 'div'}, 188 {name: 'content', parent: 'root', tag: 'div'} 189 ]; 190 var elements = ra.html.generateTags(tag, tags); 191 elements.legend.innerHTML = "<p class='noprint'>Click on item to display full details of walk</p>"; 192 elements.content.addEventListener('reportPagination', function (e) { 193 self.paginationOptions.itemsPerPage = e.cvList.itemsPerPage; 194 self.paginationOptions.currentPage = e.cvList.currentPage; 195 196 }); 197 this.addPrintButton(elements.legend); 198 this.addToDiaryButton(elements.legend); 199 var list = new ra.paginatedList(elements.content, this.paginationOptions); 200 this.events.forEachFiltered($walk => { 201 var displayMonth = month !== $walk.getIntValue("basics", "displayMonth") && should; 202 div = this.displayWalk_List($walk, displayMonth); 203 list.listItem(div); 204 month = $walk.getIntValue("basics", "displayMonth"); 205 }); 206 list.listEnd(); 207 this.printContent = list; 208 }; 209 this.displayWalksTable = function (tag) { 210 var month = ""; 211 var self = this; 212 var should = this.shouldDisplayMonth('Table'); 213 var tags = [ 214 {name: 'legend', parent: 'root', tag: 'div'}, 215 {name: 'content', parent: 'root', tag: 'div'} 216 ]; 217 var elements = ra.html.generateTags(tag, tags); 218 elements.legend.innerHTML = "<p class='noprint'>Click on item to display full details of walk</p>"; 219 elements.content.addEventListener('reportPagination', function (e) { 220 self.paginationOptions.itemsPerPage = e.cvList.itemsPerPage; 221 self.paginationOptions.currentPage = e.cvList.currentPage; 222 223 }); 224 this.addPrintButton(elements.legend); 225 this.addToDiaryButton(elements.legend); 226 var table = new ra.paginatedTable(elements.content, this.paginationOptions); 227 table.tableHeading(this.settings.tableFormat); 228 this.events.forEachFiltered($walk => { 229 var displayMonth = month !== $walk.getIntValue("basics", "displayMonth") && should; 230 this.displayWalk_Table(table, $walk, displayMonth); 231 month = $walk.getIntValue("basics", "displayMonth"); 232 }); 233 table.tableEnd(); 234 this.printContent = table; 235 }; 236 this.displayWalksCalendar = function (tag) { 237 var events = []; 238 var $items = this.settings.calendarFormat; 239 var tags = [ 240 {name: 'legend', parent: 'root', tag: 'div'}, 241 {name: 'content', parent: 'root', tag: 'div'} 242 ]; 243 var elements = ra.html.generateTags(tag, tags); 244 elements.legend.innerHTML = "<p class='noprint'>Click on item to display full details of walk</p>"; 245 246 this.events.forEachFiltered($walk => { 247 var event = {}; 248 event.id = $walk.admin.id; 249 event.start = $walk.basics.walkDate; 250 if ($walk.basics.multiDate) { 251 event.end = $walk.basics.finishDate; 252 } 253 event.raContent = '<div class="ra calendar event">' + $walk.getEventValues($items, false) + '</div>'; 254 event.textColor = '#111111'; 255 if ($walk.admin.status === 'Cancelled') { 256 event.textColor = 'red'; 257 event.backgroundColor = 'white'; 258 } else { 259 event.backgroundColor = '#EFEFEF'; 260 event.borderColor = '#AAAAAA'; 261 } 262 263 event.classNames = ['pointer']; 264 event.display = 'block'; 265 // event.eventContent = {html: '<div class="fc-event-main-frame"><span class="ra wrap">' + $walk.getEventValues( $items, false) + '</span></div>'}; 266 // event.eventContent = {html: '<div class="fc-event-main-frame"><span class="ra wrap">xgbdfhngdnhg</span></div>'}; 267 event.eventContent = {html: ''}; 268 events.push(event); 269 }); 270 271 var calendar = new FullCalendar.Calendar(elements.content, { 272 height: 'auto', 273 selectable: true, 274 displayEventTime: false, 275 headerToolbar: {center: 'dayGridMonth,listMonth'}, // buttons for switching between views 276 events: events, 277 views: { 278 dayGrid: { 279 eventTimeFormat: { 280 hour: '2-digit', 281 minute: '2-digit', 282 meridiem: false 283 } 284 }, 285 timeGrid: { 286 // options apply to timeGridWeek and timeGridDay views 287 }, 288 week: { 289 // options apply to dayGridWeek and timeGridWeek views 290 }, 291 day: { 292 // options apply to dayGridDay and timeGridDay views 293 } 294 }, 295 eventClick: function (info) { 296 var id = info.event.id; 297 ra.walk.displayWalkID(info, id); 298 }, 299 eventContent: function (arg) { 300 return { 301 html: arg.event.extendedProps.raContent 302 }; 303 } 304 305 }); 306 calendar.render(); 307 }; 308 this.displayMap = function (tag) { 309 var b = ra.baseDirectory(); 310 this.lmap = new ra.leafletmap(tag, this.mapOptions); 311 this.lmap.display(); 312 this.map = this.lmap.map(); 313 this.cluster = new ra.map.cluster(this.map); 314 var sImg = b + "media/lib_ramblers/images/marker-start.png"; 315 var cImg = b + "media/lib_ramblers/images/marker-cancelled.png"; 316 var aImg = b + "media/lib_ramblers/images/marker-area.png"; 317 318 var leg = document.createElement('p'); 319 leg.innerHTML = '<strong>Zoom</strong> in to see where our walks are going to be. <strong>Click</strong> on a walk to see details.'; 320 this.lmap.preMapDiv().appendChild(leg); 321 leg = document.createElement('div'); 322 leg.innerHTML += '<img src="' + sImg + '" alt="Walk start" height="26" width="26"> Start locations <img src="' + cImg + '" alt="Cancelled walk" height="26" width="26"> Cancelled walk <img src="' + aImg + '" alt="Walking area" height="26" width="26"> Walk in that area.'; 323 this.lmap.preMapDiv().appendChild(leg); 324
325 this.events.forEachFiltered($walk => { 326 $walk.addWalkMarker(this.cluster, this.settings.walkClass); 327 }); 328 this.cluster.addClusterMarkers(); 329 this.cluster.zoomAll(); 330 this.map.invalidateSize(); 331 }; 332 this.displayContacts = function (tag) { 333 var $contacts = []; 334 this.events.forEachFiltered($walk => { 335 var contactName = $walk.getEventValue("{contactperson}"); 336 var telephone1 = $walk.getEventValue("{telephone1}"); 337 var telephone2 = $walk.getEventValue("{telephone2}"); 338 var $contact = {name: contactName, telephone1: telephone1, telephone2: telephone2}; 339 if (!ra.contains($contacts, $contact)) { 340 $contacts.push($contact); 341 } 342 }); 343 $contacts.sort(function (a, b) { 344 if (a.name.toLowerCase() > b.name.toLowerCase()) { 345 return 1; 346 } 347 return -1; 348 }); 349 var contactsFormat = [{"title": "Contact Name", "options": {align: "left"}, field: {type: 'text', filter: true, sort: false}}, 350 {"title": "Telephone", "options": {align: "left"}}, 351 {"title": "Alt Telephone", "options": {align: "left"}}]; 352 var table = new ra.paginatedTable(tag); 353 table.tableHeading(contactsFormat);
354 $contacts.forEach($contact => { 355 table.tableRowStart(); 356 table.tableRowItem($contact.name, contactsFormat[0]); 357 table.tableRowItem($contact.telephone1); 358 table.tableRowItem($contact.telephone2); 359 table.tableRowEnd(); 360 }); 361 table.tableEnd(); 362 }; 363 364 this.shouldDisplayMonth = function (view) { 365 var result = true; 366 switch (view) { 367 case "Grades": 368 this.settings.gradesFormat.forEach($item => { 369 if (this.settings.withMonth.includes($item)) { 370 result = false; 371 } 372 }); 373 break; 374 case "List": 375 this.settings.listFormat.forEach($item => { 376 if (this.settings.withMonth.includes($item)) { 377 result = false; 378 } 379 }); 380 break; 381 case "Table": 382 this.settings.tableFormat.forEach($col => { 383 $col.items.forEach($item => { 384 if (this.settings.withMonth.includes($item)) { 385 result = false;
386 } 387 }); 388 }); 389 break; 390 } 391 return result; 392 }; 393 394 this.displayWalk_Grades = function (walk, displayMonth) { 395 var out, div, span; 396 397 div = document.createElement('div'); 398 if (displayMonth) { 399 var month = document.createElement('h3'); 400 month.innerHTML = walk.getIntValue("basics", "displayMonth"); 401 month.classList.add('ra', 'walk', 'month'); 402 div.appendChild(month); 403 } 404 405 div.classList.add("walk" + walk.admin.status); 406 span = document.createElement('span'); 407 span.classList.add('walkdetail'); 408 if (typeof displayGradesRowClass === 'function') { 409 span.classList.add(displayGradesRowClass(walk)); 410 } 411 out = walk.getEventValues(this.settings.gradesFormat); 412 span.innerHTML = walk.addTooltip(out); 413 div.appendChild(span); 414 return div; 415 }; 416 this.displayWalk_List = function (walk, displayMonth) { 417 var items = this.settings.listFormat; 418 var div = document.createElement('div'); 419 if (displayMonth) { 420 var month = document.createElement('h3'); 421 month.innerHTML = walk.getIntValue("basics", "displayMonth"); 422 month.setAttribute('class', 'ra walk month'); 423 div.appendChild(month); 424 } 425 var span = document.createElement('span'); 426 span.innerHTML = walk.addTooltip(walk.getEventValues(items)); 427 span.classList.add("walk" + walk.admin.status); 428 span.classList.add("walkdetail"); 429 if (typeof displayListRowClass === 'function') { 430 span.classList.add(displayListRowClass(walk)); 431 } 432 div.appendChild(span); 433 return div; 434 }; 435 436 this.displayWalk_Table = function (table, walk, displayMonth) { 437 438 var tr = table.tableRowStart(); 439 tr.classList.add("walk" + walk.admin.status); 440 if (typeof displayTableRowClass === 'function') { 441 tr.classList.add(displayTableRowClass(walk)); 442 } 443 this.settings.tableFormat.forEach($col => { 444 table.tableRowItem(walk.addTooltip(walk.getEventValues($col.items))); 445 }); 446 var monthDisplay = null; 447 if (displayMonth) { 448 monthDisplay = document.createElement('h3'); 449 monthDisplay.innerHTML = walk.getIntValue("basics", "displayMonth"); 450 } 451 table.tableRowEnd(monthDisplay, 'ra walk month'); 452 return tr; 453 }; 454 455 this.addPrintButton = function (tag) { 456 var printButton = document.createElement('button'); 457 printButton.setAttribute('class', 'link-button tiny button mintcake right'); 458 printButton.textContent = 'Print'; 459 tag.appendChild(printButton); 460 var _this = this; 461 printButton.addEventListener('click', function () { 462 if (this.printContent !== null) { 463 _this._print(); 464 } 465 }); 466 }; 467 this._print = function () { 468 var content = document.createElement('div'); 469 var heading = document.createElement('h2'); 470 heading.innerHTML = "Walking Programme"; 471 content.appendChild(heading); 472 var node = this.printContent.getPrintAll(); 473 content.appendChild(node); 474 ra.html.printHTML(content); 475 }; 476 this.addToDiaryButton = function (tag) { 477 var diary = document.createElement('button'); 478 diary.setAttribute('class', 'link-button tiny button mintcake right'); 479 diary.title = 'Download an .ICS file, import to Diary'; 480 diary.textContent = 'Add to Calendar'; 481 tag.appendChild(diary); 482 var _this = this; 483 diary.addEventListener('click', function () { 484 _this.events.setDisplayFilter(); 485 var file = new ra.ics.file(); 486 _this.events.forEachFiltered($walk => { 487 $walk.addWalktoIcs(file); 488 }); 489 file.download(); 490 }); 491 }; 492};
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.