// -- GESTION DU FORMULAIRE PERMETTANT DE SAISIR / ÉDITER LES QUIZS ET LEURS DÉPENDANCES (LIENS, IMAGES, TAGS, ETC.) /// Vérifie que l'utilisateur est bien connecté, a le bon statut et le redirige vers le formulaire d'inscription si ce n'est pas le cas. /// Si c'est ok, propose un moteur de recherche permettant de chercher un quiz /// Si un id est passé par l'url on affiche les informations du quiz dans un formulaire permettant de l'éditer/supprimer avec une liste des éléments liés (liens, illustrations, questions...) pouvant eux-mêmes être édités/supprimés. /// Si le nombre max configuré pour chacun de ses éléments n'est pas atteint, il est aussi proposé d'ajouter un nouvel élément. /// Si pas d'id passé par l'url, on affiche un formulaire vide permettant de saisir un nouveau quiz. // Fichiers de configuration : import { apiUrl, availableLangs, theme } from "../../config/instance.js"; const lang=availableLangs[0]; const config = require("../../config/instance.js"); const configIllustrations = require("../../config/illustrations.js"); const configLinks = require("../../config/links.js"); const configQuestionnaires = require("../../config/questionnaires.js"); const configTemplate = require("../../views/"+theme+"/config/"+lang+".js"); // Fonctions : import { getLocaly, removeLocaly } from "./tools/clientstorage.js"; import { addElement } from "./tools/dom.js"; import { helloDev, updateAccountLink } from "./tools/everywhere.js"; import { empyAndHideForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js"; import { dateFormat, isEmpty } from "../../tools/main"; import { getUrlParams } from "./tools/url.js"; import { checkSession } from "./tools/users.js"; // Dictionnaires : const { addOkMessage, deleteBtnTxt, serverError, updateBtnTxt } = require("../../lang/"+lang+"/general"); const { addIllustrationTxt, defaultAlt, introNoIllustration, introTitleForIllustration } = require("../../lang/"+lang+"/illustration"); const { addLinkTxt, defaultValueForLink, introNoLink, introTitleForLink } = require("../../lang/"+lang+"/link"); const { addQuestionTxt, introNoQuestion, introTitleForQuestion } = require("../../lang/"+lang+"/question"); const { needGroupIfRank, nextDateWithoutQuestionnaire, nextQuestionnairesList, questionnaireNeedBeCompleted, searchQuestionnaireWithNoResult } = require("../../lang/"+lang+"/questionnaire"); const { needBeConnected } = require("../../lang/"+lang+"/user"); // Principaux éléments du DOM manipulés : const btnNewQuestionnaire = document.getElementById("wantNewQuestionnaire"); const btnPreviewQuestionnaire = document.getElementById("previewQuestionnaire"); const deleteCheckBox = document.getElementById("deleteOkLabel"); const divCrash = document.getElementById("crash"); const divIllustrations = document.getElementById("illustrationsList"); const divLinks = document.getElementById("linksList"); const divMain = document.getElementById("main-content"); const divMessage = document.getElementById("message"); const divQuestionnaires = document.getElementById("questionnairesList"); const divQuestions = document.getElementById("questionsList"); const divResponse = document.getElementById("response"); const divSearchResult = document.getElementById("searchResult"); const formLink = document.getElementById("links"); const formIllustration = document.getElementById("illustrations"); const formQuestion = document.getElementById("questions"); const formQuestionnaire = document.getElementById("questionnaires"); const formSearch = document.getElementById("search"); const helpClassification = document.getElementById("helpClassification"); const helpGroup = document.getElementById("helpGroup"); const helpPublishingAt = document.getElementById("helpPublishingAt"); const inputClassification = document.getElementById("classification"); const inputGroup = document.getElementById("group"); // Vide et cache tous les formulaires annexes au questionnaire : const hideAllForms = () => { empyAndHideForm(formLink); if(defaultValueForLink!=0) document.getElementById("anchor").value=defaultValueForLink; empyAndHideForm(formIllustration); empyAndHideForm(formQuestion); } // Affiche les données d'un lien dans le formulaire adhoc : const showFormLinkInfos = (Link) => { // On commence par cacher et vider tous les formulaires annexes hideAllForms(); // Puis on affiche celui concerné formLink.style.display="block"; // + Les contraintes de champ & valeurs par défaut : setAttributesToInputs(configLinks.Link, formLink); for(let data in Link) { if(formLink.elements[data]!==undefined) formLink.elements[data].value=Link[data]; } } // Affiche les infos connues concernant les liens du questionnaire affiché : const showLinkInfos = (Links, token) => { addElement(divLinks, "h2", introTitleForLink); let listLinks=""; for(let i in Links) listLinks+="
  • "+Links[i].anchor+"
    "+updateBtnTxt+" "+deleteBtnTxt+"
  • "; if(listLinks==="") listLinks="
  • "+introNoLink+"
  • "; addElement(divLinks, "ul", listLinks, "", [], "", false);// ! à intégrer d'abord dans le DOM pour pouvoir ajouter les Listeners ensuite for(let i in Links) { document.getElementById("#updateLink"+Links[i].id).addEventListener("click", function(e) { e.preventDefault(); showFormLinkInfos(Links[i]); window.location.assign("#links"); }); document.getElementById("#deleteLink"+Links[i].id).addEventListener("click", function(e) { e.preventDefault(); showFormLinkInfos(Links[i]); formLink.elements["deleteOk"].value=true; sendLinkForm(token); }); } if(Links.length < config.nbLinksMax || config.nbLinksMax === 0) { let newBtn=""+addLinkTxt+""; addElement(divLinks, "p", newBtn, "", [], { }, false); document.getElementById("newLink").addEventListener("click", function(e) { e.preventDefault(); hideAllForms(); formLink.style.display="block"; formLink.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value; window.location.assign("#links"); setAttributesToInputs(configLinks, formLink); }); } } // Envoi des données d'un lien. const sendLinkForm = (token) => { const divResponseLink=document.getElementById("responseLink"); divResponseLink.innerHTML=""; let datas=getDatasFromInputs(formLink); const xhrLinkDatas = new XMLHttpRequest(); if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk))) xhrLinkDatas.open("DELETE", apiUrl+configLinks.linksRoute+datas.id); else if(!isEmpty(datas.id)) xhrLinkDatas.open("PUT", apiUrl+configLinks.linksRoute+datas.id); else xhrLinkDatas.open("POST", apiUrl+configLinks.linksRoute); xhrLinkDatas.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if ((this.status === 200 || this.status === 201) && response.message!=undefined && response.questionnaire!=undefined) { if(Array.isArray(response.message)) response.message = response.message.join("
    "); else response.message = response.message; showLinkInfos(response.questionnaire.Links, token);// le serveur retourne une version actualisée de la liste des liens addElement(divLinks, "p", response.message, "", ["success"], "", false); hideAllForms(); window.location.assign("#linksList"); showNextQuestionnaires(token);// peut avoir évolué suivant ce qui s'est passé } else if (response.errors) { if(Array.isArray(response.errors)) response.errors = response.errors.join("
    "); else response.errors = serverError; addElement(divResponseLink, "p", response.errors, "", ["error"]); } else addElement(divResponseLink, "p", serverError, "", ["error"]); } } xhrLinkDatas.setRequestHeader("Content-Type", "application/json"); xhrLinkDatas.setRequestHeader("Authorization", "Bearer "+token); xhrLinkDatas.send(JSON.stringify(datas)); } // Affiche les données d'une illustration dans le formulaire adhoc : const showFormIllustrationInfos = (Illustration) => { // On commence par cacher et vider tous les formulaires annexes hideAllForms(); // Puis on affiche celui concerné formIllustration.style.display="block"; // + Les contraintes de champ & valeurs par défaut setAttributesToInputs(configIllustrations.Illustration, formIllustration); // Mais le champ file n'est plus requis, quand un fichier existe déjà formIllustration.elements["image"].removeAttribute("required"); for(let data in Illustration) { if(formIllustration.elements[data]!==undefined) formIllustration.elements[data].value=Illustration[data]; } } // Affiche les infos connues concernant les illustrations du questionnaire affiché : const showIllustrationInfos = (Illustrations, token) => { addElement(divIllustrations, "h2", introTitleForIllustration); let listIllustrations=""; for(let i in Illustrations) listIllustrations+="
  • "+defaultAlt+"
    "+updateBtnTxt+" "+deleteBtnTxt+"
  • "; if(listIllustrations === "") listIllustrations="
  • "+introNoIllustration+"
  • "; addElement(divIllustrations, "ul", listIllustrations, "", [], "", false);// ! à intégrer d'abord dans le DOM pour pouvoir ajouter les Listeners ensuite for(let i in Illustrations) { document.getElementById("#updateIllustration"+Illustrations[i].id).addEventListener("click", function(e) { e.preventDefault(); showFormIllustrationInfos(Illustrations[i]); window.location.assign("#illustrations"); }); document.getElementById("#deleteIllustration"+Illustrations[i].id).addEventListener("click", function(e) { e.preventDefault(); showFormIllustrationInfos(Illustrations[i]); formIllustration.elements["deleteOk"].value=true; sendIllustrationForm(token); }); } if(Illustrations.length < config.nbIllustrationsMax || config.nbIllustrationsMax === 0) { let newBtn=""+addIllustrationTxt+""; addElement(divIllustrations, "p", newBtn, "", [], { }, false); document.getElementById("newIllustration").addEventListener("click", function(e) { e.preventDefault(); hideAllForms(); formIllustration.style.display="block"; formIllustration.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value; window.location.assign("#illustrations"); setAttributesToInputs(configIllustrations, formIllustration); }); } } // Envoi des données d'une illustration. const sendIllustrationForm = (token) => { const divResponseIllustration=document.getElementById("responseIllustration"); divResponseIllustration.innerHTML=""; let datas=getDatasFromInputs(formIllustration); let datasWithFiles=new FormData(formIllustration); // car il me manque les informations du fichier avec la fonction getDatasFromInputs const xhrIllustrationDatas = new XMLHttpRequest(); if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk))) xhrIllustrationDatas.open("DELETE", apiUrl+configIllustrations.illustrationsRoute+datas.id); else if(!isEmpty(datas.id)) xhrIllustrationDatas.open("PUT", apiUrl+configIllustrations.illustrationsRoute+datas.id); else xhrIllustrationDatas.open("POST", apiUrl+configIllustrations.illustrationsRoute); xhrIllustrationDatas.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if ((this.status === 200 || this.status === 201) && response.message!=undefined && response.questionnaire!=undefined) { if(Array.isArray(response.message)) response.message = response.message.join("
    "); else response.message = response.message; showIllustrationInfos(response.questionnaire.Illustrations, token);// le serveur retourne une version actualisée de la liste des liens addElement(divIllustrations, "p", response.message, "", ["success"], "", false); hideAllForms(); window.location.assign("#illustrationsList"); showNextQuestionnaires(token);// peut avoir évolué suivant ce qui s'est passé } else if (response.errors) { if(Array.isArray(response.errors)) response.errors = response.errors.join("
    "); else response.errors = serverError; addElement(divResponseIllustration, "p", response.errors, "", ["error"]); } else addElement(divResponseIllustration, "p", serverError, "", ["error"]); } } xhrIllustrationDatas.setRequestHeader("Authorization", "Bearer "+token); xhrIllustrationDatas.send(datasWithFiles); } // Affiche les données d'une question + ses réponses possibles dans le formulaire adhoc const showFormQuestionInfos = (Question) => { // On commence par cacher et vider tous les formulaires annexes hideAllForms(); // Puis on affiche celui concerné formQuestion.style.display="block"; for(let data in Question.Question) { if(formQuestion.elements[data]!==undefined) formQuestion.elements[data].value=Question.Question[data]; } // + Les contraintes de champ & les valeurs par défaut setAttributesToInputs(configQuestionnaires.Question, formQuestion); for(let data in Question.Choices) { if(formQuestion.elements["choiceText"+data]!==undefined) { formQuestion.elements["choiceText"+data].value=Question.Choices[data].text; if(Question.Choices[data].isCorrect==true) formQuestion.elements["choiceIsCorrect"+data].checked=true; formQuestion.elements["idChoice"+data].value=Question.Choices[data].id; } } } // Affiche les infos des questions du quiz affiché : const showQuestionInfos = (Questions, token) => { addElement(divQuestions, "h2", introTitleForQuestion); let listQuestions=""; for(let i in Questions) listQuestions+="
  • "+Questions[i].Question.rank+" - "+Questions[i].Question.text+"
    "+updateBtnTxt+" "+deleteBtnTxt+"
  • "; if(listQuestions === "") listQuestions="
  • "+introNoQuestion+"
  • "; addElement(divQuestions, "ul", listQuestions, "", [], "", false);// à intégrer d'abord dans le DOM pour pouvoir ajouter les Listeners ensuite for(let i in Questions) { document.getElementById("#updateQuestion"+Questions[i].Question.id).addEventListener("click", function(e) { e.preventDefault(); showFormQuestionInfos(Questions[i]); window.location.assign("#questions"); }); document.getElementById("#deleteQuestion"+Questions[i].Question.id).addEventListener("click", function(e) { e.preventDefault(); showFormQuestionInfos(Questions[i]); formQuestion.elements["deleteOk"].value=true; sendQuestionForm(token); }); } if(Questions.length < config.nbQuestionsMax || config.nbQuestionsMax === 0) { let newBtn=""+addQuestionTxt+""; addElement(divQuestions, "p", newBtn, "", [], { }, false); document.getElementById("newQuestion").addEventListener("click", function(e) { e.preventDefault(); hideAllForms(); formQuestion.style.display="block"; formQuestion.elements["QuestionnaireId"].value=formQuestionnaire.elements["id"].value; formQuestion.elements["rank"].value=(Questions.length===0) ? configQuestionnaires.Question.rank.defaultValue : Questions.length+1; window.location.assign("#questions"); setAttributesToInputs(configQuestionnaires.Question, formQuestion); }); } } // Envoi des données d'une question et de ses réponse. Peut être généré par le bouton submit ou par le lien "supprimer". const sendQuestionForm = (token) => { const divResponseQuestion=document.getElementById("responseQuestion"); divResponseQuestion.innerHTML=""; let datas=getDatasFromInputs(formQuestion); const xhrQuestionDatas = new XMLHttpRequest(); if(!isEmpty(datas.id) && (!isEmpty(datas.deleteOk))) xhrQuestionDatas.open("DELETE", apiUrl+configQuestionnaires.questionsRoute+datas.id); else if(!isEmpty(datas.id)) xhrQuestionDatas.open("PUT", apiUrl+configQuestionnaires.questionsRoute+datas.id);// mise à jour d'une question else xhrQuestionDatas.open("POST", apiUrl+configQuestionnaires.questionsRoute);// nouvelle question xhrQuestionDatas.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if ((this.status === 200 || this.status === 201) && response.message!=undefined && response.questionnaire!=undefined) { if(Array.isArray(response.message)) response.message = response.message.join("
    "); else response.message = response.message; showQuestionInfos(response.questionnaire.Questions, token);// le serveur me retourne une version actualisée de la liste des questions addElement(divQuestions, "p", response.message, "", ["success"], "", false); hideAllForms(); window.location.assign("#questionsList"); showNextQuestionnaires(token);// car peut avoir évolué suivant ce qui s'est passé } else if (response.errors) { if(Array.isArray(response.errors)) response.errors = response.errors.join("
    "); else response.errors = serverError; addElement(divResponseQuestion, "p", response.errors, "", ["error"]); } else addElement(divResponseQuestion, "p", serverError, "", ["error"]); } } xhrQuestionDatas.setRequestHeader("Content-Type", "application/json"); xhrQuestionDatas.setRequestHeader("Authorization", "Bearer "+token); xhrQuestionDatas.send(JSON.stringify(datas)); } // Affichant les infos connues concernant un questionnaire et ses dépendances const showFormQuestionnaireInfos = (id, token) => { const xhrGetInfos = new XMLHttpRequest(); xhrGetInfos.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getQuestionnaireRoutes+"/"+id); xhrGetInfos.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && response.Questionnaire != undefined) { formQuestionnaire.reset();// pour ne pas garder les données déjà affichées si vide dans ce qui est retourné for(let data in response.Questionnaire) { if(formQuestionnaire.elements[data]!==undefined) { if(data==="publishingAt" && response.Questionnaire[data]!==null) formQuestionnaire.elements[data].value=dateFormat(response.Questionnaire[data], "form");// !! revoir car format pouvant poser soucis si navigateur ne gère pas les champs de type "date" else formQuestionnaire.elements[data].value=response.Questionnaire[data]; } } deleteCheckBox.style.display="block"; }// ajouter gestion des retours en erreur ? if(response.Tags != undefined) { let classification=""; for(let i in response.Tags) { if(i==0) classification+=response.Tags[i].name; else classification+=","+response.Tags[i].name; } formQuestionnaire.elements["classification"].value=classification; } if(!isEmpty(response.Group)) formQuestionnaire.elements["group"].value=response.Group.Group.title+" ("+response.Group.Group.id+")"; divLinks.style.display="block"; divQuestions.style.display="block"; divIllustrations.style.display="block"; if(response.Links != undefined) showLinkInfos(response.Links, token); if(response.Questions != undefined) showQuestionInfos(response.Questions, token); if(response.Illustrations != undefined) showIllustrationInfos(response.Illustrations, token); helpPublishingAt.style.display="none";// info uniquement utile pour "placer" un nouveau quiz // à revoir : remplacer lien pour un bouton + reset complet du formulaire, y compris champs hidden : btnNewQuestionnaire.style.display="block"; btnNewQuestionnaire.setAttribute("href", configTemplate.questionnairesManagementPage); btnPreviewQuestionnaire.style.display="block"; if(response.Questionnaire["isPublished"] === false) btnPreviewQuestionnaire.setAttribute("href", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.previewQuestionnaireRoutes+"/"+id+"/"+token); else btnPreviewQuestionnaire.setAttribute("href", config.siteUrl+configQuestionnaires.publishedQuestionnaireRoutes+response.Questionnaire["slug"]+".html"); } } xhrGetInfos.send(); } // Affiche les questionnaires bientôt publiés. const showNextQuestionnaires = (token) => { const xhrNextQuestionnaires = new XMLHttpRequest(); xhrNextQuestionnaires.open("GET", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.getListNextQuestionnaires); xhrNextQuestionnaires.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && Array.isArray(response.questionnaires)) { let listHTML="", dayStr, optionsDayStr = { weekday: 'long'}; for(let i in response.questionnaires) { dayStr=new Intl.DateTimeFormat(lang, optionsDayStr).format(new Date(response.questionnaires[i].datePublishing)); listHTML+="
  • "+dayStr+" "+dateFormat(response.questionnaires[i].datePublishing, "fr")+": "+response.questionnaires[i].title+""; if(response.questionnaires[i].isPublishable===false) listHTML+=" ("+questionnaireNeedBeCompleted+")
  • "; listHTML+=""; } if(response.questionnaires.length!==0) addElement(divQuestionnaires, "h3", nextQuestionnairesList.replace("#NB", response.questionnaires.length)); addElement(helpPublishingAt, "em", nextDateWithoutQuestionnaire+dateFormat(new Date(response.dateNeeded), "fr")); addElement(divQuestionnaires, "ul", listHTML, "", "", "", false); for(let i in response.questionnaires) { document.getElementById("questionnaire_"+response.questionnaires[i].id).addEventListener("click", function(e) { e.preventDefault(); showFormQuestionnaireInfos(e.target.id.split("_")[1], user.token); window.location.assign("#questionnaires"); }); } }// ajouter gestion erreurs reçues du serveur ? } } xhrNextQuestionnaires.setRequestHeader("Authorization", "Bearer "+token); xhrNextQuestionnaires.send(); } const initialise = async () => { try { const isConnected=await checkSession(["manager", "admin"], "/"+configTemplate.connectionPage, { message: needBeConnected, color:"error" }, window.location); if(isConnected) { divMain.style.display="block"; if(!isEmpty(getLocaly("message"))) { addElement(divMessage, "p", getLocaly("message", true).message, "", [getLocaly("message", true).color], "", false); removeLocaly("message"); } const user=getLocaly("user", true); // Mise à jour du lien "compte" du header : updateAccountLink(user.status, configTemplate); // Initialisation des formulaires : setAttributesToInputs(configQuestionnaires, formSearch); setAttributesToInputs(configQuestionnaires.Questionnaire, formQuestionnaire); // Vide/cache les éléments inutiles en mode création : btnPreviewQuestionnaire.style.display="none"; deleteCheckBox.style.display="none"; hideAllForms(); // Si un id est passé par l'url, on essaye d'afficher le questionnaire : let urlDatas=getUrlParams(); if(urlDatas && urlDatas.id!==undefined) showFormQuestionnaireInfos(urlDatas.id, user.token); // Lancement d'une recherche : formSearch.addEventListener("submit", function(e) { e.preventDefault(); let datas=getDatasFromInputs(formSearch); const xhrSearch = new XMLHttpRequest(); xhrSearch.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.searchAdminQuestionnairesRoute); xhrSearch.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && Array.isArray(response)) { if(response.length===0) addElement(divSearchResult, "p", searchQuestionnaireWithNoResult, "", ["info"]); else { let selectHTML=""; for(let i in response) selectHTML+=""; addElement(divSearchResult, "select", selectHTML, "selectSearch"); const searchSelect=document.getElementById("selectSearch"); searchSelect.addEventListener("change", function() { if(searchSelect.value!=="") showFormQuestionnaireInfos(searchSelect.value, user.token); }); } } else addElement(divSearchResult, "p", serverError, "", ["error"]); } } xhrSearch.setRequestHeader("Content-Type", "application/json"); xhrSearch.setRequestHeader("Authorization", "Bearer "+user.token); if(datas) xhrSearch.send(JSON.stringify(datas)); }); showNextQuestionnaires(user.token); // Aide à la saisie pour le classement du quiz inputClassification.addEventListener("input", function(e) { divResponse.innerHTML=""; const tags=inputClassification.value.split(","); tags.reverse(); const lastTag=tags[0].trim(); if(lastTag.length >= 2) { // à revoir : importer la liste des tags lors de l'initialisation pour éviter les appels multiples ? // mais dans ce cas actualiser cette liste après chaque mise à jour. const xhrSearchTags = new XMLHttpRequest(); xhrSearchTags.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+configQuestionnaires.tagsSearchRoute); xhrSearchTags.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && Array.isArray(response)) { helpClassification.innerHTML=""; for(let i in response) { addElement(helpClassification, "a", response[i].name, "#tag"+response[i].id, ["info"], { href:"#tag"+response[i].id }, false); document.getElementById("#tag"+response[i].id).addEventListener("click", function(e) { e.preventDefault(); tags[0]=e.target.innerHTML; tags.reverse(); inputClassification.value=tags.join(","); helpClassification.innerHTML=""; }); } } } } xhrSearchTags.setRequestHeader("Content-Type", "application/json"); xhrSearchTags.setRequestHeader("Authorization", "Bearer "+user.token); xhrSearchTags.send(JSON.stringify({search: lastTag})); } }); // Aide à la sélection d'un groupe pour le quiz inputGroup.addEventListener("input", function(e) { formQuestionnaire["GroupId"].value=""; const groupInput=inputGroup.value.trim(); if(groupInput.length >= configQuestionnaires.searchGroups.minlength) { const xhrSearchGroups = new XMLHttpRequest(); xhrSearchGroups.open("POST", apiUrl+configQuestionnaires.groupRoutes+configQuestionnaires.searchGroupsRoute); xhrSearchGroups.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && Array.isArray(response)) { helpGroup.innerHTML=""; for(let i in response) { addElement(helpGroup, "a", response[i].title, "#group"+response[i].id, ["info"], { href:"#group"+response[i].id }, false); document.getElementById("#group"+response[i].id).addEventListener("click", function(e) { e.preventDefault(); let groupId=e.target.id.replace("#group", ""); inputGroup.value=e.target.innerHTML+" ("+groupId+")"; formQuestionnaire["GroupId"].value=groupId; helpGroup.innerHTML=""; }); } } } } xhrSearchGroups.setRequestHeader("Content-Type", "application/json"); xhrSearchGroups.setRequestHeader("Authorization", "Bearer "+user.token); xhrSearchGroups.send(JSON.stringify({searchGroups: groupInput})); } }); // Traitement de l'envoi du formulaire des infos de base du quiz formQuestionnaire.addEventListener("submit", function(e) { e.preventDefault(); divResponse.innerHTML=""; let datas=getDatasFromInputs(formQuestionnaire); if(!isEmpty(datas.rankInGroup) && isEmpty(datas.GroupId)) addElement(divResponse, "p", needGroupIfRank, "", ["error"]); else { if(isEmpty(datas.rankInGroup) && !isEmpty(datas.GroupId)) datas.rankInGroup=1; const xhrQuestionnaireDatas = new XMLHttpRequest(); if(!isEmpty(datas.id) && (datas.deleteOk!==undefined)) xhrQuestionnaireDatas.open("DELETE", apiUrl+configQuestionnaires.questionnaireRoutes+"/"+datas.id); else if(!isEmpty(datas.id)) xhrQuestionnaireDatas.open("PUT", apiUrl+configQuestionnaires.questionnaireRoutes+"/"+datas.id); else xhrQuestionnaireDatas.open("POST", apiUrl+configQuestionnaires.questionnaireRoutes+"/"); xhrQuestionnaireDatas.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 201 && response.id != undefined) { addElement(divResponse, "p", addOkMessage, "", ["success"]); datas.id=response.id; showNextQuestionnaires(user.token);// peut avoir évolué suivant ce qui s'est passé } else if (this.status === 200 && response.message != undefined) { if(Array.isArray(response.message)) response.message = response.message.join("
    "); else response.message = response.message; addElement(divResponse, "p", response.message, "", ["success"]); showNextQuestionnaires(user.token);// peut avoir évolué suivant ce qui s'est passé } else if (response.errors) { if(Array.isArray(response.errors)) response.errors = response.errors.join("
    "); else response.errors = serverError; addElement(divResponse, "p", response.errors, "", ["error"]); } else addElement(divResponse, "p", serverError, "", ["error"]); if(datas.deleteOk === undefined && response.errors === undefined) showFormQuestionnaireInfos(datas.id, user.token);// on actualise les données else if (response.errors === undefined) { formQuestionnaire.reset(); divLinks.innerHTML=""; divIllustrations.innerHTML=""; divQuestions.innerHTML=""; } } } xhrQuestionnaireDatas.setRequestHeader("Content-Type", "application/json"); xhrQuestionnaireDatas.setRequestHeader("Authorization", "Bearer "+user.token); if(datas) xhrQuestionnaireDatas.send(JSON.stringify(datas)); } }); formLink.addEventListener("submit", function(e) { e.preventDefault(); sendLinkForm(user.token); }); formIllustration.addEventListener("submit", function(e) { e.preventDefault(); sendIllustrationForm(user.token); }); formQuestion.addEventListener("submit", function(e) { e.preventDefault(); sendQuestionForm(user.token); }); } } catch(e) { console.error(e); addElement(divCrash, "p", serverError, "", ["error"]); } } initialise(); helloDev();