Änderungen von Dokument Solr Search
am 2025/02/23 19:33
am 2025/12/16 11:14
Zusammenfassung
Details
- Seiteneigenschaften
-
- Dokument-Autor
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. admin1 +XWiki.dherrman
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -1,11 +1,7 @@ 1 1 require(['jquery', 'xwiki-events-bridge'], function($) { 2 2 var enhanceSearchResultHighlights = function() { 3 - varhighlights = $(this).removeClass('hidden').parent().prev('.search-result-highlights').addClass('preview');3 + const highlights = $(this).removeClass('hidden').prev('.search-result-highlights').addClass('preview'); 4 4 5 - // Workaround for IE8 which doesn't support :first-of-type CSS selector. 6 - highlights.find('.search-result-highlight').first().addClass('first').parent('dd').addClass('first') 7 - .prev('dt').addClass('first'); 8 - 9 9 $(this).one('click', function(event) { 10 10 event.preventDefault(); 11 11 $(event.target).remove(); ... ... @@ -37,10 +37,16 @@ 37 37 } 38 38 }; 39 39 40 - var addFacetValueCheckbox = function( index) {36 + var addFacetValueCheckbox = function() { 41 41 // Create an id unique to the facet value. 42 42 let facetContainer = $(this).parents('.search-facet').first(); 43 - $(this).attr('id', facetContainer.attr('data-name') + '-' + index.toString()); 39 + // We need the ids of the target facet elements to stay stable through the change, in order to refocus the item 40 + // that was clicked and triggered the change. 41 + // We use the JQuery index, so that id indexes are reset across facetContainers. 42 + // This allows for stable indexes: when reloading the facets after changing the filter for the target facet X, 43 + // the ids of all the checkbox for the target facet X will keep the same index. 44 + // This property is lost if multiple facets are changed in the query at once. 45 + $(this).attr('id', facetContainer.attr('data-name') + '-' + facetContainer.find('a.itemName').index($(this))); 44 44 // Initialize the checkbox. 45 45 let checkBox = $(document.createElement('input')).attr('type', 'checkbox'); 46 46 checkBox.attr('aria-labelledby', $(this).attr('id')); ... ... @@ -68,7 +68,7 @@ 68 68 updateExpandCollapseAllFacetsState(facetsContainer); 69 69 70 70 // Expand/Collapse toggle for each facet. 71 - facetsContainer.find('.facet-toggle r').on('click', function(event) {73 + facetsContainer.find('.facet-toggle').on('click', function(event) { 72 72 $(event.target).parents('.search-facet').toggleClass('expanded'); 73 73 updateExpandCollapseAllFacetsState(facetsContainer); 74 74 }); ... ... @@ -83,6 +83,11 @@ 83 83 var queryIndex = url.indexOf('?'); 84 84 return queryIndex < 0 ? '' : url.substr(queryIndex + 1); 85 85 }; 88 + 89 + let removeQueryString = function(url) { 90 + let queryIndex = url.indexOf('?'); 91 + return queryIndex < 0 ? url : url.substring(0, queryIndex); 92 + }; 86 86 87 87 var getSearchUIState = function() { 88 88 var expandedFacets = []; ... ... @@ -112,7 +112,9 @@ 112 112 113 113 var searchRequest = null; 114 114 115 - var pushSearchUIState = function(viewURL) { 122 + // changeTargetSelector is the CSS selector of the facet anchor that initiated this reload. ' 123 + // We expect the focus to go back to this place once the UI is reloaded. 124 + var pushSearchUIState = function(viewURL, changeTargetSelector) { 116 116 // If there is a request in progress, abort it to prevent its callback from being called. 117 117 searchRequest && searchRequest.abort(); 118 118 $('.search-ui').attr('aria-busy', true); ... ... @@ -125,6 +125,7 @@ 125 125 window.history.replaceState && window.history.replaceState(state, document.title); 126 126 // Make sure the browser address bar reflects the new state (and thus the new state can be bookmarked). 127 127 window.history.pushState && window.history.pushState(state, document.title, viewURL); 137 + document.querySelector(changeTargetSelector)?.focus(); 128 128 }); 129 129 }; 130 130 ... ... @@ -131,12 +131,12 @@ 131 131 var reloadSearchUI = function(event) { 132 132 event.preventDefault(); 133 133 var anchor = $(event.target).closest('a'); 134 - anchor.length && $(document).trigger('xwiki:search:update', anchor.attr('href'));144 + anchor.length && anchor.first().trigger('xwiki:search:update', anchor.attr('href')); 135 135 }; 136 136 137 137 // Others (e.g. a custom facet) can trigger a search UI update by firing this event. 138 138 $(document).on('xwiki:search:update', function(event, viewURL) { 139 - pushSearchUIState(viewURL); 149 + pushSearchUIState(viewURL, `[data-facetvalue='${CSS.escape(event.target.dataset.facetvalue)}']`); 140 140 }); 141 141 142 142 $(window).on('popstate', function(event) { ... ... @@ -176,10 +176,41 @@ 176 176 }); 177 177 178 178 var enhanceSearchUI = function() { 189 + // Enhance search options 190 + document.querySelectorAll('input.options-item').forEach(function (option){ 191 + option.addEventListener('change', function() { 192 + let queryFieldName = this.getAttribute('data-query-name'); 193 + let queryField = document.querySelector('input[name="' + queryFieldName + '"]'); 194 + queryField.value = this.checked ? 'true' : 'false'; 195 + // We want to build the URL the same way it's done in the velocimacro #extendQueryString 196 + // We retrieve the search parameters of the latest request 197 + let params = new URLSearchParams(window.location.search); 198 + let formParams = new URLSearchParams(new FormData(this.form)); 199 + // We replace the existing parameters with their value from the form 200 + for (let param of formParams.keys()) { 201 + if (params.has(param)) params.delete(param); 202 + for (let paramValue of formParams.getAll(param)) { 203 + params.append(param,paramValue); 204 + } 205 + } 206 + pushSearchUIState(window.location.pathname + '?' + params.toString(), 207 + 'input[data-query-name="' + queryFieldName + '"]'); 208 + }); 209 + }); 210 + // Enhance search result sorting 211 + document.querySelectorAll('.search-results-sort select#sort-by-input, ' + 212 + '.search-results-sort input#sort-order-input').forEach(function (sortInput){ 213 + sortInput.addEventListener('change', function() { 214 + let baseURL = removeQueryString(this.form.getAttribute('action')); 215 + pushSearchUIState(baseURL + "?" + 216 + new URLSearchParams(new FormData(this.form)).toString(), 217 + 'input[data-query-name="' + this.getAttribute('name') + '"]'); 218 + }); 219 + }); 220 + 179 179 $('.search-result-highlightAll').each(enhanceSearchResultHighlights); 180 180 $('.search-facets').each(enhanceSearchFacets); 181 181 $([ 182 - '.search-results-sort a.sort-item', 183 183 '.search-options a.options-item', 184 184 '.pagination a', 185 185 '.controlPagination a',
- XWiki.StyleSheetExtension[0]
-
- Code
-
... ... @@ -1,7 +1,7 @@ 1 1 #template('colorThemeInit.vm') 2 2 3 3 /* Hide the 'Created by', 'Modified by' and 'Tags' document sections. */ 4 -.xdocLastModification, .skin-colibri#document-info, #xdocFooter {4 +.xdocLastModification, #xdocFooter { 5 5 display: none; 6 6 } 7 7 #document-title > h1 { ... ... @@ -9,86 +9,99 @@ 9 9 margin-bottom: 0; 10 10 } 11 11 12 +/** 13 + * Layout for the search bar 14 + */ 15 +.search-bar { 16 + margin: .5em 0; 17 +} 18 + 19 +@media (min-width: 768px) { 20 + .search-bar { 21 + max-width: 50%; 22 + } 23 +} 24 + 12 12 /** 13 - * Searchform26 + * Layout for search controls (sort + options) 14 14 */ 15 15 16 -.skin-colibri .search-form { 17 - /* There is no space after the title in Colibri. */ 18 - margin-top: 1.5em; 29 +.search-results-controls { 30 + display: flex; 31 + flex-wrap: wrap; 32 + gap: 1em; 33 + 34 + & label { 35 + /* Reset the styles of the labels. */ 36 + margin: 0; 37 + font-weight: unset; 38 + } 19 19 } 20 20 21 -.skin-colibri .search-form input[type="search"] { 22 - /* Colibri doesn't have the grid system. */ 23 - width: 50%; 41 +.search-results-sort, 42 +.search-options, .search-options > ul, .search-options > ul > li, 43 +.search-options > ul > li > label { 44 + display: flex; 45 + gap: .4em; 46 + align-items: center; 24 24 } 25 25 26 26 /** 27 27 * Sort 28 28 */ 52 +/* This select should be especially lightweight on the UI. We're removing the default border and shadow. */ 53 +#sort-by-input { 54 + cursor: pointer; 29 29 30 -ul.search-results-sort { 31 - color: $theme.textSecondaryColor; 32 - font-size: .9em; 33 - padding: 5px 0 2px 0; 56 + &:hover, &:focus { 57 + cursor: pointer; 58 + } 59 +} 60 + 61 +/* This checkbox input should be styled as a switch between ascending and descending states. */ 62 +.search-results-sort #sort-order-input { 63 + /* Hide the default checkbox. We rely on the style of the icon in its label to make it work. */ 64 + appearance: none; 34 34 margin: 0; 35 35 } 36 -.search-results-sort li { 37 - display: inline; 38 - list-style-type: none; 39 - padding-left: 1.5em; 67 + 68 +#sort-by-input, .search-results-sort label:has(>#sort-order-input) { 69 + /* We want most of the styles from "form-control", but not the shadow that comes from bootstrap. */ 70 + box-shadow: none; 71 + & :hover,& :focus,& :focus-within { 72 + border-color: var(--input-border-focus); 73 + } 40 40 } 41 -.search-results-sort li:first-of-type { 42 - padding: 0; 75 + 76 +/* Flip the second icon so that it's the arrow going up and down. */ 77 +.search-results-sort label #sort-order-input + * + * { 78 + transform: scaleY(-1); 43 43 } 44 -a.sort-item { 45 - color: inherit; 46 - text-decoration: none; 80 + 81 +/* When the box is checked, we want to hide the first icon. 82 +When the box is not checked, we want to hide the second icon. */ 83 +.search-results-sort label #sort-order-input:checked + *, 84 +.search-results-sort label #sort-order-input:not(:checked) + * + * { 85 + display: none; 47 47 } 48 -a.sort-item:hover { 49 - color: $theme.linkColor; 50 - text-decoration: underline; 51 -} 52 -a.sort-item.active, a.sort-item.active:hover { 53 - font-weight: bold; 54 - color: $theme.textColor; 55 - text-decoration: none; 56 -} 57 -.sort-item-order { 58 - margin-left: .3em; 59 -} 60 60 61 61 /** 62 62 * Options 63 63 */ 64 64 65 -ul.search-options { 66 - color: $theme.textSecondaryColor; 67 - font-size: .9em; 68 - padding: 5px 0 2px 0; 92 +.search-options ul { 69 69 margin: 0; 70 -} 71 -.search-options li { 72 - display: inline; 73 - list-style-type: none; 74 - padding-left: 1.5em; 75 -} 76 -.search-options li:first-of-type { 77 77 padding: 0; 95 + 96 + & input[type="checkbox"] { 97 + position: unset; 98 + margin: 0; 99 + } 100 + 101 + & label { 102 + margin-right: 1em; 103 + } 78 78 } 79 -a.options-item { 80 - color: inherit; 81 - text-decoration: none; 82 -} 83 -a.options-item:hover { 84 - color: $theme.linkColor; 85 - text-decoration: underline; 86 -} 87 -a.options-item.active, a.options-item.active:hover{ 88 - font-weight: bold; 89 - color: $theme.textColor; 90 - text-decoration: none; 91 -} 92 92 93 93 /** 94 94 * Search Results ... ... @@ -98,12 +98,6 @@ 98 98 margin-top: 1em; 99 99 } 100 100 101 -/* Colibri skin doesn't have the grid system. */ 102 -.skin-colibri .search-results-left { 103 - margin: 0.5em 20em 0.5em 0; 104 - padding: 0.5em 0.5em 0.5em 0; 105 -} 106 - 107 107 .search-results { 108 108 padding: .3em 0 .8em 0; 109 109 } ... ... @@ -167,6 +167,8 @@ 167 167 168 168 dl.search-result-highlights > dt { 169 169 margin-top: .3em; 177 + color: var(--text-muted); 178 + font-weight: var(--font-weight-semibold); 170 170 } 171 171 172 172 blockquote.search-result-highlight { ... ... @@ -187,11 +187,6 @@ 187 187 font-weight: bold; 188 188 } 189 189 190 -dl.search-result-highlights > dt { 191 - color: $theme.textSecondaryColor; 192 - font-weight: normal; 193 -} 194 - 195 195 dl.search-result-highlights.preview dt, 196 196 dl.search-result-highlights.preview dd > * { 197 197 display: none; ... ... @@ -198,17 +198,10 @@ 198 198 } 199 199 200 200 dl.search-result-highlights.preview dt:first-of-type, 201 -dl.search-result-highlights.preview dd:first-of-type blockquote:first-of-type, 202 -/* Workaround for IE8 which doesn't support :first-of-type CSS selector. */ 203 -dl.search-result-highlights.preview dt.first, 204 -dl.search-result-highlights.preview dd.first blockquote.first { 205 +dl.search-result-highlights.preview dd:first-of-type blockquote:first-of-type { 205 205 display: block; 206 206 } 207 207 208 -a.search-result-highlightAll:after { 209 - content: ' \bb'; 210 -} 211 - 212 212 .search-result-debug { 213 213 white-space: pre; 214 214 } ... ... @@ -217,40 +217,23 @@ 217 217 * Facets 218 218 */ 219 219 220 -.search-facets { 221 - background-color: $theme.backgroundSecondaryColor; 222 - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); 223 - /* Leave space for the bottom shadow. */ 224 - margin-bottom: 1em; 225 - border-radius: 7px; 217 +.search-facets-header{ 218 + border-bottom: 1px solid var(--xwiki-border-color); 226 226 } 227 -/* Colibri skin doesn't have the grid system. */ 228 -.skin-colibri .search-facets { 229 - float: right; 230 - max-width: 19.5em; 231 - width: 19.5em; 232 -} 233 233 234 -.search-facets-header, 235 -.search-facets-actions, 236 -.search-facet { 237 - border-bottom: 1px solid $theme.borderColor; 238 - border-top: 1px solid $theme.pageContentBackgroundColor; 239 - position: relative; 221 +.search-facets-header strong { 222 + font-size: 1.25em; 240 240 } 241 241 242 242 .search-facets-header, 243 243 .search-facets-actions { 244 - padding: 0.5em1em;227 + padding: .5em 0; 245 245 } 229 + 246 246 .search-facet { 247 - padding: 0.5em.8em;231 + padding: .2em 0; 248 248 } 249 249 250 -.search-facets-header { 251 - border-top: none; 252 -} 253 - 254 254 .search-facets-header > p, 255 255 .search-facets-actions > p { 256 256 /* The wiki syntax generates paragraphs which have bottom margin. */ ... ... @@ -261,16 +261,6 @@ 261 261 font-size: .8em; 262 262 } 263 263 264 -.search-facets-actions a { 265 - color: $theme.textSecondaryColor; 266 - text-decoration: none; 267 -} 268 - 269 -.search-facets-actions a:hover { 270 - color: $theme.linkColor; 271 - text-decoration: underline; 272 -} 273 - 274 274 .search-facets-action-collapseAll, 275 275 .search-facets-action-expandAll { 276 276 float: right; ... ... @@ -282,35 +282,37 @@ 282 282 margin: 0; 283 283 } 284 284 285 -.search-facet:last-of-type { 286 - border-bottom: none; 255 +.search-facet-header, .search-facet-body { 256 + padding-left: .5em; 257 + border: 1px solid var(--xwiki-border-color); 258 + border-radius: var(--border-radius-small); 287 287 } 288 288 289 289 .search-facet-header { 262 + background-color: var(--xwiki-background-secondary-color); 263 +} 264 + 265 +.search-facet-header label { 290 290 color: $theme.titleColor; 291 291 cursor: pointer; 292 - line-height: 1.4em; 293 - margin: 0 .2em; 294 294 display: flex; 295 295 justify-content: space-between; 296 - position:relative;270 + align-items: center; 297 297 } 298 298 299 -.search-facet :last-of-type.search-facet-header:after{300 - border:medium none;301 - }273 +.search-facet-body { 274 + opacity: 0; 275 + visibility: hidden; /* This makes sure the element is removed from the accessibility tree. */ 302 302 303 -.search-facet.expanded:last-of-type .search-facet-header:after { 304 - border-bottom: 1px dotted $theme.pageContentBackgroundColor; 305 - border-top: 1px dotted $theme.borderColor; 277 + position: absolute; 278 + transform: translateY(-10px); /* Start the animation slightly above */ 279 + padding-top: .5em; 280 + 281 + border-top-width: 0; 282 + border-top-left-radius: 0; 283 + border-top-right-radius: 0; 306 306 } 307 307 308 -.search-facet-body { 309 - overflow: hidden; /* required for effect */ 310 - display: none; 311 - margin-top: .5em; 312 -} 313 - 314 314 .search-facet-body ul, 315 315 .search-facet-body ol { 316 316 font-size: .9em; ... ... @@ -319,37 +319,55 @@ 319 319 .search-facet-body li { 320 320 display: flex; 321 321 flex-wrap: wrap; 322 - padding: . 1em .2em;294 + padding: .3em .5em; 323 323 } 324 324 325 -.search-facet .search-facet-header .facet-toggle r, button.facet-value-toggler{297 +.search-facet .search-facet-header .facet-toggle, button.facet-value-toggle { 326 326 background: transparent; 327 327 transition: background-color .2s ease-in-out; 328 328 } 329 329 330 -.search-facet .search-facet-header .facet-toggle r:active, button.facet-value-toggler:active {302 +.search-facet .search-facet-header .facet-toggle:active, button.facet-value-toggle:active { 331 331 box-shadow: unset; 332 332 } 333 333 334 -.search-facet .search-facet-header .facet-toggle r> span, button.facet-value-toggler> span,335 -.search-facet .search-facet-header .facet-toggle r> img, button.facet-value-toggler> img {306 +.search-facet .search-facet-header .facet-toggle > span, button.facet-value-toggle > span, 307 +.search-facet .search-facet-header .facet-toggle > img, button.facet-value-toggle > img { 336 336 transform: rotate(90deg); 337 337 } 338 338 339 -.search-facet.expanded .search-facet-header .facet-toggle r> span, .expanded > button.facet-value-toggler> span,340 -.search-facet.expanded .search-facet-header .facet-toggle r> img, .expanded > button.facet-value-toggler> img {311 +.search-facet.expanded .search-facet-header .facet-toggle > span, .expanded > button.facet-value-toggle > span, 312 +.search-facet.expanded .search-facet-header .facet-toggle > img, .expanded > button.facet-value-toggle > img { 341 341 transform: rotate(0deg); 342 342 } 343 343 344 -@media not(prefers-reduced-motion) {345 - .search-facet .search-facet-header .facet-toggle r> span, button.facet-value-toggler> span,346 - .search-facet .search-facet-header .facet-toggle r> img, button.facet-value-toggler> img {316 +@media (prefers-reduced-motion: no-preference) { 317 + .search-facet .search-facet-header .facet-toggle > span, button.facet-value-toggle > span, 318 + .search-facet .search-facet-header .facet-toggle > img, button.facet-value-toggle > img { 347 347 transition: transform 0.2s ease; 348 348 } 321 + 322 + .search-facet-body { 323 + transition: opacity 0.3s ease, transform 0.3s ease; 324 + } 349 349 } 350 350 351 -.search-facet.expanded .search-facet-body { 352 - display: block; 327 +.search-facet.expanded { 328 + & .search-facet-header { 329 + border-bottom-width: 0; 330 + border-bottom-left-radius: 0; 331 + border-bottom-right-radius: 0; 332 + 333 + & label { 334 + font-weight: var(--font-weight-semibold); 335 + } 336 + } 337 + & .search-facet-body { 338 + opacity: 1; 339 + position: unset; /* This element should be positioned normally when shown. */ 340 + visibility: visible; 341 + transform: translateY(0); 342 + } 353 353 } 354 354 355 355 .search-facet-body ul, .search-facet-body ul.users { ... ... @@ -360,10 +360,6 @@ 360 360 margin: .5em 0; 361 361 } 362 362 363 -.search-facet-body li:hover { 364 - background-color: $theme.highlightColor; 365 -} 366 - 367 367 .search-facet-body input[type="checkbox"] { 368 368 margin: .2em 0; 369 369 } ... ... @@ -388,7 +388,8 @@ 388 388 } 389 389 390 390 .search-facet-body .itemName, 391 -.search-facet-body .facet-value-toggler, 377 +.search-facet-body .itemNameempty, 378 +.search-facet-body .facet-value-toggle, 392 392 .search-facet-body .more { 393 393 /* Remove link styling */ 394 394 color: $theme.textColor; ... ... @@ -406,8 +406,11 @@ 406 406 } 407 407 408 408 .search-facet-body .itemCount { 409 - padding: .1em 0;396 + padding: .1em .5em; 410 410 margin-left: auto; 398 + background-color: var(--nav-link-hover-bg); 399 + /* We want those item count blocks to be pill shaped. */ 400 + border-radius: 1em / 50%; 411 411 } 412 412 413 413 @media (max-width: 768px) { ... ... @@ -427,17 +427,6 @@ 427 427 } 428 428 429 429 /** 430 - * Fix the breadcrumb in Colibri skin. 431 - */ 432 -.skin-colibri .breadcrumb > li { 433 - display: inline; 434 -} 435 -.skin-colibri .breadcrumb > li + li:before { 436 - color: $theme.textSecondaryColor; 437 - content: ' \00BB '; 438 -} 439 - 440 -/** 441 441 * Miscellaneous 442 442 */ 443 443 ... ... @@ -446,13 +446,3 @@ 446 446 padding-left: 0; 447 447 } 448 448 449 -.paginationFilter .resultsNo, 450 -.paginationFilter .controlPagination, 451 -.paginationFilter .pagination { 452 - line-height: 22px; 453 -} 454 - 455 -.iconRSS { 456 - background: url("$xwiki.getSkinFile('icons/silk/feed.png')") no-repeat scroll 0 0 transparent; 457 - padding-left: 20px; 458 -}
Community

Wir benutzen Slack, um miteinander zu kommunizieren. Melde Dich an und werde Teil unserer Maker-Community!
Frage? FAQ!
Du hast eine Frage, die sich nicht direkt im Wiki findet?
Natürlich kannst Du die Frage jederzeit gerne in der Slack Community stellen. Bevor Du das machst, schau doch bitte einmal auf unserer Homepage bei den Häufig gestellten Fragen vorbei. Wir versuchen diese Fragen stets aktuell zu halten, eventuell hilft Dir das ja schon weiter.
Offene Werkstatt
Ohne Anmeldung einfach vorbei kommen. Am besten bringst Du direkt den ausgefüllten Haftungsauschluss mit.
Jeden Donnerstag ab 19 Uhr
Während der offenen Werkstatt kannst Du einfach vorbei kommen und an Deinem Projekt arbeiten. Bitte beachte aber, dass zur Verwendung der Maschinen eine Einweisung erforderlich ist, die Du gegebenfalls vorher absolvieren musst. Wenn ein Mitglied mit entsprechender Einweisung vor Ort ist und Zeit hat, helfen wir natürlich gerne aus. Dies können wir aber nicht garantieren, da Rundgänge Priorität haben.
Sprich Dich idealerweise schon vor der offenen Werkstatt mit einem Mitglied in unserem Slack ab. So kannst Du sicherstellen, dass Du auf jeden Fall arbeiten kannst.
Übrigens: Du kannst Dich mit einem Mitglied gerne auch außerhalb der offenen Werkstattzeiten zum Arbeiten verabreden!
Führungen und Rundgänge
Im Rahmen der offenen Werkstatt bieten wir euch auch gerne einen Rundgang durch unsere Werkstatt. Hier könnt ihr den Verein und unser Konzept kennenlernen sowie die Maschinen und Möglichkeiten der Werkstatt gezeigt bekommen.
Jeden Donnerstag wird eine Führung angeboten:
- Um 19:15 Uhr (bitte um 19:00 Uhr da sein)
Der Rundgang dauert ca. 45 Minuten und ihr habt natürlich auch die Möglichkeit, eure Fragen loszuwerden.
Bitte beachtet folgendes: Die Werkstatt beinhaltet gefährliche Maschinen. Bringt daher bitte nach Möglichkeit den ausgefüllten und unterschrieben Haftungsauschluss schon mit. Dieser kann aber auch vor Ort ausgefüllt werden, das verzögert allerdings die Abläufe.