// -- 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 } 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");
const inputRankInGroup = document.getElementById("rankInGroup");
// 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+="
";
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+="
";
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+="