1/** Shared booking UI: only standalone instances use the existing direct-shop convention. */ 2function TMwidgetBookingUrl(value) { 3 var url = new URL(value, window.location.href); 4 if (url.protocol !== 'https:' || url.username || url.password) throw new Error('Invalid shop URL'); 5 url.searchParams.set('return_url', 'xyz'); 6 url.searchParams.set('session_id', 'xyz'); 7 url.searchParams.delete('hide_frame'); 8 return url.href; 9} 10function TMopenWidgetBooking(source, container, value) { 11 var root = TMroot(source); 12 if (root.attr('data-tm-booking') !== 'shop') return false; 13 var url = TMwidgetBookingUrl(value); 14 container.find('iframe').hide(); 15 container.find('.tm-widget-checkout').remove(); 16 jQuery('<a>', { 17 'class': 'button tm-widget-checkout', href: url, 18 target: root.attr('data-tm-newwindow') === '1' ? '_blank' : '_top', 19 rel: 'noopener noreferrer', text: TMdialog(source).klicke_shop 20 }).appendTo(container); 21 return true; 22} 23 24 25 26jQuery( document ).ready(function() { 27 28 var arrowRight = '→'; 29 30 $ = jQuery; 31 32 if($(".success_message").length>0){ 33 $([document.documentElement, document.body]).animate({ 34 scrollTop: $(".success_message").offset().top 35 }, 100); 36 } 37 38 if($(".eventdatum").length==0){ 39 return; 40 } 41 42 //Es gibt kein Warenkorb - Fahrt kann nicht dargestellt werden 43 if($(".travelmanager-basket").length==0 && $(".tm_plugin[data-tm-booking=shop]").length==0) 44 { 45 $(".eventinfo_container").each(function () { $(this).html(TMdialog(this)["kein_warenkorb"]); }); 46 return; 47 } 48 49 //Lokale Sprachdatei für den Kalender setzen 50 if(calendarLocale!==undefined){ 51 jQuery.datepicker.setDefaults(calendarLocale); 52 } 53 54 var vermittler_id=""; 55 if($(".eventinfo_container").first().attr("reference")!=""){ 56 vermittler_id = $(".eventinfo_container").first().attr("reference"); 57 } 58 59 //Datepicker für Eventinfo Call 60 $.each($(".eventdatum"),function(){ 61 var dialoge = TMdialog(this); 62 var fahrplan = JSON.parse(decodeURIComponent($(this).attr("days"))); 63 var station = decodeURIComponent($(this).closest(".eventinfo_container").attr("hafen_start")); 64 var station_stop = decodeURIComponent($(this).closest(".eventinfo_container").attr("hafen_stop")); 65 var station_id = parseInt($(this).attr("location_start_id")); 66 var station_stop_id = parseInt($(this).attr("location_stop_id")); 67 var linie_id = parseInt($(this).attr("linie_id")); 68 var only_tagesfahrt = parseInt($(this).attr("only_tagesfahrt"))==1; 69 var datum_rueckfahrten = JSON.parse(decodeURIComponent($(this).attr("days_return"))); 70 var url_frontend = decodeURIComponent($(this).attr("url_frontend")); 71 var vObjj = $(this); 72 var vermittler_id = TMmodern(vObjj) ? $(vObjj).closest(".eventinfo_container").attr("reference") || "" : $(".eventinfo_container").first().attr("reference"); 73 var istRundfahrt = $(vObjj).attr("one_way")=="1"; 74 75 $(this).datepicker({ 76 minDate: new Date(fahrplan[0]), 77 maxDate: new Date(fahrplan[fahrplan.length - 1]), 78 79 beforeShowDay: function (date) { 80 var string = jQuery.datepicker.formatDate('yy-mm-dd', date); 81 return [fahrplan.indexOf(string) !== -1]; 82 }, 83 84 onSelect: function (dateText) { 85 var container = $(vObjj).closest(".eventinfo_container").find(".booking_window"); 86 container.addClass("hide"); 87 var date = $(vObjj).datepicker("getDate"); 88 var datumFormat = `${String(date.getDate()).padStart(2, '0')}.${String(date.getMonth() + 1).padStart(2, '0')}.${date.getFullYear()}`; 89 90 var gesuchtesDatum = jQuery.datepicker.formatDate('yy-mm-dd', date); 91 92 //Iframe leeren 93 TMscope(vObjj, "#booking_iframe").attr("src","about:blank"); 94 95 //Fahrzeiten für den gewählten Tag ermitteln 96 var data = {}; 97 data['action'] = 'travelmanager_eventinfo_hinfahrt'; 98 data['datum'] = gesuchtesDatum; 99 data['station_start_id'] = station_id; 100 data['station_stop_id'] = station_stop_id; 101 data['linie_id'] = linie_id; 102 data['lang'] = TMlanguage(vObjj); 103 data['hash']=$(vObjj).attr("keyhash"); 104 105 jQuery.blockUI({ message: dialoge["inhalt_laden"]+'...'}); 106 TMpost(vObjj, data, function(fahrten) { 107 jQuery.unblockUI(); 108 109 //Einfache Fahrt - direkte Darstellung des Buchungsfensters 110 if($(vObjj).attr("one_way")=="1"){ 111 var url = url_frontend+"&hinfahrt_datum="+datumFormat+"&return_url="+encodeURIComponent(window.location.href)+"&session_id="+(TMmodern(vObjj) ? $(vObjj).closest(".eventinfo_container") : $(".eventinfo_container").first()).attr("session_id"); 112 var ulAbfahrt = $("<ul/>");
113 $(ulAbfahrt).addClass("uhrzeit_ul"); 114 115 $.each(fahrten,function() { 116 var li = $("<li/>"); 117 118 if(station == station_stop){ 119 var abfahrt = "<span class='abfahrt'>"+$(this).attr("abfahrt")+" </span> <span class='station_stop_ankunft'>- "+$(this).attr("ankunft")+"</span> <span class='buchung_anzeige_schiff hide'>" + $(this).attr("schiff") +"</span>"; 120 } 121 else{ 122 var abfahrt = "<span class='abfahrt'>"+$(this).attr("abfahrt")+" "+station+"</span> <span class='station_stop_ankunft'>- "+$(this).attr("ankunft")+" "+station_stop+"</span>"; 123 } 124 125 var lhf_id = $(this).attr("lhf_id"); 126 if(!$(this).attr("available")){ 127 $(li).addClass("soldout"); 128 } 129 if ($.trim(abfahrt) == "") { 130 return; 131 } 132 if($(this).attr("available")){ 133 $(li).click(function(){ 134 url+="&lhf_id="+lhf_id; 135 if(vermittler_id!=""){ 136 url+="&vermittler_id="+vermittler_id; 137 } 138 139 url+="&lang="+TMlanguage(vObjj); 140 141 //Iframe leeren 142 $(container).find("iframe").attr("src","about:blank"); 143 $(container).removeClass("hide"); 144 $(container).find(".url").text(url); 145 if (!TMopenWidgetBooking(vObjj, container, url)) $(container).find("iframe").attr("src",url); 146 /* 147 $([document.documentElement, document.body]).animate({ 148 scrollTop:$(container).find("iframe").offset().top-100 149 }, 600); */ 150 TMscope(vObjj, ".tmaktiv").removeClass("tmaktiv"); 151 $(li).addClass("tmaktiv"); 152 }); 153 } 154 $(li).html(abfahrt); 155 $(ulAbfahrt).append(li); 156 }); 157 $(vObjj).closest(".eventinfo_container").find(".eventdatum_abfahrt").html("").append(ulAbfahrt); 158 159 //Wenn es einen Eintrag gibt, diesen direkt auswählen 160 if(fahrten.length==1) { 161 $(ulAbfahrt).find("li").click(); 162 } 163 } 164 //Hin- und Rückfahrt 165 else{ 166 $(container).addClass("hide"); 167 $(vObjj).closest(".eventinfo_container").find(".rueckfahrt_abfahrt").html(""); 168 $(vObjj).closest(".eventinfo_container").find(".rueckfahrt").addClass("hide"); 169 170 //Darstellung der Abfahrts-Uhrzeit 171 var ulAbfahrt = $("<ul/>"); 172 $(ulAbfahrt).addClass("uhrzeit_ul"); 173 $.each(fahrten,function(){ 174 var li = $("<li/>"); 175 var abfahrt = $(this).attr("abfahrt"); 176 var ankunft = $(this).attr("ankunft"); 177 if($.trim(abfahrt)==""){ 178 return; 179 } 180 if(!$(this).attr("available")){ 181 $(li).addClass("soldout"); 182 } 183 var lhf_id = $(this).attr("lhf_id"); 184 //$(li).html(abfahrt+" "+station+" - "+ankunft+" "+station_stop); 185 $(li).html(abfahrt+" "+arrowRight+" "+ankunft); 186 187 if($(this).attr("available")){ 188 $(li).click(function(){
189 $(ulAbfahrt).find("li").removeClass("tmaktiv"); 190 $(li).addClass("tmaktiv"); 191 $(li).attr("ankunft",ankunft); 192 193 $(vObjj).closest(".eventinfo_container").find(".rueckfahrt_abfahrt").html(""); 194 $(vObjj).closest(".eventinfo_container").find(".rueckfahrt").addClass("hide"); 195 196 //Kalender für Rückfahrt darstellen 197 var vObjRf = $(vObjj).closest(".eventinfo_container").find(".rueckfahrt .rueckfahrt_datepicker"); 198 $(vObjj).closest(".eventinfo_container").find(".rueckfahrt").removeClass("hide");; 199 $(vObjRf).datepicker("destroy"); 200 $(vObjRf).datepicker({ 201 minDate: new Date(date), 202 maxDate: new Date(datum_rueckfahrten[datum_rueckfahrten.length - 1]), 203 204 beforeShowDay: function (dateCurrent) { 205 var string = jQuery.datepicker.formatDate('yy-mm-dd', dateCurrent); 206 //Tagesfahrten - nur aktuelle Rückfahrdatum auswählbar 207 if(only_tagesfahrt && string != gesuchtesDatum){ 208 return false; 209 } 210 return [datum_rueckfahrten.indexOf(string) !== -1]; 211 }, 212 onSelect: function (dateText) { 213 214 TMscope(vObjj, ".rueckfahrt_abfahrt").html(""); 215 $(container).addClass("hide"); //Buchungsmaske ausblenden 216 TMscope(vObjj, "#booking_iframe").attr("src","about:blank"); //Iframe leeren 217 218 //Laden der Abfahrtszeiten für Rückfahrt 219 var date = $(vObjRf).datepicker("getDate"); 220 var datumFormatRF = `${String(date.getDate()).padStart(2, '0')}.${String(date.getMonth() + 1).padStart(2, '0')}.${date.getFullYear()}`; 221 222 //Bei Abfahrt an einem anderen Tag, keine Abfahrtszeit mit übergeben 223 if(datumFormatRF != datumFormat){ 224 abfahrt = ""; 225 } 226 227 var data = {}; 228 data['datum'] = datumFormatRF; 229 data['datum_hinfahrt'] = datumFormat; 230 data['action'] = 'travelmanager_eventinfo_rueckfahrt'; 231 data['ankunft'] = ankunft; 232 data['lang'] = TMlanguage(vObjj); 233 data['hinfahrt_linie_id'] = linie_id; 234 data['station_start_id'] = $(vObjj).attr("location_start_id"); 235 data['station_stop_id'] = $(vObjj).attr("location_stop_id"); 236 data['hash']=$(vObjj).attr("keyhash"); 237 238 jQuery.blockUI({ message: dialoge["inhalt_laden"]+'...'}); 239 TMpost(vObjj, data, function(response) { 240 jQuery.unblockUI(); 241 var containerRF = $(vObjj).closest(".eventinfo_container"); 242 $(containerRF).find(".rueckfahrt_abfahrt").html(""); 243 244 if($(response).length>0){ 245 246 //Hinweisbox 247 var text = station_stop + " "+arrowRight+" " + station; 248 var hinweisDiv=$("<div class='rueckfahrt_hinweis'>"+text+"</div>"); 249 $(containerRF).find(".rueckfahrt_abfahrt").append(hinweisDiv); 250 251 var ul=$("<ul/>"); 252 $(ul).addClass("uhrzeit_ul"); 253 $.each(response,function(){ 254 //var abfahrt="<span class='abfahrt'>"+this["abfahrt"]+"</span> <span class='station_stop_ankunft'>"+station_stop+" - "+this["ankunft"]+" "+station+"</span>"; 255 256 var text = "<span class='abfahrt'>"+this["abfahrt"]+"</span> "+arrowRight+" "+this["ankunft"]+"</span>"; 257 258 var verbindungRF=this["verbindung"]; 259 var li=$("<li/>"); 260 $(li).html(text); 261 262 if(!this["available"]){ 263 $(li).addClass("soldout"); 264 } 265 else{ 266 $(li).click(function(){ 267 268 TMscope(vObjj, ".button_einfache_fahrt").removeClass("tmaktiv"); 269 $(ul).find("li").removeClass("tmaktiv"); 270 $(li).addClass("tmaktiv"); 271 272 var url = url_frontend+"&hinfahrt_datum="+datumFormat+"&rueckfahrt_datum="+datumFormatRF+"&hide_nur_hinfahrt=1&rueckfahrt="+verbindungRF+"&lhf_id="+lhf_id+"&return_url="+encodeURIComponent(window.location.href)+"&session_id="+(TMmodern(vObjj) ? $(vObjj).closest(".eventinfo_container") : $(".eventinfo_container").first()).attr("session_id"); 273 274 if(vermittler_id!=""){ 275 url+="&vermittler_id="+vermittler_id; 276 } 277 278 url+="&lang="+TMlanguage(vObjj); 279 280 $(container).removeClass("hide"); 281 $(container).find(".url").text(url); 282 if (!TMopenWidgetBooking(vObjj, container, url)) $(container).find("iframe").attr("src",url); 283 /* 284 $([document.documentElement, document.body]).animate({ 285 scrollTop:$(container).find("iframe").offset().top-100 286 }, 600); */ 287 }); 288 } 289 290 $(ul).append(li); 291 }); 292 293 var einfache_fahrt = TMscope(vObjj, ".button_container_single_ride"); 294 var li = $("<li/>").append(einfache_fahrt.clone(true,true).removeClass("hide")); 295 $(ul).append(li); 296 297 $(containerRF).find(".rueckfahrt_abfahrt").append(ul); 298 } 299 else{ 300 $(containerRF).find(".rueckfahrt_abfahrt").append($("<div class='remark_single_ride rueckfahrt_hinweis'>"+dialoge["keine_rueckfahrt"]+"</div>")); 301 302 303 //Einfache Fahrt hinzufügen 304 var einfache_fahrt = TMscope(vObjj, ".button_container_single_ride").clone(true,true).removeClass("hide"); 305 var ul = $("<ul/>"); 306 $(ul).addClass("uhrzeit_ul"); 307 var li = $("<li/>").append(einfache_fahrt); 308 $(ul).append(li); 309 $(containerRF).find(".rueckfahrt_abfahrt").append(ul); 310 } 311 312 } ); 313 314 315 } 316 }); 317 318 //Erstes Datum klicken damit die Uhrzeiten geladen werden 319 try { 320 $(vObjRf).find("a.ui-state-default.ui-state-active").first().closest("td").trigger("click"); 321 } 322 catch (e) {} 323 324 //Button für einfache Fahrt 325 var url = url_frontend+"&hinfahrt_datum="+datumFormat+"&lhf_id="+lhf_id+"&return_url="+encodeURIComponent(window.location.href)+"&session_id="+(TMmodern(vObjj) ? $(vObjj).closest(".eventinfo_container") : $(".eventinfo_container").first()).attr("session_id")+"&einfache_fahrt=true"; 326 if(vermittler_id!=""){ 327 url+="&vermittler_id="+vermittler_id; 328 } 329 url+="&lang="+TMlanguage(vObjj); 330 var button = $("<input type='button' class='button button_einfache_fahrt' value='"+dialoge["einfache_fahrt"]+"'/>"); 331 $(button).on("click",function(){ 332 $(container).find("iframe").attr("src","about:blank"); 333 $(container).removeClass("hide"); 334 $(container).find(".url").text(url); 335 if (!TMopenWidgetBooking(vObjj, container, url)) $(container).find("iframe").attr("src",url); 336 TMscope(vObjj, ".rueckfahrt_abfahrt").find("li").removeClass("tmaktiv"); 337 $(this).closest("li").addClass("tmaktiv"); 338 $(this).addClass("tmaktiv"); 339 }); 340 var divContainer=$("<div class='button_container_single_ride hide'/>").append(button); 341 $(vObjRf).append(divContainer); 342 343 }); 344 } 345
346 $(ulAbfahrt).append(li); 347 }); 348 349 //Wenn es einen Eintrag gibt, diesen direkt auswählen 350 if(fahrten.length==1) { 351 $(ulAbfahrt).find("li").click(); 352 } 353 354 if(istRundfahrt){ 355 var text = dialoge["klick_uhrzeit"]; 356 } 357 else{ 358 var text = station + " "+arrowRight+" " + station_stop; 359 } 360 361 var hinweisDiv=$("<div class='abfahrt_hinweis'>"+text+"</div>"); 362 $(vObjj).closest(".eventinfo_container").find(".eventdatum_abfahrt").html("").append(hinweisDiv); 363 $(vObjj).closest(".eventinfo_container").find(".eventdatum_abfahrt").append(ulAbfahrt); 364 } 365 } ); 366 } 367 }); 368 369 //Initiales Datum wurde gewählt - im Datepicker setzen und direkt ausführen 370 if(fahrplan.length==1){ 371 var initial_date = fahrplan[0]; 372 } 373 else{ 374 var initial_date = $(vObjj).attr("initial_date"); 375 } 376 if(initial_date!=""){ 377 var isoDate = /^(\d{4})-(\d{2})-(\d{2})$/.exec(initial_date); 378 var selectedDate = isoDate ? new Date(Number(isoDate[1]), Number(isoDate[2])-1, Number(isoDate[3])) : initial_date; 379 $(vObjj).datepicker('setDate',selectedDate); 380 $(vObjj).datepicker('option', 'onSelect').call($(vObjj), initial_date); 381 } 382 383 }); 384 385 386 window.addEventListener("message", (event) => { 387 console.log("Nachricht empfangen:", event.data); 388 389 if (event.data.type === "resize") { 390 var height = parseInt(event.data.height); // Zusätzlicher Puffer 391 $("#booking_iframe").css("height", height + "px"); 392 } 393 }); 394 395 396}); 397 398function triggerDatepickerSelect(selector, date) { 399 var datepicker = jQuery(selector); 400 401 if (datepicker.length === 0) { 402 console.warn("Datepicker-Element nicht gefunden:", selector); 403 return; 404 } 405 406 var datepickerInstance = datepicker.data("datepicker"); 407 408 if (datepickerInstance && datepickerInstance.settings.onSelect) { 409 datepickerInstance.settings.onSelect.call(datepicker, date, datepicker.datepicker("widget")); 410 } else if (datepicker.datepicker("option", "onSelect")) { 411 datepicker.datepicker("option", "onSelect").call(datepicker, date, datepicker); 412 } else { 413 console.warn("Kein onSelect-Handler für den Datepicker definiert:", selector); 414 } 415}
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.