Skip to content

Commit 87a9710

Browse files
committed
Merge branch '4.x' into 5.x
* 4.x: Show an error indicator and auto-expand collapsed fieldsets that contain fields with errors Allow to set a custom response in all AfterEntity events
2 parents 085b6c4 + 002a427 commit 87a9710

17 files changed

Lines changed: 300 additions & 28 deletions

File tree

assets/css/easyadmin-theme/forms.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,16 @@ label.form-check-label {
472472
margin-block-start: 6px;
473473
}
474474

475+
.form-fieldset-title-content .badge-danger {
476+
margin-inline-start: 8px;
477+
}
478+
479+
.form-fieldset.has-fieldset-error {
480+
border: 1px solid var(--form-input-error-border-color);
481+
border-radius: var(--border-radius);
482+
box-shadow: var(--form-input-error-shadow);
483+
}
484+
475485
/* using CSS Grid is needed for a smooth collapse animation */
476486
.form-fieldset-body {
477487
display: grid;

assets/js/form.js

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,17 @@ class Form {
8585
button.addEventListener('click', function onSubmitButtonsClick(clickEvent) {
8686
let formHasErrors = false;
8787

88-
// Remove all error counter badges
88+
// remove all error counter badges (tabs and fieldsets)
8989
document
90-
.querySelectorAll('.form-tabs-tablist .nav-item .badge-danger.badge')
90+
.querySelectorAll(
91+
'.form-tabs-tablist .nav-item .badge-danger.badge, .form-fieldset-title-content .badge-danger.badge'
92+
)
9193
.forEach((badge) => {
9294
badge.parentElement.removeChild(badge);
9395
});
96+
document.querySelectorAll('.form-fieldset.has-fieldset-error').forEach((fieldset) => {
97+
fieldset.classList.remove('has-fieldset-error');
98+
});
9499

95100
if (null !== form.getAttribute('novalidate')) {
96101
return;
@@ -100,11 +105,10 @@ class Form {
100105
if (!input.disabled && !input.validity.valid) {
101106
formHasErrors = true;
102107

103-
// Visual feedback for tabs
104-
// Adding a badge with a error count next to the tab label
108+
// visual feedback for tabs: adding a badge with a error count next to the tab label
105109
const formTab = input.closest('div.tab-pane');
106110
if (formTab) {
107-
// Match tab link either by "data-bs-target" attribute or by href linking to the id anchor
111+
// match tab link either by "data-bs-target" attribute or by href linking to the id anchor
108112
const navLinkTab = document.querySelector(
109113
`[data-bs-target="#${formTab.id}"], a[href="#${formTab.id}"]`
110114
);
@@ -114,10 +118,10 @@ class Form {
114118

115119
const badge = navLinkTab.querySelector('.badge');
116120
if (badge) {
117-
// Increment number of error
121+
// increment number of error
118122
badge.textContent = (Number.parseInt(badge.textContent) + 1).toString();
119123
} else {
120-
// Create a new badge
124+
// create a new badge
121125
const newErrorBadge = document.createElement('span');
122126
newErrorBadge.classList.add('badge', 'badge-danger');
123127
newErrorBadge.textContent = '1';
@@ -126,7 +130,28 @@ class Form {
126130
}
127131
}
128132

129-
// Visual feedback for group
133+
// visual feedback for fieldsets
134+
const formFieldset = input.closest('div.form-fieldset');
135+
if (formFieldset) {
136+
const fieldsetTitleContent =
137+
formFieldset.querySelector('.form-fieldset-title-content');
138+
139+
formFieldset.classList.add('has-fieldset-error');
140+
141+
if (fieldsetTitleContent) {
142+
const badge = fieldsetTitleContent.querySelector('.badge');
143+
if (badge) {
144+
badge.textContent = (Number.parseInt(badge.textContent) + 1).toString();
145+
} else {
146+
const newErrorBadge = document.createElement('span');
147+
newErrorBadge.classList.add('badge', 'badge-danger');
148+
newErrorBadge.textContent = '1';
149+
fieldsetTitleContent.appendChild(newErrorBadge);
150+
}
151+
}
152+
}
153+
154+
// visual feedback for group
130155
const formGroup = input.closest('div.form-group');
131156
formGroup.classList.add('has-error');
132157

@@ -149,6 +174,25 @@ class Form {
149174
that.#setTabAsActive(firstTabWithErrors.id);
150175
}
151176

177+
// auto-expand all collapsed fieldsets with errors
178+
document
179+
.querySelectorAll('.form-fieldset.has-fieldset-error')
180+
.forEach((fieldsetWithErrors) => {
181+
const collapsedBody = fieldsetWithErrors.querySelector(
182+
'.form-fieldset-body.collapse:not(.show)'
183+
);
184+
if (collapsedBody) {
185+
const Collapse = bootstrap.Collapse;
186+
new Collapse(collapsedBody, { toggle: true });
187+
const collapseToggle =
188+
fieldsetWithErrors.querySelector('.form-fieldset-collapse');
189+
if (collapseToggle) {
190+
collapseToggle.classList.remove('collapsed');
191+
collapseToggle.setAttribute('aria-expanded', 'true');
192+
}
193+
}
194+
});
195+
152196
document.dispatchEvent(
153197
new CustomEvent('ea.form.error', {
154198
cancelable: true,
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/entrypoints.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
"entrypoints": {
33
"app": {
44
"css": [
5-
"/app.98533a09.css"
5+
"/app.912702e5.css"
66
],
77
"js": [
88
"/app.e8e4fe24.js"
99
]
1010
},
1111
"form": {
1212
"js": [
13-
"/form.5bccac01.js"
13+
"/form.4f66b3e8.js"
1414
]
1515
},
1616
"page-layout": {

public/form.4f66b3e8.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)