-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IBX-2360: Validation content type create/edit #334
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,16 +1,25 @@ | ||||||||||||||
(function(global, doc, ibexa, Routing, Translator) { | ||||||||||||||
const TIMEOUT_REMOVE_PLACEHOLDERS = 1500; | ||||||||||||||
const SELECTOR_INPUTS_TO_VALIDATE = '.ibexa-input[required]:not([disabled]):not([hidden])'; | ||||||||||||||
let targetContainer = null; | ||||||||||||||
let sourceContainer = null; | ||||||||||||||
let currentDraggedItem = null; | ||||||||||||||
let draggedItemPosition = null; | ||||||||||||||
let isEditFormValid = false; | ||||||||||||||
const draggableGroups = []; | ||||||||||||||
const token = doc.querySelector('meta[name="CSRF-Token"]').content; | ||||||||||||||
const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content; | ||||||||||||||
const editForm = doc.querySelector('.ibexa-content-type-edit-form'); | ||||||||||||||
const inputsToValidate = editForm.querySelectorAll(SELECTOR_INPUTS_TO_VALIDATE); | ||||||||||||||
const sectionsNode = doc.querySelector('.ibexa-content-type-edit__sections'); | ||||||||||||||
const filterFieldInput = doc.querySelector('.ibexa-available-field-types__sidebar-filter'); | ||||||||||||||
const popupMenuElement = sectionsNode.querySelector('.ibexa-popup-menu'); | ||||||||||||||
const addGroupTriggerBtn = sectionsNode.querySelector('.ibexa-content-type-edit__add-field-definitions-group-btn'); | ||||||||||||||
const noFieldsAddedError = Translator.trans( | ||||||||||||||
/*@Desc("You have to add at least one field definition")*/ 'content_type.edit.error.no_added_fields_definition', | ||||||||||||||
{}, | ||||||||||||||
'content_type', | ||||||||||||||
); | ||||||||||||||
const endpoints = { | ||||||||||||||
add: { | ||||||||||||||
actionName: 'add_field_definition', | ||||||||||||||
|
@@ -80,7 +89,9 @@ | |||||||||||||
|
||||||||||||||
const fieldGroupInput = fieldNode.querySelector('.ibexa-input--field-group'); | ||||||||||||||
const removeFieldsBtn = fieldNode.querySelectorAll('.ibexa-collapse__extra-action-button--remove-field-definitions'); | ||||||||||||||
const inputsToValidate = fieldNode.querySelectorAll(SELECTOR_INPUTS_TO_VALIDATE); | ||||||||||||||
|
||||||||||||||
inputsToValidate.forEach(attachValidateEvents); | ||||||||||||||
removeDragPlaceholders(); | ||||||||||||||
fieldGroupInput.value = fieldsGroupId; | ||||||||||||||
targetContainer.insertBefore(fieldNode, targetPlace); | ||||||||||||||
|
@@ -132,7 +143,6 @@ | |||||||||||||
}); | ||||||||||||||
}; | ||||||||||||||
const afterChangeGroup = () => { | ||||||||||||||
const submitBtn = doc.querySelector('.ibexa-content-type-edit__publish-content-type'); | ||||||||||||||
const fieldsDefinitionCount = doc.querySelectorAll('.ibexa-collapse--field-definition').length; | ||||||||||||||
const groups = doc.querySelectorAll('.ibexa-collapse--field-definitions-group'); | ||||||||||||||
const itemsAction = doc.querySelectorAll('.ibexa-content-type-edit__add-field-definitions-group .ibexa-popup-menu__item-content'); | ||||||||||||||
|
@@ -158,8 +168,6 @@ | |||||||||||||
doc.querySelectorAll('.ibexa-collapse--field-definition').forEach((fieldDefinition, index) => { | ||||||||||||||
fieldDefinition.querySelector('.ibexa-input--position').value = index; | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
submitBtn.toggleAttribute('disabled', !fieldsDefinitionCount); | ||||||||||||||
}; | ||||||||||||||
const addField = () => { | ||||||||||||||
if (!sourceContainer.classList.contains('ibexa-available-field-types__list')) { | ||||||||||||||
|
@@ -253,7 +261,60 @@ | |||||||||||||
}) | ||||||||||||||
.catch(ibexa.helpers.notification.showErrorNotification); | ||||||||||||||
}; | ||||||||||||||
const validateInput = (input) => { | ||||||||||||||
const isInputEmpty = !input.value; | ||||||||||||||
const field = input.closest('.form-group'); | ||||||||||||||
const labelNode = field.querySelector('.ibexa-label'); | ||||||||||||||
const errorNode = field.querySelector('.ibexa-form-error'); | ||||||||||||||
|
||||||||||||||
input.classList.toggle('is-invalid', isInputEmpty); | ||||||||||||||
|
||||||||||||||
if (errorNode) { | ||||||||||||||
const fieldName = labelNode.innerHTML; | ||||||||||||||
const errorMessage = ibexa.errors.emptyField.replace('{fieldName}', fieldName); | ||||||||||||||
|
||||||||||||||
errorNode.innerHTML = isInputEmpty ? errorMessage : ''; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
if (isEditFormValid && isInputEmpty) { | ||||||||||||||
isEditFormValid = false; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that checking whether There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. solved in private conversation |
||||||||||||||
} | ||||||||||||||
}; | ||||||||||||||
const validateForm = () => { | ||||||||||||||
const inputsToValidate = editForm.querySelectorAll(SELECTOR_INPUTS_TO_VALIDATE); | ||||||||||||||
const fieldDefinitionsStatuses = {}; | ||||||||||||||
|
||||||||||||||
isEditFormValid = true; | ||||||||||||||
|
||||||||||||||
inputsToValidate.forEach((input) => { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: could this be iterated field definition by field definition without There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. solved in private conversation |
||||||||||||||
const fieldDefinition = input.closest('.ibexa-collapse--field-definition'); | ||||||||||||||
|
||||||||||||||
if (fieldDefinition) { | ||||||||||||||
const { fieldDefinitionIdentifier } = fieldDefinition.dataset; | ||||||||||||||
const isInputEmpty = !input.value; | ||||||||||||||
|
||||||||||||||
if (!fieldDefinitionsStatuses[fieldDefinitionIdentifier]) { | ||||||||||||||
fieldDefinitionsStatuses[fieldDefinitionIdentifier] = []; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
fieldDefinitionsStatuses[fieldDefinitionIdentifier].push(isInputEmpty); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
validateInput(input); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
Object.entries(fieldDefinitionsStatuses).forEach(([fieldDefinitionIdentifier, inputsStatus]) => { | ||||||||||||||
const isFieldDefinitionValid = inputsStatus.every((hasError) => !hasError); | ||||||||||||||
const fieldDefinitionNode = doc.querySelector(`[data-field-definition-identifier="${fieldDefinitionIdentifier}"]`); | ||||||||||||||
|
||||||||||||||
fieldDefinitionNode.classList.toggle('is-invalid', !isFieldDefinitionValid); | ||||||||||||||
}); | ||||||||||||||
}; | ||||||||||||||
const attachValidateEvents = (input) => { | ||||||||||||||
input.addEventListener('change', () => validateForm(input), false); | ||||||||||||||
input.addEventListener('blur', () => validateForm(input), false); | ||||||||||||||
input.addEventListener('input', () => validateForm(input), false); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And AFAICS |
||||||||||||||
}; | ||||||||||||||
class FieldDefinitionDraggable extends ibexa.core.Draggable { | ||||||||||||||
onDrop(event) { | ||||||||||||||
targetContainer = event.currentTarget; | ||||||||||||||
|
@@ -368,20 +429,25 @@ | |||||||||||||
draggableGroups.push(draggable); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
doc.querySelector('.ibexa-btn--save-content-type').addEventListener( | ||||||||||||||
'click', | ||||||||||||||
() => { | ||||||||||||||
if (doc.querySelectorAll('.ibexa-collapse--field-definition').length) { | ||||||||||||||
return; | ||||||||||||||
inputsToValidate.forEach(attachValidateEvents); | ||||||||||||||
|
||||||||||||||
editForm.addEventListener( | ||||||||||||||
'submit', | ||||||||||||||
(event) => { | ||||||||||||||
const fieldDefinitionsCount = doc.querySelectorAll('.ibexa-collapse--field-definition').length; | ||||||||||||||
|
||||||||||||||
validateForm(); | ||||||||||||||
|
||||||||||||||
if (!fieldDefinitionsCount) { | ||||||||||||||
isEditFormValid = false; | ||||||||||||||
Comment on lines
+438
to
+439
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My guess is you put this check here instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. solved in private conversation |
||||||||||||||
ibexa.helpers.notification.showErrorNotification(noFieldsAddedError); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
ibexa.helpers.notification.showErrorNotification( | ||||||||||||||
Translator.trans( | ||||||||||||||
/*@Desc("You have to add at least one field definition")*/ 'content_type.edit.error.no_added_fields_definition', | ||||||||||||||
{}, | ||||||||||||||
'content_type', | ||||||||||||||
), | ||||||||||||||
); | ||||||||||||||
if (!isEditFormValid) { | ||||||||||||||
event.preventDefault(); | ||||||||||||||
|
||||||||||||||
return; | ||||||||||||||
} | ||||||||||||||
}, | ||||||||||||||
false, | ||||||||||||||
); | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we don't have sonar/eslint checks in this repo yet, but it seems that it overrides the variable from the upper scope?