1import mwCore from "/js/mw-core/mw-core.js"; 2import "/js/mw-core/mw-core-icon.js"; 3 4class mwCoreSelectfield extends mwCore { 5 // livecycle methods 6 7 updated() { 8 // cache DOM 9 10 this.cacheDOM(); 11 12 // register eventListener 13 14 this.registerEventListener(); 15 16 // set value 17 18 if (this.value) { 19 this._dom.select.value = this.value; 20 } else if (this._dom.select.value) { 21 // set value from first option field if not empty 22 23 this.value = this._dom.select.value; 24 } 25 } 26 27 static get observedAttributes() { 28 return [ 29 "name", 30 "label", 31 "messageerror", 32 "disabled", 33 "validate", 34 "readonly", 35 "labelinline", 36 "error", 37 "optionallabel", 38 ]; 39 } 40 41 // css 42 43 styles() { 44 return [ 45 `<link href="/css/styleguide.css" rel="stylesheet">`, 46 ` 47 * { 48 user-select: none; 49 } 50 *:focus-visible { 51 outline: 2px solid black !important; 52 outline-offset: -2px !important; 53 transition: none !important; 54 } 55 label { 56 display: inline-block; 57 margin: 0 0 4px; 58 } 59 :host([error]) label:after { 60 color: var(--mw-core-color-state-error); 61 content: "â¢"; 62 margin: 0 0 0 4px; 63 } 64 .form-row.focus label { 65 color: var(--mw-core-color-brand1); 66 } 67 :host([disabled]) label { 68 color: var(--mw-core-color-action-disabled); 69 } 70 select { 71 -moz-appearance: none; 72 -webkit-appearance: none; 73 appearance: none; 74 background: none; 75 border: var(--mw-core-color-form-field-stroke); 76 display: block; 77 height: 48px; 78 margin: 0; 79 outline: none; 80 padding: 0 36px 0 16px; 81 position: relative; 82 width: 100%; 83 z-index: 2; 84 } 85 :host([error]) select, 86 .form-row.focus select { 87 border-color: transparent; 88 } 89 :host([disabled]) select { 90 background: var(--mw-core-color-action-disabled); 91 border-color: transparent; 92 opacity: 0.3; 93 } 94 :host([readonly]) select { 95 border: var(--mw-core-color-form-field-stroke); 96 border-style: dashed; 97 } 98 .form-value-container { 99 background: var(--mw-core-color-form-field-background); 100 overflow: hidden; 101 position: relative; 102 } 103 .form-value-container:after { 104 background: var(--mw-core-color-overlay-dark10); 105 content: ""; 106 display: block; 107 height: 100%; 108 left: 0; 109 opacity: 0; 110 position: absolute; 111 top: 0; 112 transform: translate(-100%, 0px); 113 transition: transform 0.15s, opacity 0.2s; 114 width: 100%; 115 } 116 :host([error]) .form-value-container:after { 117 background: var(--mw-core-color-state-error); 118 opacity: 0.1 !important; 119 transform: translate(0px, 0px); 120 } 121 .form-row.focus .form-value-container:after { 122 opacity: 1; 123 transform: translate(0px, 0px); 124 } 125 :host([readonly]) .form-value-container:after { 126 transform: translate(0px, 0px); 127 z-index: 2; 128 } 129 .error-message { 130 display: none; 131 } 132 :host([error]) .error-message { 133 color: var(--mw-core-color-state-error); 134 display: block; 135 margin: 4px 0; 136 } 137 :host([error][labelinline]) .error-message { 138 font-size: 12px; 139 left: 20px; 140 line-height: 1; 141 margin: 0; 142 pointer-events: none; 143 position: absolute; 144 top: -6px; 145 } 146 :host([error][labelinline]) .error-message:before, 147 :host([error][labelinline]) .error-message:after { 148 background: var(--mw-core-color-state-error); 149 content: ""; 150 display: block; 151 height: 1px; 152 left: -12px; 153 margin: -0.5px 0 0 0; 154 position: absolute; 155 top: 50%; 156 width: 10px; 157 } 158 :host([error][labelinline]) .error-message:after { 159 left: auto; 160 right: -12px; 161 } 162 mw-core-icon.trigger { 163 align-items: center; 164 bottom: 0; 165 display: flex; 166 position: absolute; 167 right: 10px; 168 top: 0; 169 z-index: 0; 170 } 171 172 @media all and (min-width: 769px) { 173 174 select { 175 padding: 0 40px 0 20px; 176 } 177 178 } 179 180 `, 181 ]; 182 } 183 184 // render template 185 186 render() { 187 let template = this.querySelector("template"); 188 let options = ``; 189 190 if (template) { 191 let $options = template.content.querySelectorAll("option"); 192 193 for (let $option of $options) { 194 let tmp = document.createElement("div"); 195 tmp.appendChild($option.cloneNode(true)); 196 197 options += tmp.innerHTML; 198 } 199 } 200 201 let name = this.name ? this.name : ""; 202 let label = this.label ? this.label : ""; 203 let id = Math.random().toString(16).slice(2); 204 205 if (this.optionallabel && !this.validate) { 206 label += " " + this.optionallabel; 207 } 208 209 // Für aria-describedby die ID der Fehlermeldung erstellen 210 let errorId = `error-${id}`; 211 212 return ` 213 <div class="form-row"> 214 ${!this.labelinline ? `<label class="form-label" for="${id}">${label}</label>` : ``} 215 <div class="form-value-container effect-border-radius"> 216 <select 217 id="${id}" 218 ${name ? `name="${name}"` : ``} 219 class="form-value effect-border-radius" 220 ${this.disabled ? `disabled aria-disabled="true"` : ``} 221 ${this.readonly ? `disabled aria-readonly="true"` : ``} 222 ${this.labelinline ? `aria-label="${label}"` : ``} 223 aria-invalid="${this.error ? "true" : "false"}" 224 aria-describedby="${this.error && this.messageerror ? errorId : ""}" 225 >${options}</select> 226 <mw-core-icon class="trigger" name="chevrondown" aria-hidden="true"></mw-core-icon> 227 </div> 228 ${this.error && this.messageerror ? `<p id="${errorId}" class="error-message small-text" role="alert">${this.messageerror}</p>` : ``} 229 </div> 230 `; 231 } 232 233 // getter and setter 234 235 get name() { 236 return this._getAttribute("name"); 237 } 238 239 set name(val) { 240 this._setAttribute("name", val); 241 } 242 243 get label() { 244 return this._getAttribute("label"); 245 } 246 247 set label(val) { 248 this._setAttribute("label", val); 249 } 250 251 get messageerror() { 252 return this._getAttribute("messageerror"); 253 } 254 255 set messageerror(val) { 256 this._setAttribute("messageerror", val); 257 } 258 259 get disabled() { 260 return this._getAttribute("disabled"); 261 } 262 263 set disabled(val) { 264 this._setAttribute("disabled", val); 265 } 266 267 get validate() { 268 return this._getAttribute("validate"); 269 } 270 271 set validate(val) { 272 this._setAttribute("validate", val); 273 } 274 275 get readonly() { 276 return this._getAttribute("readonly"); 277 } 278 279 set readonly(val) { 280 this._setAttribute("readonly", val); 281 } 282 283 get labelinline() { 284 return this._getAttribute("labelinline"); 285 } 286 287 set labelinline(val) { 288 this._setAttribute("labelinline", val); 289 } 290 291 get error() { 292 return this._getAttribute("error"); 293 } 294 295 set error(val) { 296 this._setAttribute("error", val); 297 } 298 299 get value() { 300 return this._getAttribute("value"); 301 } 302 303 set value(val) { 304 this._setAttribute("value", val); 305 } 306 307 get optionallabel() { 308 return this._getAttribute("optionallabel"); 309 } 310 311 set optionallabel(val) { 312 this._setAttribute("optionallabel", val); 313 } 314 315 // custom methods 316 317 cacheDOM() { 318 // cache dom elements for faster access 319 320 this._dom = { 321 select: this.shadowRoot.querySelector("select"), 322 clearIcon: this.shadowRoot.querySelector("mw-core-icon.clear-value"), 323 }; 324 } 325 326 checkValue() { 327 if (this.value) { 328 this.error = false;
329 } else { 330 this.error = true; 331 } 332 } 333 334 registerEventListener() { 335 if (this._dom.select) { 336 // focus 337 338 this._dom.select.addEventListener("focus", (event) => { 339 if (this.disabled || this.readonly) { 340 return; 341 } 342 this._dom.select.closest(".form-row").classList.add("focus"); 343 }); 344 345 // blur (leave) 346 347 this._dom.select.addEventListener("blur", (event) => { 348 this._dom.select.closest(".form-row").classList.remove("focus"); 349 350 // field check 351 352 if (this.validate) { 353 setTimeout(() => { 354 this.checkValue(); 355 }, 100); 356 } 357 }); 358 359 // set value 360 361 this._dom.select.addEventListener("change", (event) => { 362 this.value = this._dom.select.value; 363 this.fireEvent(); 364 }); 365 } 366 } 367 368 fireEvent() { 369 // fires custom event (change) 370 371 this.dispatchEvent(new CustomEvent("change")); 372 } 373} 374 375customElements.define("mw-core-selectfield", mwCoreSelectfield);
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.