hr-design-system-handlebars 1.105.0 → 1.105.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/handlebars/helpers/handlebar-helpers.js +24 -0
  3. package/dist/assets/index.css +25 -30
  4. package/dist/assets/js/alpine.js +4 -1
  5. package/dist/assets/js/components/forms/contactForm.alpine.js +36 -0
  6. package/dist/assets/js/components/forms/inputHandler.alpine.js +18 -12
  7. package/dist/views/components/forms/choice.hbs +2 -2
  8. package/dist/views/components/forms/fields.hbs +6 -2
  9. package/dist/views/components/forms/input.hbs +33 -20
  10. package/dist/views/components/forms/select.hbs +3 -8
  11. package/dist/views/components/forms/textarea.hbs +11 -8
  12. package/dist/views/components/forms/webform.hbs +23 -45
  13. package/dist/views/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
  14. package/dist/views/components/site_header/section_navigation/section_navigation_item.hbs +1 -1
  15. package/dist/views/components/site_header/service_navigation/service_navigation_item.hbs +1 -1
  16. package/dist/views_static/components/forms/choice.hbs +2 -2
  17. package/dist/views_static/components/forms/fields.hbs +6 -2
  18. package/dist/views_static/components/forms/input.hbs +33 -20
  19. package/dist/views_static/components/forms/select.hbs +3 -8
  20. package/dist/views_static/components/forms/textarea.hbs +11 -8
  21. package/dist/views_static/components/forms/webform.hbs +23 -45
  22. package/dist/views_static/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
  23. package/dist/views_static/components/site_header/section_navigation/section_navigation_item.hbs +1 -1
  24. package/dist/views_static/components/site_header/service_navigation/service_navigation_item.hbs +1 -1
  25. package/package.json +1 -1
  26. package/src/assets/fixtures/content/copytext/copytext_webform.json +60 -0
  27. package/src/assets/js/alpine.js +4 -1
  28. package/src/stories/views/components/content/copytext/fixtures/copytext_webform.json +1 -1
  29. package/src/stories/views/components/forms/choice.hbs +2 -2
  30. package/src/stories/views/components/forms/contactForm.alpine.js +36 -0
  31. package/src/stories/views/components/forms/fields.hbs +6 -2
  32. package/src/stories/views/components/forms/input.hbs +33 -20
  33. package/src/stories/views/components/forms/inputHandler.alpine.js +18 -12
  34. package/src/stories/views/components/forms/select.hbs +3 -8
  35. package/src/stories/views/components/forms/textarea.hbs +11 -8
  36. package/src/stories/views/components/forms/webform.hbs +23 -45
  37. package/src/stories/views/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
  38. package/src/stories/views/components/site_header/section_navigation/section_navigation_item.hbs +1 -1
  39. package/src/stories/views/components/site_header/service_navigation/service_navigation_item.hbs +1 -1
  40. package/dist/assets/js/components/forms/selectHandler.alpine.js +0 -15
  41. package/src/stories/views/components/forms/selectHandler.alpine.js +0 -15
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v1.105.1 (Mon Oct 07 2024)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - ♻️ Refactor Send Button Validation check - DPE-3384 Refactoring [#1093](https://github.com/mumprod/hr-design-system-handlebars/pull/1093) ([@vascoeduardo](https://github.com/vascoeduardo))
6
+
7
+ #### Authors: 1
8
+
9
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
10
+
11
+ ---
12
+
1
13
  # v1.105.0 (Mon Oct 07 2024)
2
14
 
3
15
  #### 🚀 Enhancement
@@ -538,6 +538,30 @@ var helpers = {
538
538
  'strip': function (input, param) {
539
539
  return input
540
540
  },
541
+ /**
542
+ * Handlebars Helper: joinString
543
+ *
544
+ * This helper function concatenates multiple strings or numbers into a single string.
545
+ * It filters out non-string and non-numeric values (such as objects, arrays, or null)
546
+ * to prevent invalid data from being included in the final result.
547
+ *
548
+ * Usage:
549
+ * {{joinString 'form' (generateRandom)}}
550
+ *
551
+ * Example Output:
552
+ * If 'form' is passed as the first argument and the `generateRandom` function returns 408,
553
+ * the output will be: 'form408'.
554
+ *
555
+ * Notes:
556
+ * - Strings and numbers are included in the final concatenation.
557
+ * - Objects, arrays, and other non-string, non-number types are ignored.
558
+ *
559
+ * Function implementation:
560
+ */
561
+ 'joinStrings': function (...args) {
562
+ return args.filter(arg => typeof arg === 'string' || typeof arg === 'number').join('');
563
+ }
564
+
541
565
  }
542
566
 
543
567
  // Export helpers
@@ -1139,9 +1139,6 @@ article.indexTextDS .indexTextHighlighted .link {
1139
1139
  .right-0 {
1140
1140
  right: 0px;
1141
1141
  }
1142
- .right-14 {
1143
- right: 3.5rem;
1144
- }
1145
1142
  .right-4 {
1146
1143
  right: 1rem;
1147
1144
  }
@@ -1986,27 +1983,6 @@ article.indexTextDS .indexTextHighlighted .link {
1986
1983
  .animate-none {
1987
1984
  animation: none;
1988
1985
  }
1989
- @keyframes shake {
1990
-
1991
- 10%, 90% {
1992
- transform: translate3d(-1px, 0, 0);
1993
- }
1994
-
1995
- 20%, 80% {
1996
- transform: translate3d(2px, 0, 0);
1997
- }
1998
-
1999
- 30%, 50%, 70% {
2000
- transform: translate3d(-4px, 0, 0);
2001
- }
2002
-
2003
- 40%, 60% {
2004
- transform: translate3d(4px, 0, 0);
2005
- }
2006
- }
2007
- .animate-shake {
2008
- animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
2009
- }
2010
1986
  @keyframes spin {
2011
1987
 
2012
1988
  to {
@@ -2246,6 +2222,10 @@ article.indexTextDS .indexTextHighlighted .link {
2246
2222
  .rounded-lg {
2247
2223
  border-radius: 0.5rem;
2248
2224
  }
2225
+ .rounded-b {
2226
+ border-bottom-right-radius: 0.25rem;
2227
+ border-bottom-left-radius: 0.25rem;
2228
+ }
2249
2229
  .rounded-l {
2250
2230
  border-top-left-radius: 0.25rem;
2251
2231
  border-bottom-left-radius: 0.25rem;
@@ -2307,6 +2287,9 @@ article.indexTextDS .indexTextHighlighted .link {
2307
2287
  .border-t {
2308
2288
  border-top-width: 1px;
2309
2289
  }
2290
+ .border-t-0 {
2291
+ border-top-width: 0px;
2292
+ }
2310
2293
  .border-t-\[3px\] {
2311
2294
  border-top-width: 3px;
2312
2295
  }
@@ -2400,9 +2383,9 @@ article.indexTextDS .indexTextHighlighted .link {
2400
2383
  border-color: #005293;
2401
2384
  border-color: var(--color-primary-ds);
2402
2385
  }
2403
- .border-red-500 {
2386
+ .border-red-400 {
2404
2387
  --tw-border-opacity: 1;
2405
- border-color: rgba(239, 68, 68, var(--tw-border-opacity));
2388
+ border-color: rgba(248, 113, 113, var(--tw-border-opacity));
2406
2389
  }
2407
2390
  .border-red-700 {
2408
2391
  --tw-border-opacity: 1;
@@ -2601,6 +2584,14 @@ article.indexTextDS .indexTextHighlighted .link {
2601
2584
  background-color: #005293;
2602
2585
  background-color: var(--color-primary-ds);
2603
2586
  }
2587
+ .bg-red-100 {
2588
+ --tw-bg-opacity: 1;
2589
+ background-color: rgba(254, 226, 226, var(--tw-bg-opacity));
2590
+ }
2591
+ .bg-red-500 {
2592
+ --tw-bg-opacity: 1;
2593
+ background-color: rgba(239, 68, 68, var(--tw-bg-opacity));
2594
+ }
2604
2595
  .bg-slate-200 {
2605
2596
  --tw-bg-opacity: 1;
2606
2597
  background-color: rgba(226, 232, 240, var(--tw-bg-opacity));
@@ -3209,6 +3200,10 @@ article.indexTextDS .indexTextHighlighted .link {
3209
3200
  --tw-text-opacity: 1;
3210
3201
  color: rgba(22, 163, 74, var(--tw-text-opacity));
3211
3202
  }
3203
+ .text-green-800 {
3204
+ --tw-text-opacity: 1;
3205
+ color: rgba(22, 101, 52, var(--tw-text-opacity));
3206
+ }
3212
3207
  .text-inherit {
3213
3208
  color: inherit;
3214
3209
  }
@@ -3499,7 +3494,7 @@ article.indexTextDS .indexTextHighlighted .link {
3499
3494
  border-bottom-color: var(--color-secondary-ds);
3500
3495
  }
3501
3496
  .counter-reset {
3502
- counter-reset: cnt1728311675728;
3497
+ counter-reset: cnt1728316535820;
3503
3498
  }
3504
3499
  .hyphens-auto {
3505
3500
  -webkit-hyphens: auto;
@@ -3907,7 +3902,7 @@ article.indexTextDS .indexTextHighlighted .link {
3907
3902
  --tw-ring-color: rgba(255, 255, 255, 0.5);
3908
3903
  }
3909
3904
  .-ordered {
3910
- counter-increment: cnt1728311675728 1;
3905
+ counter-increment: cnt1728316535820 1;
3911
3906
  }
3912
3907
  .-ordered::before {
3913
3908
  position: absolute;
@@ -3923,7 +3918,7 @@ article.indexTextDS .indexTextHighlighted .link {
3923
3918
  letter-spacing: .0125em;
3924
3919
  --tw-text-opacity: 1;
3925
3920
  color: rgba(0, 0, 0, var(--tw-text-opacity));
3926
- content: counter(cnt1728311675728);
3921
+ content: counter(cnt1728316535820);
3927
3922
  }
3928
3923
  /*! ****************************/
3929
3924
  /*! DataPolicy stuff */
@@ -8223,7 +8218,7 @@ input[type="radio"]:checked::after {
8223
8218
  .lg\:first-of-type\:pl-0:first-of-type {
8224
8219
  padding-left: 0px;
8225
8220
  }
8226
- .lg\:hover\:underline:hover {
8221
+ .hover\:lg\:underline:hover {
8227
8222
  -webkit-text-decoration-line: underline;
8228
8223
  text-decoration-line: underline;
8229
8224
  }
@@ -20,7 +20,7 @@ AsyncAlpine.init(Alpine)
20
20
 
21
21
  .data('socialSharingHandler', ()=> import('components/social_sharing/socialSharingHandler.alpine.js'))
22
22
  .data('inputHandler', ()=> import('components/forms/inputHandler.alpine.js'))
23
- .data('selectHandler', ()=> import('components/forms/selectHandler.alpine.js'))
23
+ .data('contactForm', ()=> import('components/forms/contactForm.alpine.js'))
24
24
  .start()
25
25
 
26
26
  window.Alpine = Alpine
@@ -52,6 +52,9 @@ Alpine.store('sharingIsOpen', {
52
52
  Alpine.store('sharingBottomPos', {
53
53
  current: '0'
54
54
  })
55
+ Alpine.store('forms', {
56
+ submissionAttempted: []
57
+ })
55
58
  // Initialization of data handlers
56
59
  Alpine.data('mainNavigationHandler', mainNavigationHandler)
57
60
  Alpine.data('overlayHandler', overlayHandler)
@@ -0,0 +1,36 @@
1
+ export default function contactForm(formId) {
2
+ return {
3
+ formInit(){
4
+ this.$store.forms.submissionAttempted[formId] = false;
5
+ console.log("this.$store.forms.submissionAttempted",this.$store.forms.submissionAttempted[formId]);
6
+ },
7
+ clickHandler() {
8
+ console.log('check for Error:',formId);
9
+ const form = this.$refs[formId];
10
+ console.log('form',form);
11
+ const formData = new FormData(form);
12
+ const fields = Array.from(form.elements); // Array of all form fields
13
+
14
+ // Loop through each field, focus it, blur it, and serialize the data
15
+
16
+ if(form.reportValidity()){
17
+ this.submitData();
18
+ } else {
19
+ this.$store.forms.submissionAttempted[formId] = true;
20
+ }
21
+ },
22
+ submitData() {
23
+ const formData = new FormData(this.$refs[formId]);
24
+ // Convert the FormData to a serialized string
25
+ const serializedData = Array.from(formData.entries())
26
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
27
+ .join('&');
28
+
29
+ // Log the serialized form data
30
+ console.log('DATA: ' + serializedData);
31
+ },
32
+ getSubmissionAttempted() {
33
+ return this.$store.forms.submissionAttempted[formId]
34
+ }
35
+ }
36
+ }
@@ -1,14 +1,16 @@
1
- export default function inputHandler(element, errorMandatory, type, errorEmail, prefilledText = '') {
1
+ export default function inputHandler(element, formId, errorMandatory, type, errorEmail, prefilledText = '') {
2
2
  return {
3
3
  [element]: prefilledText,
4
- valid: true,
4
+ valid: false,
5
5
  wasFocused: false,
6
6
  isFocused: false,
7
- validEmail: false,
8
7
  isChecked: false,
8
+ typeMismatch: true,
9
+ valueMissing: true,
10
+
9
11
  errorMessage() {
10
12
  if( type == "email"){
11
- return !this.valid ? errorMandatory : errorEmail
13
+ return this.valueMissing ? errorMandatory : errorEmail
12
14
  }
13
15
  else {
14
16
  return errorMandatory
@@ -17,19 +19,23 @@ export default function inputHandler(element, errorMandatory, type, errorEmail,
17
19
  hideDescription() {
18
20
  switch (type) {
19
21
  case "email":
20
- return Boolean((!this.valid && this.wasFocused && !this.isFocused) || (!this.validEmail && this.wasFocused && !this.isFocused));
22
+ return Boolean((!this.valid && this.wasFocused && !this.isFocused) || (this.typeMismatch && this.wasFocused && !this.isFocused) || (!this.valid && !this.isFocused && this.$store.forms.submissionAttempted[formId]));
21
23
  case "checkbox":
22
- return Boolean(!this.valid && this.wasFocused && !this.isFocused && !this.isChecked);
24
+ return Boolean(!this.valid && this.wasFocused && !this.isFocused && !this.isChecked || (!this.valid && !this.isFocused && this.$store.forms.submissionAttempted[formId]));
25
+ case "select":
26
+ return Boolean((!this.valid && this.wasFocused && !this.isFocused) || (!this.valid && !this.isFocused && this.$store.forms.submissionAttempted[formId]))
23
27
  default:
24
- return Boolean(!this.valid && this.wasFocused && !this.isFocused);
28
+ return Boolean((!this.valid && this.wasFocused && !this.isFocused) || (!this.valid && !this.isFocused && this.$store.forms.submissionAttempted[formId]));
25
29
  }
26
30
  },
27
31
  hideError() {
28
- return Boolean(!this.hideDescription())
32
+ return Boolean(!this.hideDescription())
29
33
  },
30
- validateEmail() {
31
- var emailRegex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
32
- this.validEmail = emailRegex.test( this[element]);
33
- }
34
+ validateField() {
35
+ var field = document.getElementById(element)
36
+ this.typeMismatch = field.validity.typeMismatch;
37
+ this.valueMissing = field.validity.valueMissing;
38
+ this.valid = field.checkValidity()
39
+ }
34
40
  };
35
41
  }
@@ -1,12 +1,12 @@
1
1
  <div class="relative flex flex-col w-full {{#unless _inGroup}} mb-6 md:mb-12{{/unless}} gap-y-4 md:gap-y-5"
2
2
  ax-load
3
- x-data="inputHandler('input{{nextRandom}}','{{_errorMandatory}}','{{_type}}')"
3
+ x-data="inputHandler('input{{nextRandom}}','{{_formId}}','{{_errorMandatory}}','{{_type}}')"
4
4
  x-ignore
5
5
  >
6
6
  <div class="flex flex-row items-center w-full gap-x-2 md:gap-x-3">
7
7
  <input class="relative self-start flex-shrink-0 w-6 h-6 bg-white border appearance-none cursor-pointer {{~inline-switch _type '["checkbox","radio"]' '[" border-blue-science-hex checked:bg-blue-congress-hex checked:border-transparent"," border-blue-science-hex checked:bg-white checked:border-blue-congress-hex rounded-full",""]'}}"
8
8
  :class="{' border-blue-science-hex': hideError(),'border-red-700': hideDescription() }"
9
- @change="validateInput"
9
+ @change="input{{getRandom}}.checked ? valid = true : valid = false;"
10
10
  x-model="isChecked"
11
11
  id="input{{getRandom}}"
12
12
  {{#if _required}}
@@ -13,7 +13,6 @@
13
13
  {{/if}}
14
14
 
15
15
  {{else}}
16
-
17
16
  <div class="js-wrapper-{{this.name}}">
18
17
  {{#if this.type.isTextarea}}
19
18
  {{~> components/forms/textarea
@@ -27,6 +26,7 @@
27
26
  _required=this.isRequired
28
27
  _maxLength=this.maxLength
29
28
  _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
29
+ _formId=../_formId
30
30
  }}
31
31
  {{else if this.type.isText}}
32
32
  {{~> components/forms/input
@@ -43,6 +43,7 @@
43
43
  _maxLength=this.maxLength
44
44
  _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
45
45
  _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
46
+ _formId=../_formId
46
47
  }}
47
48
  {{else if this.type.isSelect}}
48
49
  {{~> components/forms/select
@@ -53,6 +54,7 @@
53
54
  _items=this.options
54
55
  _required=this.isRequired
55
56
  _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
57
+ _formId=../_formId
56
58
  }}
57
59
  {{else if this.type.isChoice}}
58
60
  {{#if this.isGrouped }}
@@ -66,7 +68,7 @@
66
68
  _multipleChoice=../_multipleChoice
67
69
  _addClass=../_addClass
68
70
  _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
69
-
71
+ _formId=../_formId
70
72
  }}
71
73
  {{else}}
72
74
  {{~> components/forms/choice
@@ -79,6 +81,7 @@
79
81
  _required=this.isRequired
80
82
  _selected= this.options.[0].isSelected
81
83
  _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
84
+ _formId=../_formId
82
85
  }}
83
86
  {{/if}}
84
87
  {{else if this.type.isUpload}}
@@ -89,6 +92,7 @@
89
92
  _multiple=false
90
93
  _required=this.isRequired
91
94
  _locaKeyButton="uploadForm_label_file_button"
95
+ _formId=../_formId
92
96
  }}
93
97
  {{/if}}
94
98
  </div>
@@ -1,19 +1,17 @@
1
1
  <div class=" relative flex flex-col w-full mb-5 {{_wrapperClass}}"
2
- :class="{'animate-shake': hideDescription() }"
3
2
  ax-load
4
- x-data="inputHandler('input{{nextRandom}}','{{_errorMandatory}}',{{#if _isEmail}}'email'{{else}}'{{_type}}'{{/if}},'{{_errorEmail}}','{{#if _formField.forHtmlAttribute}}{{_formField.forHtmlAttribute}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}')"
3
+ x-data="inputHandler('input{{nextRandom}}','{{_formId}}','{{_errorMandatory}}',{{#if _isEmail}}'email'{{else}}'{{_type}}'{{/if}},'{{_errorEmail}}','{{#if _formField.forHtmlAttribute}}{{_formField.forHtmlAttribute}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}')"
4
+ x-init="validateField()"
5
5
  x-ignore
6
6
  >
7
7
  <input class="relative w-full h-12 pt-4 pl-4 text-gray-800 placeholder-transparent bg-white border-blue-500 pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
8
8
  :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
9
9
  x-model="input{{getRandom}}"
10
10
  id="input{{getRandom}}"
11
- x-bind:data-is-valid="valid ? 'true' : 'false'"
12
- {{#if _required}}
13
- @focus="isFocused = true;"
14
- @blur="wasFocused = true; isFocused=false; input{{getRandom}}.length > 0 ? valid = true : valid = false; validateEmail()"
15
- x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false; validateEmail()"
16
- {{/if}}
11
+ x-bind:data-is-valid="valid ? 'true' : 'false'"
12
+ @focus="isFocused = true;"
13
+ @blur="wasFocused = true; isFocused=false; validateField();"
14
+ x-on:keyup ="validateField();"
17
15
  type="{{#if _type}}{{_type}}{{/if}}"
18
16
  name="{{#if _name}}{{_name}}{{/if}}"
19
17
  {{#if _locaKey}}
@@ -61,20 +59,35 @@
61
59
  {{/if}}
62
60
  {{/if}}
63
61
  </label>
64
- {{#if _required}}
65
- <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
66
- {{> components/forms/error_icon _xclass="{'hidden': hideError() }"}}
67
- </div>
68
- {{/if}}
62
+
63
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
64
+ {{> components/forms/error_icon _xclass="{'hidden': hideError() }"}}
65
+ </div>
66
+
69
67
  <div class="flex items-end justify-between h-5 font-heading">
70
68
  {{#if _description}}
71
- <div class="pl-4 text-xs text-gray-500" {{#if _required}}:class="{'hidden': hideDescription() }"{{/if}}>{{_description}}</div>
69
+ <div class="pl-4 text-xs text-gray-500" :class="{'hidden': hideDescription() }">{{_description}}</div>
72
70
  {{/if}}
73
- {{#if _required}}
74
- <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" x-text="errorMessage"></div>
75
- {{/if}}
76
- {{#if _maxLength}}
77
- <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="input{{getRandom}}.length">0</span>/{{_maxLength}}</div>
78
- {{/if~}}
71
+
72
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" x-text="errorMessage"></div>
73
+
74
+ </div>
75
+ <div class="hidden">
76
+ <div class="px-4 py-2 font-bold text-white bg-red-500 rounded-t">
77
+ DEBUG
78
+ </div>
79
+ <div class="px-4 py-3 text-red-700 bg-red-100 border border-t-0 border-red-400 rounded-b">
80
+ <div>isFocused:<span x-text="isFocused" class="font-bold" :class="isFocused ? 'text-green-800' : 'text-red-700'"></span></div>
81
+ <div>wasFocused:<span x-text="wasFocused" class="font-bold" :class="wasFocused ? 'text-green-800' : 'text-red-700'"></span></div>
82
+ <div>valid:<span x-text="valid" class="font-bold" :class="valid ? 'text-green-800' : 'text-red-700'"></span></div>
83
+
84
+ <div>hideDescription:<span x-text="hideDescription()" class="font-bold" :class="hideDescription() ? 'text-green-800' : 'text-red-700'"></span></div>
85
+ <div>hideError:<span x-text="hideError()" class="font-bold" :class="hideError() ? 'text-green-800' : 'text-red-700'"></span></div>
86
+ <div>input.length:<span x-text="input{{getRandom}}.length " class="font-bold" ></span></div>
87
+ <div>input:<span x-text="input{{getRandom}}" class="font-bold" ></span></div>
88
+ <div>errorMessage:<span x-text="errorMessage" class="font-bold" ></span></div>
89
+ <div>valueMissing:<span x-text="valueMissing" class="font-bold" ></span></div>
90
+ <div>typeMismatch:<span x-text="typeMismatch" class="font-bold" ></span></div>
91
+ </div>
79
92
  </div>
80
93
  </div>
@@ -1,6 +1,6 @@
1
1
  <div class="relative flex flex-col w-full mb-5 "
2
2
  ax-load
3
- x-data="selectHandler('select{{nextRandom}}')"
3
+ x-data="inputHandler('select{{nextRandom}}', '{{_formId}}','select')"
4
4
  x-ignore
5
5
  >
6
6
  <select
@@ -43,17 +43,12 @@
43
43
  ">
44
44
  {{_label}}{{#if _required}}*{{/if}}
45
45
  </label>
46
- {{#if _required}}
47
- <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-14">
48
- {{> components/forms/error_icon _xclass="{'hidden': hideError() }"}}
49
- </div>
50
- {{/if}}
51
46
  <div class="flex items-end justify-between h-5 font-heading">
52
47
  {{#if _description}}
53
- <div class="pl-4 text-xs text-gray-500 " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
48
+ <div class="pl-4 text-xs text-gray-500 " :class="{'hidden': hideDescription()}">{{_description}}</div>
54
49
  {{/if}}
55
50
  {{#if _required}}
56
- <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
51
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" >{{_errorMessage}}</div>
57
52
  {{/if}}
58
53
  </div>
59
54
  <div class="absolute right-0 p-4 py-3 transform border-l peer-focus:border-r peer-focus:border-l-0 pointer-events-none top-1.5 peer-focus:rotate-180">
@@ -1,6 +1,9 @@
1
1
  <div class="relative flex flex-col w-full mb-5"
2
- x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHtmlContent}}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' , valid: true, wasFocused: false, isFocused: false}"
3
- :class="{'animate-shake': !valid && wasFocused && !isFocused }">
2
+ ax-load
3
+ x-data="inputHandler('textarea{{nextRandom}}','{{_formId}}','{{_errorMandatory}}','textarea','','{{#if _formField.isValid}}{{{_formField.forHtmlContent}}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}')"
4
+ x-init="validateField()"
5
+ x-ignore
6
+ >
4
7
  <div class="w-full h-4 bg-white"></div>
5
8
  <textarea
6
9
  x-model="textarea{{getRandom}}"
@@ -33,7 +36,7 @@ x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHt
33
36
  {{#if _required}}required{{/if}}
34
37
  class="relative w-full px-4 pb-px text-gray-800 placeholder-transparent bg-white border-blue-500 min-h-12 peer border-y focus:border-b-2 focus:pb-0 border-t-transparent focus:outline-none"
35
38
  {{#if _required}}
36
- :class="{'border-blue-500': valid || !wasFocused || isFocused,'border-red-500': !valid && wasFocused && !isFocused}"
39
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
37
40
  {{/if}}
38
41
  >{{~#if _formField.isValid~}}
39
42
  {{{_formField.forHtmlContent}}}
@@ -57,16 +60,16 @@ x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHt
57
60
  {{/if}}
58
61
  </label>
59
62
  {{#if _required}}
60
- <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
61
- {{> components/forms/error_icon _xclass="{'hidden': valid || !wasFocused || isFocused }"}}
62
- </div>
63
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
64
+ {{> components/forms/error_icon _xclass="{'hidden': hideError() }"}}
65
+ </div>
63
66
  {{/if}}
64
67
  <div class="flex items-end justify-between h-5 font-heading">
65
68
  {{#if _description}}
66
- <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
69
+ <div class="pl-4 text-xs text-gray-500" :class="{'hidden': hideDescription() }">{{_description}}</div>
67
70
  {{/if}}
68
71
  {{#if _required}}
69
- <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
72
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" >{{_errorMessage}}</div>
70
73
  {{/if}}
71
74
  {{#if _maxLength}}
72
75
  <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="textarea{{getRandom}}.length">0</span>/{{_maxLength}}</div>
@@ -6,59 +6,37 @@
6
6
  {{this.title}}
7
7
  </h3>
8
8
 
9
- <form x-data="contactForm()"
10
-
9
+ <form
10
+ x-ref="form{{nextRandom}}"
11
+ ax-load
12
+ x-data="contactForm('form{{getRandom}}')"
13
+ x-init="formInit()"
14
+ x-ignore
15
+
11
16
  @submit.prevent="submitData"
12
- x-ref="contactFormRef"
17
+ id="form{{getRandom}}"
13
18
  class="relative flex flex-col justify-center overflow-hidden group"
14
- id="form--{{nextRandom}}"
15
19
  action="{{this.url}}"
16
20
  method="post"
17
21
  enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}"
18
- accept-charset="utf-8" >
19
- {{> components/forms/fields }}
22
+ accept-charset="utf-8"
23
+
24
+ >
25
+
26
+ <div class="">
27
+ <div class="px-4 py-2 font-bold text-white bg-red-500 rounded-t">
28
+ DEBUG
29
+ </div>
30
+ <div class="px-4 py-3 text-red-700 bg-red-100 border border-t-0 border-red-400 rounded-b">
31
+ <div>submissionAttempted[form{{getRandom}}]:<span x-text="getSubmissionAttempted()" class="font-bold" :class="getSubmissionAttempted() ? 'text-green-800' : 'text-red-700'"></span></div>
32
+ </div>
33
+ </div>
34
+ {{> components/forms/fields _formId=(joinStrings 'form' (getRandom)) }}
20
35
 
21
36
  {{> components/forms/controls }}
22
- </form>
23
- <script>
24
- function contactForm() {
25
- return {
26
- formData: {
27
- name: '',
28
- email: '',
29
- message: ''
30
- },
31
- clickHandler() {
32
- console.log('check for Error ');
33
- const form = this.$refs.contactFormRef;
34
- const formData = new FormData(form);
35
- const fields = Array.from(form.elements); // Array of all form fields
36
37
 
37
- // Loop through each field, focus it, blur it, and serialize the data
38
- fields.forEach((field) => {
39
- if (field.type !== 'submit') { // Skip the submit button
40
- field.focus(); // Focus the field
41
- field.blur(); // Immediately unfocus (blur) the field
42
- }
43
- });
44
- if(form.reportValidity()){
45
- this.submitData();
46
- }
47
-
48
- },
49
- submitData() {
50
- const formData = new FormData(this.$refs.contactFormRef);
51
- // Convert the FormData to a serialized string
52
- const serializedData = Array.from(formData.entries())
53
- .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
54
- .join('&');
55
-
56
- // Log the serialized form data
57
- console.log('DATA: ' + serializedData);
58
- }
59
- }
60
- }
61
- </script>
38
+ </form>
39
+
62
40
  {{/components/forms/backgroundBox }}
63
41
  {{~else~}}
64
42
  {{> content/webform/components/webform _addClass="print:hidden copytext__clearBox marginTrailer--m"}}
@@ -1,3 +1,3 @@
1
- <li class="sb-brand-navigation-item h-8 {{#if @first }}-ml-3 {{/if}}{{#if this.selected}} h-10 md:h-8 font-bold text-brandnav-pseudo {{/if}}cursor-pointer inline-block lg:hover:underline active:font-bold active:text-primary">
1
+ <li class="sb-brand-navigation-item h-8 {{#if @first }}-ml-3 {{/if}}{{#if this.selected}} h-10 md:h-8 font-bold text-brandnav-pseudo {{/if}}cursor-pointer inline-block hover:lg:underline active:font-bold active:text-primary">
2
2
  <a class="{{if (isUserConsentNeeded (resourceUrl "index.html" _site=this.site)) 'js-user-consent-needed ' ''}}link-focus-inset leading-[34px] items-center flex-col px-3 {{#if this.selected }}relative {{/if}}md:flex-row js-load w-max flex justify-center {{#if this.selected}} -currentBrand {{/if}}" aria-label="{{this.name}}" href="{{resourceUrl "index.html" _site=this.site}}"{{#if this.extern}} target="_blank" rel="noopener noreferrer"{{/if}} data-hr-click-tracking='{"settings": [{"type": "uxNavigation", "secondLevelId": 1, "clickLabel": "Brandnavigation::{{this.text}}-Link geklickt"}]}'>{{this.text}}</a>
3
3
  </li>
@@ -2,7 +2,7 @@
2
2
  <li x-data="dropdown"
3
3
  @click.outside="dropped = false"
4
4
  @close-servicemenu.window="dropped = false"
5
- :class="dropped ? 'border-b-0 lg:bg-white lg:text-primary ' : ' lg:hover:underline'"
5
+ :class="dropped ? 'border-b-0 lg:bg-white lg:text-primary ' : ' hover:lg:underline'"
6
6
  class="flex flex-wrap justify-start order-2 w-full list-none transition-[max-height] md:transition-none duration-1000 ease-out border-b border-navigation-border-color text-navigation-text sb-section-navigation-item first:lg:-ml-4 md:pl-0 lg:last:pr-8 lg:first:pl-0 first:font-normal last:border-b-0 lg:border-0 lg:w-auto bg-navigation-bg lg:rounded-t">
7
7
 
8
8
  {{#if this.isCluster ~}}
@@ -8,7 +8,7 @@
8
8
  @close-servicemenu.window="dropped = false; $store.serviceNavIsOpen = false"
9
9
  x-data="dropdown"
10
10
  id="{{getRandom}}"
11
- class="js-load flex flex-col items-center justify-center h-full px-4 text-left lg:justify-start lg:px-3 lg:pt-1 lg:hover:underline lg:relative lg:rounded-t lg:border-0 lg:left-0 text-navigation-icons link-focus-inset {{#if this.selected}}-currentService{{/if}}"
11
+ class="js-load flex flex-col items-center justify-center h-full px-4 text-left lg:justify-start lg:px-3 lg:pt-1 hover:lg:underline lg:relative lg:rounded-t lg:border-0 lg:left-0 text-navigation-icons link-focus-inset {{#if this.selected}}-currentService{{/if}}"
12
12
 
13
13
  :class="dropped ? 'bg-white fill-current text-primary lg:border-0 lg:underline' : ''"
14
14
  aria-owns="flyout-{{getRandom}}"
@@ -1,12 +1,12 @@
1
1
  <div class="relative flex flex-col w-full {{#unless _inGroup}} mb-6 md:mb-12{{/unless}} gap-y-4 md:gap-y-5"
2
2
  ax-load
3
- x-data="inputHandler('input{{nextRandom}}','{{_errorMandatory}}','{{_type}}')"
3
+ x-data="inputHandler('input{{nextRandom}}','{{_formId}}','{{_errorMandatory}}','{{_type}}')"
4
4
  x-ignore
5
5
  >
6
6
  <div class="flex flex-row items-center w-full gap-x-2 md:gap-x-3">
7
7
  <input class="relative self-start flex-shrink-0 w-6 h-6 bg-white border appearance-none cursor-pointer {{~inline-switch _type '["checkbox","radio"]' '[" border-blue-science-hex checked:bg-blue-congress-hex checked:border-transparent"," border-blue-science-hex checked:bg-white checked:border-blue-congress-hex rounded-full",""]'}}"
8
8
  :class="{' border-blue-science-hex': hideError(),'border-red-700': hideDescription() }"
9
- @change="validateInput"
9
+ @change="input{{getRandom}}.checked ? valid = true : valid = false;"
10
10
  x-model="isChecked"
11
11
  id="input{{getRandom}}"
12
12
  {{#if _required}}