diff --git a/fiches/static/fiches/js/forms.js b/fiches/static/fiches/js/forms.js index ed5dd8e..9890442 100644 --- a/fiches/static/fiches/js/forms.js +++ b/fiches/static/fiches/js/forms.js @@ -1,211 +1,7 @@ "use strict"; -// function countSubEntries(formEntryElement) { -// return formEntryElement -// .querySelectorAll(".form-sub-entry") -// .length; -// } - -// function reindexSubEntries(formEntryElement) { -// const subEntryElements = [...formEntryElement.querySelectorAll(".form-sub-entry")]; -// for (let [subEntryIndex, subEntryElement] of subEntryElements.entries()) { -// subEntryElement.setAttribute("data-sub-entry-index", subEntryIndex); -// } -// } - -// function checkSubEntryDeleteCheckbox(subEntryElement) { -// const checkboxElement = [...subEntryElement.querySelectorAll('input[type="checkbox"')] -// .filter(element => element.className.endsWith("DELETE")); - -// if (checkboxElement.length >= 1) { -// checkboxElement.checked = true; -// } -// } - - -// function createAndAppendNewSubEntryButton(formEntryElement) { -// const buttonElement = document.createElement("button"); -// buttonElement.setAttribute("type", "button"); -// buttonElement.classList.add("add-sub-entry-button"); - -// // TODO: handle the translation of this button -// buttonElement.textContent = "New entry"; - -// buttonElement.addEventListener("click", event => { -// // Clone one of the sub-entries, make it look like it is new, and reindex the sub-entries -// // This works because there is always at least one sub-entry to clone -// const someSubEntryElement = formEntryElement.querySelector(".form-sub-entry"); -// const clonedSubEntryElement = someSubEntryElement.cloneNode(true); - -// for (let inputElement of clonedSubEntryElement.querySelectorAll("input")) { -// inputElement.value = ""; -// } - -// // Since the cloned removal button has lost its click event listener, -// // it should be created again from scratch -// clonedSubEntryElement -// .querySelector(".remove-button") -// .remove(); -// createAndAppendSubEntryDeletionButton(clonedSubEntryElement); - -// formEntryElement.insertBefore(clonedSubEntryElement, buttonElement); -// reindexSubEntries(formEntryElement); -// }); - -// formEntryElement.append(buttonElement); -// } - -// function createAndAppendSubEntryDeletionButton(subEntryElement) { -// const buttonElement = document.createElement("button"); -// buttonElement.setAttribute("type", "button"); -// buttonElement.classList.add("remove-button"); - -// buttonElement.addEventListener("click", event => { -// const parentFormEntryElement = subEntryElement.parentNode; - -// // If this sub-entry is the last one, only clear its input fields -// // Otherwise, remove the node from the form entry -// if (countSubEntries(parentFormEntryElement) === 1) { -// subEntryElement -// .querySelectorAll("input") -// .value = ""; -// } -// else { -// subEntryElement.remove(); -// reindexSubEntries(parentFormEntryElement); -// } -// }); - -// subEntryElement.append(buttonElement); -// } - -// function createSubEntryElement() { -// const subEntryElement = document.createElement("div"); -// subEntryElement.classList.add("form-sub-entry"); - -// return subEntryElement; -// } - - -// ---------------------------------------------------------------------------- - - -// TODO: remove this hacky function by directly grouping all the elements of each sub-entry -// directly in Django (e.g.
elements with a "form-sub-entry" class) -// function transformFormEntryWithSubEntries(formEntryElement) { -// // Nb. successive children to group together -// // (6 - 4 = 2, since the checkbox and all the label are ignored) -// const nbSuccessiveElementsPerSubEntry = 2; - -// const subEntryElements = []; -// let currentSubEntryElement = createSubEntryElement(); -// let nbChildrenOfCurrentSubEntry = 0; -// subEntryElements.push(currentSubEntryElement); - -// const formEntryChildNodes = [...formEntryElement.childNodes]; -// let firstElementHasBeenSkipped = false; - -// for (let childNode of formEntryChildNodes) { -// // Ignore non-element nodes -// if (childNode.nodeType !== Node.ELEMENT_NODE) { -// continue; -// } - -// // Skip the first element (it should be the label of the whole form entry) -// if (!firstElementHasBeenSkipped) { -// firstElementHasBeenSkipped = true; -// continue; -// } - -// // Ignore hidden form elements -// if (childNode.hasAttribute("type") -// && childNode.getAttribute("type") === "hidden") { -// continue; -// } - -// // Remove the checkbox to delete an entry and its label -// if (childNode.hasAttribute("id") -// && childNode.getAttribute("id").endsWith("DELETE")) { -// //childNode.remove(); -// continue; -// } - -// if (childNode.hasAttribute("for") -// && childNode.getAttribute("for").endsWith("DELETE")) { -// //childNode.remove(); -// continue; -// } - -// // Remove all the remaining labels -// // (they should be replaced by placeholder text within the input) -// if (childNode.nodeName === "LABEL") { -// childNode.remove(); -// continue; -// } - -// // If the current sub-entry is full, -// // create a new sub-entry (for the remaining child nodes) -// if (nbChildrenOfCurrentSubEntry === nbSuccessiveElementsPerSubEntry) { -// currentSubEntryElement = createSubEntryElement(); -// nbChildrenOfCurrentSubEntry = 0; -// subEntryElements.push(currentSubEntryElement); -// } - -// // Fill the current sub-entry (until it becomes full) -// // Note: the order MUST be preserved for the CSS to work (see _content.scss for details) -// currentSubEntryElement.append(childNode); -// nbChildrenOfCurrentSubEntry += 1; -// } - -// // For each sub-entry element: -// // - add placeholder text in each input field -// // - add a button to remove the sub-entry -// // Note: this method is not robust since it assumes the two elements always exist -// // and it identifies them by their relative order only! -// for (let [subEntryIndex, subEntryElement] of subEntryElements.entries()) { -// const subEntryInputElements = subEntryElement.querySelectorAll("input"); -// subEntryInputElements[0].setAttribute("placeholder", "Type"); // TODO: handle translation -// subEntryInputElements[1].setAttribute("placeholder", "Value"); // TODO: handle translation - -// createAndAppendSubEntryDeletionButton(subEntryElement); -// } - -// // Finally append all the sub-entry elements to the form entry -// formEntryElement.append(...subEntryElements); -// reindexSubEntries(formEntryElement); -// } - -// TODO: remove this hacky setup (cf. the TODO above) -// document.addEventListener("DOMContentLoaded", event => { -// // Create a list of all the form entry elements which contain sub entries -// // by filtering the list of all the form entry elements -// const targetForAttributeValues = [ -// "id_phone", -// "id_social", -// "id_mail", -// "id_address" -// ]; - -// const formEntryElementsWithSubEntries = [...document.querySelectorAll("#content-edit-profile .form-entry")] -// .filter(formEntryElement => { -// return [...formEntryElement.childNodes] -// .some(formEntryChildElement => { -// return formEntryChildElement.nodeType === Node.ELEMENT_NODE -// && formEntryChildElement.hasAttribute("for") -// && targetForAttributeValues.includes(formEntryChildElement.getAttribute("for")) -// }); -// }); - -// // Transform the remaining form entry elements to fix their structure -// for (let formEntryElement of formEntryElementsWithSubEntries) { -// //transformFormEntryWithSubEntries(formEntryElement); -// //createAndAppendNewSubEntryButton(formEntryElement); -// } -// }); - - -// ---------------------------------------------------------------------------- - +// Sub-entry of a mutli-entry form entry +// (e.g. one phone number amont several phone numbers grouped in a single entry) class SubEntry { constructor(subEntryElement, index, parentFormEntry) { this.parentFormEntry = parentFormEntry; @@ -297,6 +93,14 @@ class SubEntry { } } + + +// ---------------------------------------------------------------------------- + + + +// Form entry which can contain 0+ sub-entries +// (e.g. a phone number entry which can contain several numbers) class MultiEntryFormEntry { constructor(formEntryElement) { this.formEntryElement = formEntryElement; @@ -412,11 +216,18 @@ class MultiEntryFormEntry { startHandlingNewSubEntryButtonClicks() { const buttonElement = this.formEntryElement.querySelector(".add-sub-entry-button"); buttonElement.addEventListener("click", event => { + event.preventDefault(); this.createNewSubEntry(); }); } } + + +// ---------------------------------------------------------------------------- + + + // Setup the script by creating one instance of MultiEntryFormEntry // for each form entry configured to contain several sub-entries document.addEventListener("DOMContentLoaded", event => {