PageSourceSearch

https://www.wagrain-kleinarl.at/js/mw-core/mw-core-table.js

js wagrain-kleinarl.at collected 2026-09-24 22:03:50 UTC 14,397 bytes, 620 lines download raw bytes

1import mwCore from "/js/mw-core/mw-core.js";
2import mwUtility from "/js/mw-core/mw-utility.js";
3import "/js/mw-core/mw-core-icon.js";
4
5class mwCoreTable extends mwCore {
6	// livecycle methods
7
8	beforeFirstRender() {
9		let template;
10
11		// render data
12
13		try {
14			template = this.querySelector(`template[is="component-data"]`);
15
16			this._data = JSON.parse(template.content.textContent);
17
18			// remove template from DOM
19
20			template.remove();
21		} catch (error) {
22			console.error(error);
23			return;
24		}
25
26		// media query
27
28		this._mq = this.breakpoint ? parseInt(this.breakpoint) : 767;
29
30		let instance = this;
31		mwUtility.mediaQuery(this._mq, {
32			yep: function () {
33				instance.display = "mobile";
34			},
35			nope: function () {
36				instance.display = "desktop";
37			}
38		});
39
40		// load swiper async if necessary
41
42		if (this.variant === "slider") {
43			import("/js/mw-core/swiper.js").then((_) => {
44				// load css
45
46				let styles = document.createElement("link");
47				styles.setAttribute("href", "/css/swiper.css");
48				styles.setAttribute("rel", "stylesheet");
49
50				this.shadowRoot.appendChild(styles);
51
52				// set swiper flag
53
54				this._swiperLoaded = true;
55				this._swiperInit = false;
56
57				// rerender layout
58
59				this.reRender();
60			});
61		}
62	}
63
64	updated() {
65		// init swiper if swiper async loaded
66
67		if (this.variant === "slider" && this._swiperLoaded && !this._swiperInit) {
68			let breakpoints = {
69				0: {
70					slidesPerView: 2
71				},
72				650: {
73					slidesPerView: 3
74				},
75				980: {
76					slidesPerView: 4
77				}
78			};
79
80			if (this.sliderbreakpoints) {
81				// get custom breakpoints (attribute or property)
82				// format px:slidesPerView
83				// example: 768:4
84
85				let customBreakpoints = this.sliderbreakpoints.split("|");
86
87				breakpoints = {};
88
89				for (let breakpoint of customBreakpoints) {
90					breakpoints[breakpoint.split(":")[0]] = {
91						slidesPerView: breakpoint.split(":")[1]
92					};
93				}
94			}
95
96			this._swiperInstance = new Swiper(
97				this.shadowRoot.querySelector(".swiper-container"),
98				{
99					pagination: {
100						el: this.shadowRoot.querySelector(".swiper-pagination"),
101						clickable: true
102					},
103					navigation: {
104						nextEl: this.shadowRoot.querySelector(".swiper-button-next"),
105						prevEl: this.shadowRoot.querySelector(".swiper-button-prev")
106					},
107					breakpoints: breakpoints
108				}
109			);
110		}
111
112		// cache DOM
113
114		this.cacheDOM();
115
116		// register eventListener
117
118		this.registerEventListener();
119	}
120
121	static get observedAttributes() {
122		return [
123			"variant",
124			"display",
125			"breakpoint",
126			"sliderbreakpoints",
127			"fixfirstcolumn",
128			"reverse",
129			"hidefirstcolumninfirstrow"
130		];
131	}
132
133	// css
134
135	styles() {
136		return [
137			`<link href="/css/styleguide.css" rel="stylesheet">`,
138			`
139				*:focus-visible {
140					outline: 2px solid black !important;
141					outline-offset: -2px !important;
142					transition: none !important;
143				}
144
145				/*** Variant Default - Mobile ***/
146
147				:host([display="mobile"]) .table-default .entry {
148					margin: 0 0 6px;
149				}
150				:host([display="mobile"]) .table-default .entry .row {
151					display: flex;
152				}
153				:host([display="mobile"]) .table-default .entry .row .column:nth-child(1) {
154					background: var(--mw-core-color-background-bright);
155					flex: 2;
156					overflow: hidden;
157					padding: 10px;
158					text-overflow: ellipsis;
159				}
160				:host([display="mobile"]) .table-default .entry .row .column:nth-child(2) {
161					flex: 3;
162					padding: 10px;
163				}
164
165				/*** Variant Default - Desktop ***/
166
167				:host([display="desktop"]) .table-default .row {
168					border-bottom: 1px solid var(--mw-core-color-background-bright);
169					display: flex;
170				}
171				:host([display="desktop"]) .table-default .row:nth-child(1) {
172					border-color: transparent;
173				}
174				:host([display="desktop"]) .table-default .row .column {
175					flex: 1;
176					overflow: hidden;
177					padding: 10px;
178					text-overflow: ellipsis;
179				}
180				:host([display="desktop"]) .table-default .row:nth-child(1) .column {
181					background: var(--mw-core-color-background-bright);
182				}
183				:host([display="desktop"]) .table-default .row:hover .column {
184					background: var(--mw-core-color-background-bright);
185				}
186
187				/*** Variant Slider ***/
188
189				:host([variant="slider"]) * {
190					user-select: none;
191				}
192				:host([variant="slider"]) .root {
193					padding: 0 0 60px;
194				}
195				.table-slider {
196					position: relative;
197				}
198				.table-slider .row {
199					align-items: center;
200					border-bottom: 1px solid var(--mw-core-color-background-bright);
201					display: block;
202					line-height: 50px;
203					overflow: hidden;
204					padding: 0 10px;
205					text-overflow: ellipsis;
206					white-space: nowrap;
207				}
208				.table-slider .column .row:nth-child(1) {
209					background: var(--mw-core-color-background-bright);
210					border-color: transparent;
211				}
212
213				/*** Swiper ***/
214
215				.table-slider .swiper-pagination {
216					align-items: center;
217					bottom: -60px;
218					display: flex;
219					height: 40px;
220					justify-content: center;
221					left: 60px;
222					right: 60px;
223				}
224				.table-slider .swiper-pagination-bullet {
225					display: block;
226					flex: 0 0 10px;
227					height: 10px;
228					margin: 0 5px;
229					outline: none;
230				}
231				.table-slider .swiper-pagination-bullet-active {
232					background: var(--mw-core-color-action-primary);
233				}
234				.table-slider .swiper-button-prev {
235					bottom: -60px;
236					color: var(--mw-core-color-action-primary);
237					height: 40px;
238					left: 0;
239					outline: none;
240					top: auto;
241					user-select: none;
242					width: 40px;
243				}
244				.table-slider .swiper-button-prev:after {
245					content: "";
246				}
247				.table-slider .swiper-button-next {
248					bottom: -60px;
249					color: var(--mw-core-color-action-primary);
250					height: 40px;
251					outline: none;
252					right: 0;
253					top: auto;
254					user-select: none;
255					width: 40px;
256				}
257				.table-slider .swiper-button-next:after {
258					content: "";
259				}
260
261				/*** Variant Slider with fixfirstcolumn ***/
262
263				:host([fixfirstcolumn]) .table-slider .table-content {
264					display: flex;
265				}
266				:host([fixfirstcolumn]) .table-slider .table-content .fixedColumn {
267					flex: 0 0 180px;
268				}
269				:host([fixfirstcolumn]) .table-slider .table-content .swiper-container {
270					flex: 1;
271				}
272				:host([fixfirstcolumn][hidefirstcolumninfirstrow]) .table-slider .table-content .fixedColumn .row:first-child {
273					visibility: hidden;
274				}
275				
276				@media all and (min-width: 500px) {
277
278					:host([fixfirstcolumn]) .table-slider .table-content .column {
279						border-right: 1px solid var(--mw-core-color-background-bright);
280					}
281					:host([fixfirstcolumn]) .table-slider .table-content .fixedColumn {
282						flex: 0 0 280px;
283						width: 280px;
284					}
285					:host([fixfirstcolumn]) .table-slider .row {
286						border: 0;
287						border-top: 1px solid var(--mw-core-color-background-bright);
288					}
289					:host([fixfirstcolumn]) .table-slider .column .row:nth-child(1) {
290						background: none;
291					}
292					:host([fixfirstcolumn]) .table-slider .row:last-child {
293						border-bottom: 1px solid var(--mw-core-color-background-bright);
294					}
295					:host([fixfirstcolumn]) .table-slider .swiper-slide.column .row {
296						justify-content: center;
297					}
298					:host([fixfirstcolumn]) .table-slider .table-content .fixedColumn .row {
299						border-left: 1px solid var(--mw-core-color-background-bright);
300						margin-right: 40px;
301					}
302					:host([fixfirstcolumn]) .table-slider .table-content .fixedColumn .row:first-child {
303						margin-right: 0;
304					}
305					:host([fixfirstcolumn]) .table-slider .table-content .swiper-container {
306						margin: 0 40px 0 0;
307					}
308					:host([fixfirstcolumn]) .table-slider .swiper-button-prev {
309						background: var(--mw-core-color-action-primary);
310						border-radius: 0;
311						bottom: 0;
312						color: #FFFFFF;
313						height: auto;
314						left: 240px;
315						top: 50px;
316					}
317					:host([fixfirstcolumn]) .table-slider .swiper-button-next {
318						background: var(--mw-core-color-action-primary);
319						border-radius: 0;
320						bottom: 0;
321						color: #FFFFFF;
322						height: auto;
323						top: 50px;
324					}
325
326				}
327
328			`
329		];
330	}
331
332	// render template
333
334	render() {
335		// check data
336
337		if (!this._data) {
338			console.error("no valid data");
339			return "";
340		}
341
342		let content = ``;
343
344		// check if data is array
345		// and if array length > 0
346
347		if (!Array.isArray(this._data)) {
348			console.error("table data not an array");
349			return;
350		} else if (this._data.length === 0) {
351			console.error("table data empty");
352			return;
353		}
354
355		// switch table layout
356
357		switch (this.variant) {
358			case "default":
359			case null:
360				// default layout
361
362				if (this.display === "mobile") {
363					content = this.renderDefaultMobileTable();
364				} else {
365					content = this.renderDefaultDesktopTable();
366				}
367
368				break;
369
370			case "slider":
371				// slider layout
372
373				content = this.renderSliderTable();
374
375				break;
376		}
377
378		return `${content}`;
379	}
380
381	// getter and setter
382
383	get variant() {
384		return this._getAttribute("variant");
385	}
386
387	set variant(val) {
388		this._setAttribute("variant", val);
389	}
390
391	get display() {
392		return this._getAttribute("display");
393	}
394
395	set display(val) {
396		this._setAttribute("display", val);
397	}
398
399	get breakpoint() {
400		return this._getAttribute("breakpoint");
401	}
402
403	set breakpoint(val) {
404		this._setAttribute("breakpoint", val);
405	}
406
407	get fixfirstcolumn() {
408		return this._getAttribute("fixfirstcolumn");
409	}
410
411	set fixfirstcolumn(val) {
412		this._setAttribute("fixfirstcolumn", val);
413	}
414
415	get reverse() {
416		return this._getAttribute("reverse");
417	}
418
419	set reverse(val) {
420		this._setAttribute("reverse", val);
421	}
422
423	get sliderbreakpoints() {
424		return this._getAttribute("sliderbreakpoints");
425	}
426
427	set sliderbreakpoints(val) {
428		this._setAttribute("sliderbreakpoints", val);
429	}
430
431	get hidefirstcolumninfirstrow() {
432		return this._getAttribute("hidefirstcolumninfirstrow");
433	}
434
435	set hidefirstcolumninfirstrow(val) {
436		this._setAttribute("hidefirstcolumninfirstrow", val);
437	}
438
439	// custom methods
440
441	cacheDOM() {
442		// cache dom elements for faster access
443
444		this._dom = {};
445	}
446
447	registerEventListener() {}
448
449	renderDefaultMobileTable() {
450		// render default mobile table
451
452		let content = ``;
453
454		if (this._data.length <= 1) {
455			console.error("table data missing rows");
456			return "";
457		}
458
459		for (let i = 1; i < this._data.length; i++) {
460			content += `<div class="entry">`;
461
462			for (let j = 0; j < this._data[i].columns.length; j++) {
463				let currentData = this._data[i].columns[j].text;
464
465				content += `<div class="row">
466								<div class="column normal-text-bold">${this._data[0].columns[j].text}</div>
467								<div class="column normal-text">${currentData}</div>
468							</div>`;
469			}
470
471			content += `</div>`;
472		}
473
474		return `<div class="table-default">${content}</div>`;
475	}
476
477	renderDefaultDesktopTable() {
478		// render default mobile table
479
480		let content = ``;
481
482		if (this._data.length <= 1) {
483			console.error("table data missing rows");
484			return "";
485		}
486
487		if (!this.reverse) {
488			for (let i = 0; i < this._data.length; i++) {
489				content += `<div class="row">`;
490
491				for (let j = 0; j < this._data[i].columns.length; j++) {
492					let currentData = this._data[i].columns[j].text;
493					let align = this._data[i].columns[j].align;
494
495					content += `<div class="column ${
496						i === 0 ? `normal-text-bold` : `normal-text`
497					}" style="text-align: ${align}">${currentData}</div>`;
498				}
499
500				content += `</div>`;
501			}
502		} else {
503			for (let j = 0; j < this._data[0].columns.length; j++) {
504				content += `<div class="row">`;
505
506				for (let i = 0; i < this._data.length; i++) {
507					let currentData = this._data[i].columns[j].text;
508					let align = this._data[i].columns[j].align;
509
510					content += `<div class="column ${
511						i === 0 ? `normal-text-bold` : `normal-text`
512					}" style="text-align: ${align}">${currentData}</div>`;
513				}
514
515				content += `</div>`;
516			}
517		}
518
519		return `<div class="table-default">${content}</div>`;
520	}
521
522	renderSliderTable() {
523		// render slider table
524
525		let content = ``;
526		let firstColumn = ``;
527
528		if (this._data.length < 1) {
529			console.error("table data missing rows");
530			return "";
531		}
532
533		if (!this.reverse) {
534			for (let j = 0; j < this._data[0].columns.length; j++) {
535				// detect firstColumn
536				// if fixfirstcolumn is true
537
538				if (j === 0 && this.fixfirstcolumn) {
539					firstColumn += `<div class="fixedColumn column">`;
540				} else {
541					content += `<div class="column swiper-slide">`;
542				}
543
544				for (let i = 0; i < this._data.length; i++) {
545					if (j === 0 && this.fixfirstcolumn) {
546						firstColumn += `<div class="row ${
547							i === 0 ? `normal-text-bold` : `normal-text`
548						}" style="text-align: ${this._data[i].columns[j].align}">
549											${this._data[i].columns[j].text}
550										</div>`;
551					} else {
552						content += `<div class="row ${
553							i === 0 ? `normal-text-bold` : `normal-text`
554						}" style="text-align: ${this._data[i].columns[j].align}">
555										${this._data[i].columns[j].text}
556									</div>`;
557					}
558				}
559
560				if (j === 0 && this.fixfirstcolumn) {
561					firstColumn += `</div>`;
562				} else {
563					content += `</div>`;
564				}
565			}
566		} else {
567			for (let i = 0; i < this._data.length; i++) {
568				if (i === 0 && this.fixfirstcolumn) {
569					firstColumn += `<div class="fixedColumn column">`;
570				} else {
571					content += `<div class="column swiper-slide">`;
572				}
573
574				for (let j = 0; j < this._data[i].columns.length; j++) {
575					if (i === 0 && this.fixfirstcolumn) {
576						firstColumn += `<div class="row ${
577							j === 0 ? `normal-text-bold` : `normal-text`
578						}">
579											${this._data[i].columns[j]}
580										</div>`;
581					} else {
582						content += `<div class="row ${
583							j === 0 ? `normal-text-bold` : `normal-text`
584						}">
585										${this._data[i].columns[j]}
586									</div>`;
587					}
588				}
589
590				if (i === 0 && this.fixfirstcolumn) {
591					firstColumn += `</div>`;
592				} else {
593					content += `</div>`;
594				}
595			}
596		}
597
598		return `
599			<div class="table-slider">
600				<div class="table-content">
601					${firstColumn}
602					<div class="swiper-container">
603						<div class="swiper-wrapper">
604							${content}
605						</div>
606					</div>
607				</div>
608				<div class="swiper-pagination"></div>
609				<div class="swiper-button-prev effect-border-radius">
610					<mw-core-icon size="m" name="chevronleft"></mw-core-icon>
611				</div>
612				<div class="swiper-button-next effect-border-radius">
613					<mw-core-icon size="m" name="chevronright"></mw-core-icon>
614				</div>
615			</div>
616		`;
617	}
618}
619
620customElements.define("mw-core-table", mwCoreTable);

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.