Fehler bei der Verarbeitung der Vorlage.
Error while invoking the "replace-content" JSP custom tag; see cause exception ---- FTL stack trace ("~" means nesting-related): - Failed at: @ait_contentreplacer["replace-content"] [in template "20116#20152#34036" at line 11, column 1] ----
1<#assign
2 ait_contentreplacer = taglibLiferayHash["/META-INF/ait-contentreplacer.tld"]
3
4 journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
5 assetCategoryLocalServiceUtil = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")
6 languageUtil = serviceLocator.findService("com.liferay.portal.kernel.language.LanguageUtil")
7 webKeys = staticUtil["com.liferay.portal.kernel.util.WebKeys"]
8 LayoutLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.LayoutLocalService")
9>
10
11<@ait_contentreplacer["replace-content"]>
12
13 <#-- Configuration -->
14 <#assign largeStructureIds = [
15 "BKS-2-SPALTIGE-INDEXBOX",
16 "BKS-2-SPALTIGE-PROMOTION-BOX"
17 ]>
18
19 <#assign forcedBoxTemplateMapping = {
20 "BKS-PRODUKT-DEPOT" : "BKS-PRODUKT-DEPOT-BOX",
21 "BKS-PRODUKT-KARTE" : "BKS-PRODUKT-KARTE-BOX",
22 "BKS-PRODUKT-KONTO-FIRMENKUNDEN" : "BKS-PRODUKT-KONTO-FIRMENKUNDEN-BOX",
23 "BKS-PRODUKT-KONTO-PRIVATKUNDEN" : "BKS-PRODUKT-KONTO-PRIVATKUNDEN-BOX",
24
25 "BKS-HR-KONTO-PRIVAT" : "BKS-HR-KONTO-PRIVAT-BOX",
26 "BKS-HR-MASTERCARD" : "BKS-HR-MASTERCARD-BOX",
27
28 "BKS-SL-ACTIVA MAESTRO" : "BKS-SL-ACTIVA-MAESTRO-BOX",
29 "BKS-SL-ACTIVA MASTERCARD" : "BKS-SL-ACTIVA-MASTERCARD-BOX",
30 "BKS-SL-KONTO PRIVAT" : "BKS-SL-KONTO-PRIVAT-BOX",
31 "BKS-SL-PAKETI" : "BKS-SL-PAKETI-BOX"
32 }>
33
34 <#assign
35
36 labelNoFilterResult = "Leider konnte kein passendes Produkt gefunden werden.<br/>Bitte passen Sie Ihre Auswahl an."
37
38 productDetailYes = "Ja"
39 productDetailNo = "Nein"
40
41 comparisonButtonPopoverText = "Bitte wählen Sie weitere Produkte.<br/>Ab zwei Produkten können Sie den Vergleich starten."
42
43 <#-- Labels Depot -->
44 infoTextServicepreisDepot = "Die Berechnung des Servicepreises erfolgt quartalsweise im Nachhinein. Es wird taggenau abgerechnet. Zuzüglich USt."
45 infoTextDepotpreis = "Die Berechnung des Depotpreises erfolgt quartalsweise im Nachhinein. Es wird taggenau abgerechnet. Zuzüglich USt."
46 infoTextInvestmentfondsKauf = "Bei Fonds der 3 Banken Generali Investment GesmbH wird kein Sockelbetrag verrechnet."
47
48 spacerTextTransactions = "<strong>Transaktionspreise vom Volumen pro Transaktion</strong> <br/>Bei Internet-Transaktionen reduziert sich der Fixpreis um 10,00 Euro je Transaktion, ausgenommen Online Depot"
49 spacerTextCommunication = "<strong>Zustellung von anfallenden Belegen und Mitteilungen</strong>"
50
51 disclaimerText = "Preise für Zusatzleistungen können je Depotmodell variieren. Details entnehmen Sie bitte dem Preisaushang, der in allen BKS Bank-Filialen aufliegt."
52
53 labelServicepreisDepot = "Servicepreis pro Monat pro Depot"
54 labelDepotpreis = "Depotpreis pro Jahr"
55 labelAktien = "Aktien, Optionsscheine, Partizipationsscheine, Hybride, Call/Put, freiwillige Kapitalmaßnahmen"
56 labelAnleihen = "Anleihen"
57 labelInvestmentfondsKauf = "Investmentfonds Kauf (abhängig von der Fondsart)"
58 labelInvestmentfondsVerkauf = "Investmentfonds Verkauf"
59 labelEBox = "Kommunikationszentrum des Kundenportals (elektronisches Postfach)"
60 labelPostversand = "Postversand"
61
62 <#-- Labels Karte -->
63 labelVersicherungsschutz = "Versicherungsschutz"
64 labelReisestornoversicherung = "Reisestornoversicherung"
65 labelBKSOnlineAbrufbar = "Umsätze in MyNet abrufbar"
66 labelZusatzleistung = "Zusatzleistungen"
67 labelVerfuegerrahmen = "Monatlicher Verfügungsrahmen"
68 labelKartengebuehr = "Kartengebühr"
69 labelZusatzkarte = "Zusatz-/Partnerkarte pro Jahr"
70
71 <#-- Labels Konto Firmekunden -->
72 labelGrundpreis = "Grundpreis pro Monat"
73
74 spacerTextTransaktionen = "<strong>Transaktionen</strong>"
75 labelELBABKS = "ELBA / BizzNet / BizzNet Plus"
76 labelElektronischeBuchungen = "Elektronische Buchungen"
77 labelSelbstbedienung = "Selbstbedienung"
78 labelServiceAmSchalter = "Service am Schalter"
79
80 spacerTextKarten = "<strong>Karten</strong>"
81 spacerInfoKarten = "Ermäßigung immer nur für eine Karte"
82 labelMaestroKarte = "Debitkarte pro Monat"
83 labelVISACard = "VISA Business Classic Card pro Monat"
84 labelBKSMastercardBusiness = "BKS Mastercard Business pro Monat"
85 infoTextBKSMastercardBusiness = "BKS Mastercard Business für Einzelunternehmer (nicht im Firmenbuch eingetragen)"
86
87 spacerTextAuszug = "<strong>Auszug</strong>"
88 labelAuszugElektronisch = "PDF-Auszug"
89 labelAuszugPapier = "Auszug Papier"
90
91 spacerTextBizzNet = "<strong>BizzNet</strong>"
92 labelBizzNet = "pro Monat"
93 infoTextBizzNet = "Internetbanking mit den wichtigsten Funktionen für Firmenkunden."
94
95 spacerTextBizzNetPlus = "<strong>BizzNet Plus</strong>"
96 labelBizzNetPlus = "pro Monat"
97 infoTextBizzNetPlus = "Alle Funktionen des BizzNet inklusive der Funktion Sammler/Datenträgerimport."
98 labelBizzNetPlusMitLastschrift = "Lastschriften-Modul pro Monat zusätzlich"
99 infoTextBizzNetPlusMitLastschrift = "Inklusive der Funktionen Sammler/Datenträger-Import und Export"
100
101 spacerTextELBA = "<strong>ELBA</strong>"
102 labelELBA = "Nutzungsentgelt pro Monat"
103 infoTextELBA = "Das Electronic Banking ermöglicht Ihnen einen direkten Zugriff auf Ihre Konten bei verschiedenen Geldinstituten."
104
105 <#-- Labels Konto Privatkunden -->
106 labelMyNetInternetbanking = "MyNet (Internetbanking), BKS App"
107 infoTextMyNetInternetbanking = "
108 <p>Leistungspaket MyNet und BKS Bank App:</p>
109 <ul>
110 <li>Überblick über alle von Ihnen bei der BKS Bank geführten Konten</li>
111 <li>Überweisungen und Wertpapierorder durchführen und Daueraufträge anlegen</li>
112 <li>Einfache und sichere Kommunikation mit Ihrem Kundenbetreuer</li>
113 <li>Individuelle Anpassungsmöglichkeit des Kontorahmens</li>
114 <li>Kartenverwaltung: Sperren der Debit Mastercard, Aufgabe eines individuellen Limits für POS-Transaktionen oder Bargeldbezug</li>
115 </ul>"
116
117 labelDebitMastercard = "Debitkarte"
118
119 labelApplePayBluecodeGarminPayBKSWallet = "Apple Pay, Garmin Pay, Bezahlen mit Android Smartphone, Bluecode, Swatch Pay"
120
121 labelKontoversicherung = "Kontoversicherung"
122 infoTextKontoversicherung = "
123 <ul>
124 <li>Finanzielle Absicherung im Todesfall</li>
125 <li>Bis zu einem Sollsaldo von 7.000,-</li>
126 <li>Versichert ist der Kontoinhaber bis zum vollendeten 70. Lebensjahr</li>
127 </ul>"
128
129 labelStandardUndInternetbankingBuchung = "Standard- und Internetbanking-Buchung"
130 infoTextStandardUndInternetbankingBuchung = "Gutschriften, Lastschriften, Daueraufträge, Bargeldbehebungen an Automaten.
131 Überträge und Überweisungen im MyNet"
132
133 labelSelbstbedienungsBuchung = "Selbstbedienungs-Buchung"
134 infoTextSelbstbedienungsBuchung = "Bargeldeinzahlungen und Überweisungen an SB-Geräten"
135
136 labelSchalterServiceBuchung = "Schalter-Service-Buchung"
137 infoTextSchalterServiceBuchung = "Bargeldeinzahlungen und -behebungen an der Kassa, Scheckgutschriften und -lastschriften, beleghafte Überweisungen,
138 Überweisungen am Schalter"
139
140 labelPaketpreis = "Preis Kontomodell pro Monat (inkl. Kontoführung)"
141 labelAirbag = "BKS Airbag pro Monat (optional)"
142 infoTextAirbag = "
143 <p><strong>BKS Airbag:</strong> 24h-IT-Hotline bei Problemen und Fragen</p>
144 <ul>
145 <li>Unterstützung im Umgang mit Hard- und Software</li>
146 <li>Installation, Deinstallation und Durchführung von Updates</li>
147 <li>Information zu neuer Hard- und Software</li>
148 <li>Beratung bei Betrug durch Phishing und Malware</li>
149 <li>Akut- und Nachsorge bei einem Cyberfall</li>
150 <li>Optimierung und Reduktion des Strom- bzw. Energieverbrauchs</li>
151 </ul>"
152
153 labelBKSMastercard = "BKS Mastercard pro Monat (optional)"
154
155 labelZweitkontoNaturZukunftKonto = "Zweitkonto Natur & Zukunft-Konto oder Du & Wir-Konto (optional)"
156 infoTextZweitkontoNaturZukunftKonto = "Leistungsumfang wie Erstkonto - Einbindung in das MyNet des Erstkontos"
157
158 labelZweitkontoAllInKonto = "Zweitkonto All & In-Konto (optional)"
159 infoTextZweitkontoAllInKonto = "Leistungsumfang wie Erstkonto - Einbindung in das MyNet des Erstkontos"
160
161 labelKontoabschluss = "Kontoabschluss erfolgt"
162 />
163
164 <#-- Flattens a tree of categories and only returns leaf nodes - duplicates are not handled -->
165 <#function flatten list>
166 <#local flatList = []>
167 <#list list as item>
168 <#local children = assetCategoryLocalServiceUtil.getChildCategories(item.getCategoryId())>
169 <#if children?has_content>
170 <#--recursive flatten all children and add result to flatList -->
171 <#local flatList = flatList + flatten(children)>
172 <#else>
173 <#-- add category to flatList -->
174 <#local flatList = flatList + [item]>
175 </#if>
176 </#list>
177 <#return flatList>
178 </#function>
179
180 <#-- Returns a list of unique categories (matched by categoryId)-->
181 <#function unique list>
182 <#local uniqueList = []>
183 <#list list as item>
184 <#local addItem = true>
185 <#list uniqueList as uniqueItem>
186 <#if uniqueItem.getCategoryId() == item.getCategoryId()>
187 <#local addItem = false>
188 <#break>
189 </#if>
190 </#list>
191 <#if addItem>
192 <#local uniqueList = uniqueList + [item]>
193 </#if>
194 </#list>
195 <#return uniqueList>
196 </#function>
197
198 <#function mapCategories categories>
199 <#local list = []>
200 <#list categories as category>
201 <#local list = list + [category.getCategoryId()]>
202 </#list>
203 <#return list?join(",")>
204 </#function>
205
206 <#function columnClass ddmStructureKey>
207 <#if largeStructureIds?seq_contains(ddmStructureKey)>
208 <#return "col-sm-12 col-lg-8">
209 <#else>
210 <#return "col-sm-6 col-lg-4">
211 </#if>
212 </#function>
213
214 <#function getTemplateKey article>
215 <#local structureKey = article.getDDMStructureKey()>
216 <#if forcedBoxTemplateMapping[structureKey]??>
217 <#return forcedBoxTemplateMapping[structureKey]>
218 <#else>
219 <#return article.getDDMTemplateKey()>
220 </#if>
221 </#function>
222
223 <#-- Rendering -->
224 <#if !entries?has_content>
225 <#if !themeDisplay.isSignedIn()>
226 ${renderRequest.setAttribute("PORTLET_CONFIGURATOR_VISIBILITY", true)}
227 </#if>
228
229 <div class="alert alert-info">
230 <@liferay_ui["message"] key="no-entries-were-found" />
231 </div>
232 <#else>
233 <div class="row row-flex-equal card-list-container filter-result-container">
234 <div class="col-sm-12 filter-no-result-item filter-result-hide filter-result-hidden">
235 <p>${labelNoFilterResult}</p>
236 </div>
237 <#list entries as entry>
238 <#assign
239 assetRenderer = entry.getAssetRenderer()
240
241 entryTitle = htmlUtil.escape(assetRenderer.getTitle(locale))
242
243 entryClassName = assetRenderer.getClassName()
244
245 article = entry.getAssetRenderer().getArticle()
246
247 flatCategories = unique(flatten(entry.getCategories()))
248
249 >
250
251 <#if stringUtil.equals(entryClassName, "com.liferay.journal.model.JournalArticle")>
252
253 <div class="${columnClass(article.getDDMStructureKey())} filter-result-item" data-filter-categories="${mapCategories(flatCategories)}" data-structure-key="${article.getDDMStructureKey()}" data-article-id="${article.getId()}">
254 <div class="lfr-portal-asset-edit-tooltip">
255 <@getEditIcon />
256 </div>
257 <#assign articleDisplay = journalArticleLocalService.getArticleDisplay(
258 article.getGroupId(),
259 article.getArticleId(),
260 article.getVersion(),
261 getTemplateKey(article),
262 "view",
263 languageUtil.getLanguageId(renderRequest),
264 renderRequest.getAttribute(webKeys.THEME_DISPLAY))>
265
266 ${articleDisplay.getContent()}
267 </div>
268 <#else>
269 <#if themeDisplay.isSignedIn()>
270 <div class="alert alert-warning">
271 <@liferay_ui["message"] key="asset-type" /> <@liferay_ui["message"] key="not-supported" />
272 </div>
273 </#if>
274 </#if>
275 </#list>
276 </div>
277 </#if>
278
279 <#macro getEditIcon>
280 <#if assetRenderer.hasEditPermission(themeDisplay.getPermissionChecker())>
281 <#assign editPortletURL = assetRenderer.getURLEdit(renderRequest, renderResponse, windowStateFactory.getWindowState("NORMAL"), themeDisplay.getURLCurrent())!"" />
282
283 <#if validator.isNotNull(editPortletURL)>
284 <#assign title = languageUtil.format(locale, "edit-x", entryTitle, false) />
285
286 <@liferay_ui["icon"]
287 cssClass="icon-monospaced visible-interaction"
288 icon="pencil"
289 markupView="lexicon"
290 message=title
291 url=editPortletURL.toString()
292 />
293 </#if>
294 </#if>
295 </#macro>
296
297 <#if entries?has_content>
298 <div id="siteBottomOverlayContainer" class="site-bottom-overlay-container">
299 <div id="siteBottomOverlayBtnContainer" class="site-bottom-overlay-btn-container">
300 <button id="siteBottomOverlayBtn"
301 class="btn btn-primary site-bottom-overlay-btn ${randomNamespace}-popover-overlay-btn"
302 data-bs-container="#siteBottomOverlayBtnContainer"
303 data-bs-toggle="popover"
304 data-bs-placement="top"
305 data-bs-content="${comparisonButtonPopoverText}"
306 data-bs-trigger="manual"
307 data-bs-html="true"
308 data-bs-template='<div class="popover" role="tooltip"><div class="arrow popover-arrow"></div><button type="button" class="close" onclick="$('.${randomNamespace}-popover-overlay-btn').popover('hide'); " aria-label="<@liferay.language key='close'/>"><span aria-hidden="true">×</span></button><h3 class="popover-title"></h3><div class="popover-body"></div></div>'
309 disabled>Vergleichen</button>
310 <span class="hide-accessible">
311 ${comparisonButtonPopoverText}
312 </span>
313 </div>
314 </div>
315
316 <@renderProductComparisonModalIfNecessary structureKey="BKS-PRODUKT-KARTE" entries=entries/>
317 <@renderProductComparisonModalIfNecessary structureKey="BKS-PRODUKT-KONTO-PRIVATKUNDEN" entries=entries/>
318 <@renderProductComparisonModalIfNecessary structureKey="BKS-PRODUKT-DEPOT" entries=entries/>
319 <@renderProductComparisonModalIfNecessary structureKey="BKS-PRODUKT-KONTO-FIRMENKUNDEN" entries=entries/>
320
321
322 <!-- **************************** COMPARISON SCRIPT ********** -->
323
324
325 <script type="text/javascript">
326
327 AUI().ready("",function(A) {
328
329 Liferay.Loader.require([
330 "bks-main-theme-js-modules@2.0.0/bootstrap/popover"
331 ], function(Popover) {
332
333 }, function(error) {
334 console.log(error);
335 });
336
337 Liferay.Loader.require([
338 "bks-main-theme-js-modules@2.0.0/jquery/jquery-3.6.0.min",
339 "bks-main-theme-js-modules@2.0.0/bootstrap/popover",
340 ], function($, Popover, Modal) {
341 /* find all checkboxes for product comparison and attach JSON object wird articleId and structureKey as 'data-product-data' attribute */
342 var a = $('.filter-result-container').find('.filter-result-item').each( function(index,obj) {
343 // console.log("_______ " + index + " - objs",$(obj).data('article-id'));
344 var articleId = $(obj).data('article-id');
345 var structureKey = $(obj).data('structure-key');
346 // console.log('-------------------- XXXXXXXXXX:', structureKey,articleId);
347 $(obj).find('input[type=checkbox]').data('product-data',{
348 articleId: articleId,
349 structureKey: structureKey
350 });
351 $(obj).find('input[type=checkbox]').each(function(v,w) {
352 // console.log("********** ", v,w, $(w).data('product-data'));
353 });
354 });
355
356
357 var popoverBtn = document.querySelector(".${randomNamespace}-popover-overlay-btn")
358 var overlayBtnPopover = Popover.getOrCreateInstance(popoverBtn);
359
360 var closeBtn = document.createElement('button');
361 closeBtn.className = 'close';
362 closeBtn.type = 'button';
363 closeBtn.setAttribute('type', 'button');
364 closeBtn.setAttribute('aria-label', '${languageUtil.get(locale, "close")}');
365 closeBtn.innerHTML = "×";
366
367 closeBtn.addEventListener('click', function() {
368 overlayBtnPopover.hide();
369 });
370
371 popoverBtn.addEventListener('shown.bs.popover', function() {
372 document.querySelector('#siteBottomOverlayBtnContainer > .popover').insertBefore(closeBtn, document.querySelector('#siteBottomOverlayBtnContainer > .popover').firstChild);
373 });
374
375 a.change(function(ev) {
376 // console.log("_______ changed",ev);
377 var filterResultItemEl = ev.currentTarget;
378 var checkbox = $(filterResultItemEl).find('input[type=checkbox]');
379 var checkboxChecked = $(checkbox).prop('checked');
380 var productData = checkbox.data('product-data');
381 // console.log(">>>>>>> product-data", productData);
382
383 if (checkboxChecked) {
384 SelectionManager.select(productData);
385 }else {
386 SelectionManager.unselect(productData);
387 }
388
389 var selectionSize = SelectionManager.selectionSize();
390 // console.log("_____________selectionSize " + selectionSize);
391 if ( selectionSize == 0 ) {
392 $('#siteBottomOverlayContainer').addClass('container-hidden').removeClass('container-visible');
393 $('#siteBottomOverlayContainer').removeClass('compareHidden').removeClass('popoverHidden');
394 // $(".${randomNamespace}-popover-overlay-btn").popover('hide');
395 overlayBtnPopover.hide();
396 setTimeout(function() {
397 $('#siteBottomOverlayBtnContainer').hide();
398 $('#siteBottomOverlayBtn').prop("disabled", false);
399 },150);
400 } else {
401 $('#siteBottomOverlayContainer').addClass('container-visible').removeClass('container-hidden');
402
403 $('#siteBottomOverlayContainerScroll').addClass('container-hidden').removeClass('container-visible');
404 $('#siteBottomOverlayBtnScrollContainer').hide();
405 $('#siteBottomOverlayContainer').removeClass('compareHidden').removeClass('popoverHidden');
406
407 if (selectionSize == 1 ) {
408 $('#siteBottomOverlayBtn').prop("disabled", true);
409 $('#siteBottomOverlayBtn').html("Vergleichen");
410 $('#siteBottomOverlayBtnContainer').show();
411 overlayBtnPopover.show();
412 console.warn("________________selection size = 1");
413 } else {
414 $('#siteBottomOverlayBtn').prop("disabled", false);
415 $('#siteBottomOverlayBtn').html("Vergleichen (" + selectionSize + ")");
416 $('#siteBottomOverlayBtnContainer').show();
417 overlayBtnPopover.hide();
418 }
419 }
420
421 // console.log("_____________ selection", SelectionManager.getSelection());
422
423 // iterate all checkboxes, disable the ones with other structures
424 var a = $('.filter-result-container').find('.filter-result-item').find('input[type=checkbox]').each( function(idx,chkbox) {
425 var productDataThis = $(chkbox).data('product-data');
426 var structureDifferent = productData.structureKey !== productDataThis.structureKey;
427
428 if ( productDataThis.articleId !== productData.articleId ) {
429 // console.log(" -->> product-data structureDifferent=" + structureDifferent, productDataThis);
430 if ( checkboxChecked ) {
431 if (structureDifferent) {
432 $(chkbox).prop('checked', false );
433 $(chkbox).prop("disabled", true );
434 } else {
435 $(chkbox).prop("disabled", false );
436 }
437 } else {
438 $(chkbox).prop("disabled", false );
439 }
440 }
441 });
442
443 /*$('#textbox1').val($(this).is(':checked'));*/
444 });
445 }, function(error) {
446 console.error(error);
447 })
448
449
450 /* selectionManager is a helper object that stores the selection of the user */
451 var SelectionManager = {
452
453 structureKey: '',
454 selection: {},
455
456 select: function(productData) {
457 if ( this.selectionSize() === 0 ) {
458 this.structureKey = productData.structureKey;
459 this.selection[productData.articleId] = productData;
460 } else if ( productData.structureKey == this.structureKey ) {
461 this.selection[productData.articleId] = productData;
462 }
463 },
464
465 unselect: function(productData) {
466 delete this.selection[productData.articleId];
467 if ( this.selectionSize() === 0 ) {
468 this.structureKey = '';
469 }
470 },
471
472 getSelection: function() {
473 return this.selection;
474 },
475
476 getStructureKey: function() {
477 return this.structureKey;
478 },
479
480 selectionSize: function() {
481 var count = 0;
482 for (var key in this.selection) {
483 if (this.selection.hasOwnProperty(key))
484 count++;
485 }
486 return count;
487 }
488
489 };
490
491 var jqueryPromise = new Promise((resolve, reject) => {
492 Liferay.Loader.require([
493 "bks-main-theme-js-modules@2.0.0/jquery/jquery-3.6.0.min"
494 ], function($) {
495 resolve($)
496 }, function(error) {
497 reject(error)
498 })
499 });
500
501
502
503 /* attach a changeHandler function to each checkbox */
504
505
506 function _resize() {
507 jqueryPromise.then(function($) {
508 var wW = $(window).width();
509
510 if (wW >= 768) {
511 var tableElement = $('#productComparisonDialog .table-product.tablesaw');
512 var tableWidth = tableElement.get(0).clientWidth;
513 var colsFixed = $(tableElement).find('thead tr th.col-fixed');
514 var colsSwipe = $(tableElement).find('thead tr th.col-swipe');
515
516 var colsFixedWidth = 0;
517 colsFixed.each(function(index) {
518 colsFixedWidth += colsFixed[index].clientWidth;
519 });
520
521 $(tableElement).find(".btn-right").css("left", "" + (tableWidth - colsFixedWidth) + "px");
522
523 var lastThIsHidden = colsSwipe.last().hasClass("tablesaw-swipe-cellhidden");
524 var firstThIsHidden = colsSwipe.first().hasClass("tablesaw-swipe-cellhidden");
525
526 $(tableElement).find(".btn-right").prop("disabled", !lastThIsHidden);
527 $(tableElement).find(".btn-left").prop("disabled", !firstThIsHidden);
528 }
529 })
530 }
531
532 function startProductCompare() {
533 jqueryPromise.then(function($) {
534
535 // Add Content to Modal
536 $('#productComparisonDialog').html('');
537 var templateId = '#productComparisonDialogTemplate-' + SelectionManager.getStructureKey();
538 // console.log("templateId:", templateId);
539 var content = $(templateId).html();
540 var productDataArray = new Array();
541 $('.filter-result-container').find('.filter-result-item').find('input[type=checkbox]').each( function(idx,chkbox) {
542 var productData = $(chkbox).data('product-data');
543 // console.log("_________________________ PUSHING __________________",productData);
544 productDataArray.push( productData );
545 } );
546 // console.log("________ productDataArray:", productDataArray);
547
548 $('#productComparisonDialog').html(content);
549
550 var selection = SelectionManager.getSelection();
551 for ( var i=0;i<productDataArray.length;i++ ) {
552 if ( !selection[ productDataArray[i].articleId ] ) {
553 // console.log(" ----> removing article #" + productDataArray[i].articleId);
554 $('#productComparisonDialog').find('*[data-article-id="' + productDataArray[i].articleId + '"]' ).each(function( idx,node ) {
555 // console.log(" >>> found:", node);
556 $(node).remove();
557 });
558 }
559 }
560
561 // register clickhandlers -> similar to CTA-Buttons, but using a data-tag
562 var buttons = $('#productComparisonDialog').find('[data-application]');
563 if (buttons.length > 0) {
564 buttons.on("click", function(e) {
565 e.preventDefault();
566
567 var legacyApplication = $(this).attr('data-application');
568 if (!legacyApplication) {
569 console.error('Tried to require an Angular app but failed because no data-application attribute was found. Debug info below.');
570 console.error('object trying to get the data-application from: ', $(this));
571 return;
572 }
573
574 legacyApplication = legacyApplication.replace('bks-redesign-', ''); // support for old values with bks-redesign- prefix
575 var myApp = legacyApplication.split(/\s+/);
576
577 Liferay.Loader.require(
578 ['bks-apps@0.0.0/bks-' + myApp[0] + '/runtime','bks-apps@0.0.0/bks-' + myApp[0] + '/polyfills','bks-apps@0.0.0/bks-' + myApp[0] + '/main'],
579 function(appMain) {
580 window.bksApps[myApp[0]].start().then(function(app) {
581 appRef = app;
582 setTimeout( app.show, 20); // without this the initial animation will not play
583 }).catch( function(err) { console.error(err) });
584 }, function(error) {
585 console.error(error)
586 }
587 );
588 });
589 }
590
591 // Show Modal
592 // $('#productComparisonDialog').modal('show');
593 Liferay.Loader.require([
594 "bks-main-theme-js-modules@2.0.0/bootstrap/modal"
595 ], function(Modal) {
596 var modal = new Modal(document.getElementById('productComparisonDialog'));
597 modal.show();
598 }, function(error) {
599 console.error(error);
600 })
601 })
602 }
603
604
605 jqueryPromise.then(function($) {
606
607 // Init Modal Content after it is shown
608 document.getElementById('productComparisonDialog').addEventListener('show.bs.modal', function (event) {
609 // can not use shown.bs.modal event because it is fired too late
610 // Waiting until Fade In Animation is finished
611 // Then init Tablesaw to get correct Layout
612
613 setTimeout(function(){
614 // Init Popovers
615 Liferay.Loader.require([
616 "bks-main-theme-js-modules@2.0.0/bootstrap/popover"
617 ], function(Popover) {
618 var popoverTriggerEl = document.querySelector(".${randomNamespace}-popover");
619 if(popoverTriggerEl) {
620 var popover = new Popover(popoverTriggerEl, {
621 trigger: 'hover'
622 });
623 }
624 }, function(error) {
625 console.log(error);
626 });
627
628 Liferay.Loader.require([
629 "bks-main-theme-js-modules@2.0.0/tablesaw/tablesaw.jquery"
630 ], function() {
631 var tableElement = $('#productComparisonDialog .table-product.tablesaw');
632
633 Tablesaw._init( tableElement.get() );
634
635 $(tableElement).find('.btn-left').click( function(e) {
636 $( tableElement ).tablesaw().trigger("tablesawprev.swipetoggle");
637 e.preventDefault();
638 });
639
640 $(tableElement).find('.btn-right').click( function(e) {
641 $( tableElement ).tablesaw().trigger("tablesawnext.swipetoggle");
642 e.preventDefault();
643 });
644
645 $( tableElement ).tablesaw().on("tablesawcolumns", function(e) {
646 _resize();
647 });
648
649 _resize();
650
651 // Show Buttons after Tablesaw is initialized
652 $( tableElement ).find(".btn-container").css("display", "block");
653 }, function(error) {
654 console.log(error);
655 });
656
657 Liferay.Loader.require([
658 "bks-main-theme-js-modules@2.0.0/bootstrap/popover"
659 ], function(Popover) {
660 var tablePopoverTrigger = document.querySelectorAll('#productComparisonDialog [data-bs-toggle="popover"]');
661 tablePopoverTrigger.forEach(function(trigger) {
662 return new Popover(trigger);
663 })
664 })
665
666 }, 200);
667
668 $('#siteBottomOverlayBtn').hide();
669 });
670
671 // Handle Modal Close Event
672 document.getElementById('productComparisonDialog').addEventListener('hidden.bs.modal', function(event) {
673 $('#siteBottomOverlayBtn').show();
674 });
675
676 /* attach click handler to product comparison button */
677 $('#siteBottomOverlayBtn').click(function(e) {
678 // console.log("_____________ CLICK _____________");
679 startProductCompare();
680 });
681 })
682 });
683
684 </script>
685
686
687 <div class="fade modal modal-bks" id="productComparisonDialog" aria-labelledby="productComparisonDialogLabel" role="dialog" tabindex="-1" style="display: none;">
688
689 </div>
690
691 </#if>
692
693
694 <#macro renderProductComparisonModalIfNecessary structureKey entries>
695 <#assign structureEntries = []>
696
697 <#list entries as entry>
698 <#assign
699 assetRenderer = entry.getAssetRenderer()
700 entryClassName = assetRenderer.getClassName()
701 >
702 <#if stringUtil.equals(entryClassName, "com.liferay.journal.model.JournalArticle")>
703 <#assign
704 article = entry.getAssetRenderer().getArticle()
705 thisStructureKey = article.getDDMStructureKey()
706 >
707 <#if stringUtil.equals(structureKey, thisStructureKey)>
708 <#assign structureEntries = structureEntries + [entry] />
709 </#if>
710 </#if>
711 </#list>
712
713 <#if structureEntries?size gt 0>
714 <@renderProductComparisonModalContent structureKey structureEntries/>
715 </#if>
716 </#macro>
717
718 <#macro renderProductComparisonModalContent structureKey entries>
719 <div id="productComparisonDialogTemplate-${structureKey}" class="hide">
720 <div class="modal-dialog modal-full-screen modal-product-comparison" role="document">
721 <div class="modal-content">
722 <div class="modal-header">
723 <h1 class="modal-title" id="productComparisonDialogLabel">Produktvergleich</h1>
724 <button type="button" class="close" data-bs-dismiss="modal" aria-label="<@liferay.language key="close" />" role="button">
725 <svg aria-hidden="true" class="lexicon-icon scale-lexicon-icon">
726 <use xlink:href="#icon_close" />
727 </svg>
728 </button>
729 </div>
730 <div class="modal-body">
731 <@renderProductComparisonTable structureKey structureEntries "hidden-xs"/>
732 </div>
733 </div>
734 </div>
735 </div>
736 </#macro>
737
738 <#macro renderProductComparisonTable structureKey entries cssClass>
739 <#assign isSingleEntry = true />
740 <#if entries?size gt 1>
741 <#assign isSingleEntry = false />
742 </#if>
743
744 <#if isSingleEntry>
745 <#assign articleId = entries?first.getAssetRenderer().getArticle().getId() />
746 <div class="table-wrapper product-detail product-comparison ${cssClass}" data-article-id="${articleId}">
747 <table class="table table-product">
748 <thead>
749 <@renderProductComparisonTableHeaderRow entries isSingleEntry/>
750 </thead>
751 <#else>
752 <div class="table-wrapper table-wrapper-tablesaw product-detail product-comparison ${cssClass}">
753 <table class="table table-product tablesaw tablesaw-swipe" data-tablesaw-mode="swipe">
754 <thead>
755 <@renderProductComparisonTableHeaderRow entries isSingleEntry/>
756 </thead>
757 </#if>
758 <tbody>
759 <#switch structureKey>
760 <#case "BKS-PRODUKT-KARTE">
761 <@renderProductComparisonTableDescriptionRow 8 "" entries isSingleEntry/>
762 <@renderProductComparisonTableRow "" labelVersicherungsschutz "" entries isSingleEntry "Versicherungsschutz"/>
763 <@renderProductComparisonTableRow "" labelReisestornoversicherung "" entries isSingleEntry "Reisestornoversicherung"/>
764 <@renderProductComparisonTableRow "" labelBKSOnlineAbrufbar "" entries isSingleEntry "BKSOnlineAbrufbar"/>
765 <@renderProductComparisonTableRow "" labelZusatzleistung "" entries isSingleEntry "Zusatzleistung"/>
766 <@renderProductComparisonTableRow "product-bold" labelVerfuegerrahmen "" entries isSingleEntry "Verfuegerrahmen"/>
767 <@renderProductComparisonTableRow "product-bold" labelKartengebuehr "" entries isSingleEntry "Kartengebuehr"/>
768 <@renderProductComparisonTableRow "" labelZusatzkarte "" entries isSingleEntry "Zusatzkarte"/>
769 <@renderProductComparisonTableLinkRow entries isSingleEntry "Button"/>
770 <#break>
771 <#case "BKS-PRODUKT-KONTO-PRIVATKUNDEN">
772 <@renderProductComparisonTableDescriptionRow 14 "" entries isSingleEntry/>
773 <@renderProductComparisonTableRow "" labelMyNetInternetbanking infoTextMyNetInternetbanking entries isSingleEntry "MyNetInternetbanking" />
774 <@renderProductComparisonTableRow "" labelDebitMastercard "" entries isSingleEntry "DebitMastercard" />
775 <@renderProductComparisonTableRow "" labelApplePayBluecodeGarminPayBKSWallet "" entries isSingleEntry "ApplePayBluecodeGarminPayBKSWallet" />
776 <@renderProductComparisonTableRow "" labelKontoversicherung infoTextKontoversicherung entries isSingleEntry "Kontoversicherung" />
777 <@renderProductComparisonTableRow "" labelStandardUndInternetbankingBuchung infoTextStandardUndInternetbankingBuchung entries isSingleEntry "StandardUndInternetbankingBuchung" />
778 <@renderProductComparisonTableRow "" labelSelbstbedienungsBuchung infoTextSelbstbedienungsBuchung entries isSingleEntry "SelbstbedienungsBuchung" />
779 <@renderProductComparisonTableRow "" labelSchalterServiceBuchung infoTextSchalterServiceBuchung entries isSingleEntry "SchalterServiceBuchung" />
780 <@renderProductComparisonTableRow "product-bold" labelPaketpreis "" entries isSingleEntry "Paketpreis" />
781 <@renderProductComparisonTableRow "" labelAirbag infoTextAirbag entries isSingleEntry "Airbag" />
782 <@renderProductComparisonTableRow "" labelBKSMastercard "" entries isSingleEntry "BKSMastercard" />
783 <@renderProductComparisonTableRow "" labelZweitkontoNaturZukunftKonto infoTextZweitkontoNaturZukunftKonto entries isSingleEntry "ZweitkontoNaturZukunftKonto" />
784 <@renderProductComparisonTableRow "" labelZweitkontoAllInKonto infoTextZweitkontoAllInKonto entries isSingleEntry "ZweitkontoAllInKonto" />
785 <@renderProductComparisonTableRow "" labelKontoabschluss "" entries isSingleEntry "Kontoabschluss" />
786 <@renderProductComparisonTableLinkRow entries isSingleEntry "Button"/>
787 <#break>
788 <#case "BKS-PRODUKT-DEPOT">
789 <@renderProductComparisonTableDescriptionRow 11 "" entries isSingleEntry/>
790 <@renderProductComparisonTableRow "" labelServicepreisDepot infoTextServicepreisDepot entries isSingleEntry "ServicepreisDepot"/>
791 <@renderProductComparisonTableRow "" labelDepotpreis infoTextDepotpreis entries isSingleEntry "Depotpreis"/>
792 <@renderProductComparisonTableSpacerRow spacerTextTransactions entries isSingleEntry/>
793 <@renderProductComparisonTableRow "" labelAktien "" entries isSingleEntry "Aktien"/>
794 <@renderProductComparisonTableRow "" labelAnleihen "" entries isSingleEntry "Anleihen"/>
795 <@renderProductComparisonTableRow "" labelInvestmentfondsKauf infoTextInvestmentfondsKauf entries isSingleEntry "InvestmentfondsKauf"/>
796 <@renderProductComparisonTableRow "" labelInvestmentfondsVerkauf "" entries isSingleEntry "InvestmentfondsVerkauf"/>
797 <@renderProductComparisonTableSpacerRow spacerTextCommunication entries isSingleEntry/>
798 <@renderProductComparisonTableRow "" labelEBox "" entries isSingleEntry "EBox"/>
799 <@renderProductComparisonTableRow "" labelPostversand "" entries isSingleEntry "Postversand"/>
800 <@renderProductComparisonTableLinkRow entries isSingleEntry "Button"/>
801 <#break>
802 <#case "BKS-PRODUKT-KONTO-FIRMENKUNDEN">
803 <@renderProductComparisonTableDescriptionRow 20 "" entries isSingleEntry/>
804 <@renderProductComparisonTableRow "product-bold" labelGrundpreis "" entries isSingleEntry "Grundpreis"/>
805 <@renderProductComparisonTableSpacerRow spacerTextTransaktionen "" entries isSingleEntry/>
806 <@renderProductComparisonTableRow "" labelELBABKS "" entries isSingleEntry "ELBABKS"/>
807 <@renderProductComparisonTableRow "" labelElektronischeBuchungen "" entries isSingleEntry "ElektronischeBuchungen"/>
808 <@renderProductComparisonTableRow "" labelSelbstbedienung "" entries isSingleEntry "Selbstbedienung"/>
809 <@renderProductComparisonTableRow "" labelServiceAmSchalter "" entries isSingleEntry "ServiceAmSchalter"/>
810 <@renderProductComparisonTableSpacerRow spacerTextKarten spacerInfoKarten entries isSingleEntry/>
811 <@renderProductComparisonTableRow "" labelMaestroKarte "" entries isSingleEntry "MaestroKarte"/>
812 <@renderProductComparisonTableRow "" labelVISACard "" entries isSingleEntry "VISACard"/>
813 <@renderProductComparisonTableRow "" labelBKSMastercardBusiness infoTextBKSMastercardBusiness entries isSingleEntry "BKSMastercardBusiness"/>
814 <@renderProductComparisonTableSpacerRow spacerTextAuszug "" entries isSingleEntry/>
815 <@renderProductComparisonTableRow "" labelAuszugElektronisch "" entries isSingleEntry "AuszugElektronisch"/>
816 <@renderProductComparisonTableSpacerRow spacerTextBizzNet "" entries isSingleEntry/>
817 <@renderProductComparisonTableRow "" labelBizzNet infoTextBizzNet entries isSingleEntry "BizzNet"/>
818 <@renderProductComparisonTableSpacerRow spacerTextBizzNetPlus "" entries isSingleEntry/>
819 <@renderProductComparisonTableRow "" labelBizzNetPlus infoTextBizzNetPlus entries isSingleEntry "BizzNetPlus"/>
820 <@renderProductComparisonTableRow "" labelBizzNetPlusMitLastschrift "" entries isSingleEntry "BizzNetPlusMitLastschrift"/>
821 <@renderProductComparisonTableSpacerRow spacerTextELBA "" entries isSingleEntry/>
822 <@renderProductComparisonTableRow "" labelELBA infoTextELBA entries isSingleEntry "ELBA"/>
823 <@renderProductComparisonTableLinkRow entries isSingleEntry "Button"/>
824 <#break>
825 </#switch>
826 </tbody>
827 </table>
828 </div>
829 <#if !isSingleEntry>
830 <#list entries as entry>
831 <#assign singleEntries = [entry] />
832 <@renderProductComparisonTable structureKey singleEntries "visible-xs"/>
833 </#list>
834 </#if>
835 </#macro>
836
837 <#macro renderProductComparisonTableHeaderRow entries isSingleEntry>
838 <#assign colAttributes = '' />
839 <tr>
840 <#if isSingleEntry>
841 <#assign colAttributes = 'scope="colgroup" colspan="2"' />
842 <#else>
843 <#assign colAttributes = 'scope="col" data-tablesaw-priority="3"' />
844 <th class="col-fixed" scope="col" data-tablesaw-priority="persist">
845 </th>
846 <th class="col-btn" scope="col" data-tablesaw-priority="persist"></th>
847 </#if>
848 <#list entries as entry>
849 <#assign
850 article = entry.getAssetRenderer().getArticle()
851 docXml = saxReaderUtil.read(article.getContent())
852 fieldVal = docXml.valueOf("//dynamic-element[@name='Heading']/dynamic-content/text()")
853 >
854 <th class="col-swipe product-title" data-article-id="${article.getId()}" ${colAttributes}>
855 ${fieldVal}
856 </th>
857 </#list>
858 </tr>
859 </#macro>
860
861 <#macro renderProductComparisonTableDescriptionRow index productLineClass entries isSingleEntry>
862 <#assign colAttributes = '' />
863
864 <tr class="${productLineClass}">
865 <#if isSingleEntry>
866 <#assign colAttributes = 'colspan="2"' />
867 <#else>
868 <td data-tablesaw-priority="persist"></td>
869 <#if index gt 0>
870 <td data-tablesaw-priority="persist" rowspan="${index}" class="col-btn">
871 <div class="btn-container" style="display: none;">
872 <button class="btn-left">
873 <svg aria-hidden="true" class="lexicon-icon scale-lexicon-icon">
874 <use xlink:href="#icon_arrow_alt_left" />
875 </svg>
876 </button>
877 <button class="btn-right">
878 <svg aria-hidden="true" class="lexicon-icon scale-lexicon-icon">
879 <use xlink:href="#icon_arrow_alt_right" />
880 </svg>
881 </button>
882 </div>
883 </td>
884 </#if>
885 </#if>
886 <#list entries as entry>
887 <#assign
888 article = entry.getAssetRenderer().getArticle()
889 docXml = saxReaderUtil.read(article.getContent())
890 />
891 <td class="product-description" data-article-id="${article.getId()}" ${colAttributes}>
892 <#assign textVal = docXml.valueOf("//dynamic-element[@name='ProductDescription']/dynamic-content/text()") />
893 <#if textVal?? && textVal != "">
894 ${textVal}
895 </#if>
896 </td>
897 </#list>
898 </tr>
899 </#macro>
900
901 <#macro renderProductComparisonTableSpacerRow productSpacerText entries isSingleEntry>
902 <#assign colAttributes = '' />
903
904 <#if isSingleEntry>
905 <#assign colAttributes = 'colspan="2"' />
906 </#if>
907
908 <tr class="row-spacer">
909 <td class="product-info-text" ${colAttributes}>
910 <#if productSpacerText != "">
911 ${productSpacerText}
912 <#else>
913
914 </#if>
915 </td>
916 <#if !isSingleEntry>
917 <#list entries as entry>
918 <#assign
919 article = entry.getAssetRenderer().getArticle()
920 />
921 <td data-article-id="${article.getId()}"></td>
922 </#list>
923 </#if>
924 </tr>
925 </#macro>
926
927 <#macro renderProductComparisonTableRow productLineClass productItemLabel productItemInfo entries isSingleEntry fieldName>
928 <tr class="${productLineClass}">
929 <td class="product-label">
930 <span class="product-label-text">${productItemLabel}</span>
931 <#if productItemInfo != "">
932 <@renderInfoIcon productItemInfo/>
933 </#if>
934 </td>
935 <#list entries as entry>
936 <@renderProductComparisonTableItemValue entry fieldName />
937 </#list>
938 </tr>
939 </#macro>
940
941 <#macro renderProductComparisonTableItemValue entry fieldName>
942 <#assign
943 article = entry.getAssetRenderer().getArticle()
944 docXml = saxReaderUtil.read(article.getContent())
945 />
946
947 <td class="product-value" data-article-id="${article.getId()}">
948 <#assign dropdownVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "Dropdown']/dynamic-content/text()") />
949 <#assign textVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "Text']/dynamic-content/text()") />
950 <#assign subtextVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "Subtext']/dynamic-content/text()") />
951 <#switch dropdownVal>
952 <#case "check">
953 <@renderEntryTrueIcon />
954 <#break>
955 <#case "text">
956 <#if textVal?? && textVal != "">
957 <span class="product-value-text">${textVal}</span>
958 </#if>
959 <#if subtextVal?? && subtextVal != "">
960 <span class="product-value-subtext">${subtextVal}</span>
961 </#if>
962 <#break>
963 <#default>
964 <@renderEntryFalseIcon />
965 <#break>
966 </#switch>
967 </td>
968 </#macro>
969
970 <#macro renderProductComparisonTableLinkRow entries isSingleEntry fieldName>
971 <#assign colAttributes = '' />
972
973 <tr class="product-links">
974 <#if isSingleEntry>
975 <#assign colAttributes = 'colspan="2"' />
976 <#else>
977 <td></td>
978 <td></td>
979 </#if>
980 <#list entries as entry>
981 <#assign
982 article = entry.getAssetRenderer().getArticle()
983 docXml = saxReaderUtil.read(article.getContent())
984 />
985
986 <td class="product-link" data-article-id="${article.getId()}" ${colAttributes}>
987 <#assign
988 textVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "Text']/dynamic-content/text()")
989 linkInternalVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "LinkInternal']/dynamic-content/text()")
990 linkExternalVal = docXml.valueOf("//dynamic-element[@name='" + fieldName + "LinkExternal']/dynamic-content/text()")
991 app = docXml.valueOf("//dynamic-element[@name='" + fieldName + "Applikation']/dynamic-content/text()")
992 />
993 <#if app?? && app != ''>
994 <a id="application-${article.getArticleResourceUuid()}" data-application="${app}" class="btn btn-primary" href="javascript:void(0);" title="${languageUtil.format(locale, "go-to-x", textVal, false)}">${textVal}</a>
995 <#elseif linkInternalVal?? && linkInternalVal != ''>
996 <#assign
997 linkInternalUrl = getLinkInternalFriendlyUrl(linkInternalVal)
998 />
999 <a class="btn btn-primary" data-senna-off href="${linkInternalUrl}" title="${languageUtil.format(locale, "go-to-x", textVal, false)}">${textVal}</a>
1000 <#elseif linkExternalVal?? && linkExternalVal != ''>
1001 <a class="btn btn-primary" data-senna-off href="${linkExternalVal}" target="_blank" title="${languageUtil.format(locale, "go-to-x", textVal, false)}">${textVal}</a>
1002 </#if>
1003 </td>
1004 </#list>
1005 </tr>
1006 </#macro>
1007
1008 <#function getLinkInternalFriendlyUrl linkData>
1009 <#assign
1010 linkInternalFriendlyUrl = ''
1011 />
1012 <#if linkData != ''>
1013 <#-- split the string to just get the page layout id , groupID and if its a private layout-->
1014 <#list linkData?split("@") as item>
1015 <#if item_index == 0>
1016 <#assign linkInternalPageId = item?number>
1017 </#if>
1018 <#if item_index == 1>
1019 <#if item == "private">
1020 <#assign linkInternalPrivate = true>
1021 <#else>
1022 <#assign linkInternalPrivate = false>
1023 </#if>
1024 </#if>
1025 <#if item_index = 2>
1026 <#assign linkInternalGroupId = item?number>
1027 </#if>
1028 </#list>
1029 <#-- get layout from interal link-->
1030 <#assign
1031 linkInternalLayout = LayoutLocalService.getLayout(linkInternalGroupId, linkInternalPrivate, linkInternalPageId)
1032 linkInternalFriendlyUrl = linkInternalLayout.getFriendlyURL(locale)
1033 >
1034 </#if>
1035
1036 <#return linkInternalFriendlyUrl>
1037 </#function>
1038
1039 <!-- *************** MACROS von Karte-Produkt - UNCHANGED *********************-->
1040
1041 <#macro renderInfoIcon iconText>
1042 <span class="icon-tooltip ${randomNamespace}-popover"
1043 data-bs-toggle="popover"
1044 data-bs-placement="top"
1045 data-bs-content="${iconText}"
1046 data-bs-trigger="hover"
1047 data-bs-html="true"
1048 >
1049 <svg aria-hidden="true" class="lexicon-icon scale-lexicon-icon">
1050 <use xlink:href="#icon_info" />
1051 </svg>
1052 </span>
1053 <span class="hide-accessible">
1054 ${iconText}
1055 </span>
1056 </#macro>
1057
1058 <#macro renderEntryFalseIcon>
1059 <span aria-hidden="true">
1060 –
1061 </span>
1062 <span class="hide-accessible">
1063 ${productDetailNo}
1064 </span>
1065 </#macro>
1066
1067 <#macro renderEntryTrueIcon>
1068 <svg aria-hidden="true" class="product-value-icon-check lexicon-icon scale-lexicon-icon">
1069 <use xlink:href="#icon_check" />
1070 </svg>
1071 <span class="hide-accessible">
1072 ${productDetailYes}
1073 </span>
1074 </#macro>
1075
1076 <!-- *************** MACROS von Karte-Produkt - UNCHANGED *********************-->
1077
1078</@>