|
371 | 371 | const validateInput = (input) => {
|
372 | 372 | const isInputEmpty = !input.value;
|
373 | 373 | const field = input.closest('.form-group');
|
374 |
| - const labelNode = field.querySelector('.ibexa-label'); |
375 |
| - const errorNode = field.querySelector('.ibexa-form-error'); |
| 374 | + const labelNode = field?.querySelector('.ibexa-label'); |
| 375 | + const errorNode = field?.querySelector('.ibexa-form-error'); |
376 | 376 |
|
377 | 377 | input.classList.toggle('is-invalid', isInputEmpty);
|
378 | 378 |
|
379 |
| - if (errorNode) { |
| 379 | + if (errorNode && labelNode) { |
380 | 380 | errorNode.innerHTML = '';
|
381 | 381 |
|
382 | 382 | if (isInputEmpty) {
|
|
390 | 390 |
|
391 | 391 | isEditFormValid = isEditFormValid && !isInputEmpty;
|
392 | 392 | };
|
| 393 | + const validateMatrixColumns = (columnSettingsNode) => { |
| 394 | + const columns = columnSettingsNode.querySelectorAll('.ibexa-matrix-settings__column'); |
| 395 | + const requiredInputs = columnSettingsNode.querySelectorAll('.ibexa-input[required]'); |
| 396 | + const hasAddedColumns = columns.length > 0; |
| 397 | + const hasEmptyRequiredInputs = [...requiredInputs].some((input) => !input.value); |
| 398 | + const isValid = hasAddedColumns && !hasEmptyRequiredInputs; |
| 399 | + const errorNode = columnSettingsNode.querySelector('.ibexa-form-error'); |
| 400 | + |
| 401 | + errorNode.toggleAttribute('hidden', hasAddedColumns); |
| 402 | + |
| 403 | + return isValid; |
| 404 | + }; |
393 | 405 | const validateForm = () => {
|
394 | 406 | const fieldDefinitionsStatuses = {};
|
| 407 | + const matrixColumnsSettingsNodes = doc.querySelectorAll('.ibexa-matrix-settings__columns'); |
395 | 408 |
|
396 | 409 | isEditFormValid = true;
|
397 | 410 | inputsToValidate = editForm.querySelectorAll(SELECTOR_INPUTS_TO_VALIDATE);
|
|
403 | 416 | const { fieldDefinitionIdentifier } = fieldDefinition.dataset;
|
404 | 417 | const isInputEmpty = !input.value;
|
405 | 418 |
|
406 |
| - if (!fieldDefinitionsStatuses[fieldDefinitionIdentifier]) { |
407 |
| - fieldDefinitionsStatuses[fieldDefinitionIdentifier] = []; |
408 |
| - } |
409 |
| - |
| 419 | + fieldDefinitionsStatuses[fieldDefinitionIdentifier] ??= []; |
410 | 420 | fieldDefinitionsStatuses[fieldDefinitionIdentifier].push(isInputEmpty);
|
411 | 421 | }
|
412 | 422 |
|
413 | 423 | validateInput(input);
|
414 | 424 | });
|
415 | 425 |
|
| 426 | + matrixColumnsSettingsNodes.forEach((columnSettingsNode) => { |
| 427 | + const fieldDefinition = columnSettingsNode.closest('.ibexa-collapse--field-definition'); |
| 428 | + const { fieldDefinitionIdentifier } = fieldDefinition.dataset; |
| 429 | + const hasError = !validateMatrixColumns(columnSettingsNode); |
| 430 | + |
| 431 | + fieldDefinitionsStatuses[fieldDefinitionIdentifier] ??= []; |
| 432 | + fieldDefinitionsStatuses[fieldDefinitionIdentifier].push(hasError); |
| 433 | + isEditFormValid = isEditFormValid && !hasError; |
| 434 | + }); |
| 435 | + |
416 | 436 | Object.entries(fieldDefinitionsStatuses).forEach(([fieldDefinitionIdentifier, inputsStatus]) => {
|
417 | 437 | const isFieldDefinitionValid = inputsStatus.every((hasError) => !hasError);
|
418 | 438 | const fieldDefinitionNode = doc.querySelector(`[data-field-definition-identifier="${fieldDefinitionIdentifier}"]`);
|
|
427 | 447 | };
|
428 | 448 | const scrollToInvalidInput = () => {
|
429 | 449 | const firstInvalidInput = editForm.querySelector('.ibexa-input.is-invalid');
|
430 |
| - const fieldDefinition = firstInvalidInput.closest('.ibexa-collapse--field-definition'); |
431 |
| - const scrollToNode = fieldDefinition ?? firstInvalidInput; |
| 450 | + const firstInvalidFieldDefinition = editForm.querySelector('.ibexa-collapse--field-definition.is-invalid'); |
| 451 | + const scrollToNode = firstInvalidFieldDefinition ?? firstInvalidInput; |
432 | 452 |
|
433 | 453 | scrollToNode.scrollIntoView({ behavior: 'smooth' });
|
434 | 454 | };
|
|
629 | 649 | draggableGroups.push(draggable);
|
630 | 650 | });
|
631 | 651 |
|
| 652 | + doc.body.addEventListener('ibexa-fieldtype-matrix:added-column', (event) => { |
| 653 | + const { columnNode } = event.detail; |
| 654 | + const inputs = columnNode.querySelectorAll('.ibexa-input[required]'); |
| 655 | + |
| 656 | + inputs.forEach((input) => { |
| 657 | + attachValidateEvents(input); |
| 658 | + }); |
| 659 | + }); |
| 660 | + |
632 | 661 | fieldDefinitionsGroups.forEach((group) => group.addEventListener('click', () => setActiveGroup(group), false));
|
633 | 662 | inputsToValidate.forEach(attachValidateEvents);
|
634 | 663 |
|
|
0 commit comments