Le deal à ne pas rater :
Display One Piece Card Game Japon OP-08 – Two Legends : où la ...
Voir le deal


proposition générateur fiche de présentation

Tamaraa
Invité

Anonymous



   
Coucou Kim sunny

Je suis entrain de potasser sur un générateur de fiche de présentation et au lieu qu'il prenne la poussière je m'étais dit que j'allais venir le partager.

J'ai vu sur tumblr qu'on pouvait te partager des tutos, alors je voudrais savoir comment je peux te donner tout ça une fois qu'il sera prêt ! Je sais pas si ce sera pas un peu sale mais il est fonctionnel et je pense assez facile d'utilisation.

Merci à toi Very Happy
Kim

Kim


Pronoun(s) : Elle/she
Messages : 157

   
Heyy Tamaraa ! Tu sais très bien que tu peux me joindre sur discord 👀

Edit!

On s'y met à plusieurs pour lui apporter un maximum de fonctionnalité utile. On cherche par exemple comment pouvoir faire en sorte d'également éditer sa fiche via le formulaire.

Javascript
Il faut changer le lien de la 2e ligne pour faire apparaître le formulaire que dans la catégorie voulu

Code:
// On affiche le générateur que sur le forum voulu
document.addEventListener("DOMContentLoaded", function () {
  if (!window.location.href.includes("/post?f=10&mode=newtopic")) return;
  document.querySelector("#formGenerateur").style.display = "block";
  
  document.getElementById("generateBtn").addEventListener("click", getData);
  
});
                                                        
function getData() {
  const generator = document.querySelector('.box');
 const inputs = generator.querySelectorAll('input, select, textarea');

 const payload = {};
 Array.from(inputs).forEach((input) => {
 // L'input doit avoir un nom qui servira de clé pour l'objet payload
 if(input.name) {
         payload[input.name] = input.value;
 }
    });
    
    console.log(payload);
 const generatedCode = generateCodeFromPayload(payload);
 insertGeneratedCodeIntoEditor(generatedCode);
}

function generateCodeFromPayload(payload) {
  const {
    triggerWarnings,
    prenomNom,
    citation,
    avatarCelebrite,
    age,
    dateNaissance,
    lieuNaissance,
    nationalite,
    occupation,
    statutCivil,
    caractere,
    faceclaim,
    groupe,
    credits,
    histoire,
    pseudo,
    pronoms,
    pays,
    typePersonnage,
    motFin,
  } = payload;

  return `<div class="fiche">      
  <span>${prenomNom}</span>
  <span>${citation}</span><div class="firstSection">
    <img class="avatar" src="${avatarCelebrite}" alt="">
    <div class="infoPerso">
      <div class="tw">
        <span>trigger warnings :</span>
        <span>${triggerWarnings}</span>
      </div>
      <div class="bio">
        <span>âge :</span> ${age} ans. <span>date et lieu de naissance :</span> ${dateNaissance} à ${lieuNaissance}.
        <span>nationalité :</span>
        ${nationalite}. <span>
          occupation :</span> ${occupation}. <span>statut
          civil :</span> ${statutCivil}. <span>caractère :</span> ${caractere}
      </div>
      <div class="adminPerso">
        <span>faceclaim :</span> ${faceclaim}. <span>groupe :</span> ${groupe}. <span>crédits :</span> ${credits}.
      </div>
    </div>
  </div><div class="secondSection">
    ${histoire}
  </div><div class="thirdSection">
    <span>pseudo, prénom :</span> ${pseudo}. <span>pronoms :</span> ${pronoms}. <span>pays :</span> ${pays}. <span>type de personnage :</span> ${typePersonnage}. <span>le mot de la fin :</span> ${motFin}.
  </div>
  </div>`;
}

function insertGeneratedCodeIntoEditor(code) {
  const editorTextarea = document.querySelector("textarea[placeholder]");
  if (!editorTextarea) {
    console.error("Le textarea de l'éditeur n'a pas été trouvé.");
    return;
  }

  const instance = $(editorTextarea).sceditor("instance");
  if (!instance) {
    console.error("Instance de sceditor non trouvée.");
    return;
  }

  instance.val(code);
}


Template posting_body
Juste après le bloc de description par exemple

Code:
<div id="formGenerateur" class="form" style="padding: 20px; display: none">
 <div class="box" style="padding: 20px">
 <h2>Première partie</h2>

 <!-- champ du formulaire - champ pour texte court -->
 <label for="triggerWarnings">Trigger Warnings :</label>
 <input type="text" name="triggerWarnings" />
 <!-- fin du champ -->

 <label for="prenomNom">Prénom Nom :</label>
 <input type="text" name="prenomNom" />

 <label for="citation">Citation :</label>
 <input type="text" name="citation" />

 <!-- champs du formulaire permettant l'ajout de l'url de l'avatar -->
 <label for="avatarcélébrite">Url de l'avatar de la célébrité :</label>
 <input type="text" name="avatarCelebrite" />
 <!-- fin du champ -->

 <label for="age">Age :</label>
 <input type="text" name="age" />

 <label for="dateNaissance">Date de Naissance :</label>
 <input type="text" name="dateNaissance" />

 <label for="lieuNaissance">Lieu de Naissance :</label>
 <input type="text" name="lieuNaissance" />

 <label for="nationalite">Nationalité :</label>
 <input type="text" name="nationalite" />

 <label for="occupation">Occupation :</label>
 <input type="text" name="occupation" />

 <label for="statutCivil">Statut Civil:</label>
 <input type="text" name="statutCivil" />

 <label for="caractere">Caractère :</label>
 <input type="text" name="caractere" />

 <label for="faceclaim">Faceclaim :</label>
 <input type="text" name="faceclaim" />

 <!-- champ du formulaire - menu déroulant permettant de sélectionner une proposition -->
 <label for="groupe">Groupe :</label>
 <select name="groupe">
 <option value="">Choisir le groupe</option>
 <option value="Groupe1">Groupe 1</option>
 <option value="Groupe2">Groupe 2</option>
 <option value="Groupe3">Groupe 3</option>
 <option value="Groupe4">Groupe 4</option>
 </select>
 <!-- fin du champ -->

 <label for="credits">Crédits :</label>
 <input type="text" name="credits" />

 <h2>Deuxième partie</h2>

 <!-- champ du formulaire - champ pour texte long -->
 <label for="histoire">Histoire du personnage :</label>
 <textarea name="histoire"></textarea>
 <!-- fin du champ -->

 <h2>Troisième partie</h2>

 <label for="pseudo">Pseudo, prénom :</label>
 <input type="text" name="pseudo" />

 <label for="pronoms">Pronoms :</label>
 <input type="text" name="pronoms" />

 <label for="pays">Pays:</label>
 <input type="text" name="pays" />

 <label for="typePersonnage">Type de personnage:</label>
 <select name="typePersonnage">
 <option value="">Choisir le type de personnage</option>
 <option value="inventé">Inventé</option>
 <option value="éphémère">Ephémère</option>
 <option value="pré-lien">Pré-lien</option>
 </select>

 <label for="motFin">Le mot de la fin:</label>
 <input type="text" name="motFin" /><br /><br />
 <!-- bouton permettant de générer le code -->
 <input type="button" id="generateBtn" style="cursor: pointer;" value="Générer" />
 <!-- fin du bouton -->
 </div>
</div>
Kim

Kim


Pronoun(s) : Elle/she
Messages : 157

   
Hey again 👋

On test une autre approche, cette fois pour ne passer que par un formulaire de fiche. Pour se faire on sauvegarde tout en format JSON et on l'utilise au besoin de l'édition ou de l'affichage du post.

Dans l'idée, ça donnerait ça :
- Générer une fiche en JSON
- Insérer ce JSON dans le post en texte

A l'affichage du post (pas encore traité dans le script) :
- Repérer que le premier post est une fiche (le contenu sera du JSON en string)
- Recupérer le contenu
- Le transformer en code fiche

A l'édition :
- Remplir de nouveau le formulaire du générateur avec les infos déjà sauvegardées



En HTML, il faut créer le formulaire qui sera l'éditeur de la fiche. Dans le template posting_body, un exemple :

Code:
<div id="formGenerateur" class="form" style="padding: 20px; display: none">
 <h2>Editeur de fiche</h2>

 <label for="triggerWarnings">Trigger Warnings :</label>
 <input type="text" name="triggerWarnings" />
                <br/>
 <label for="prenomNom">Prénom Nom :</label>
 <input type="text" name="prenomNom" />
                <br/>
 <!-- bouton permettant de générer le code -->
 <input type="button" id="generateBtn" style="cursor: pointer;" value="Générer" />
 <!-- fin du bouton -->
</div>


Et le script (à mettre dans une page javascript dans la PA)
Pensez à changer la valeur de la variable FICHE_CATEGORY par le numéro de catégorie où vous faites vos essais

Code:
document.addEventListener("DOMContentLoaded", () => {
  // Variables globales
  const
    FICHE_CATEGORY = '10', // la catégorie des fiches
    FORM = document.querySelector("#formGenerateur"), // Le form de génération de fiche
    FORM_INPUTS = Array.from(FORM.querySelectorAll(`input, select, textarea`)), // Les champs du form sous forme de tableau
    POST_CONTENT = document.querySelector("textarea#text_editor_textarea").value; // Le contenu du post

  // Réccupérer le contenu du post
  // Renvoi le contenu sous JSON si le contenu peut être parse, sinon renvoi false
  const getCharacterData = (data) => {
    try {
      return JSON.parse(data);
    } catch {
      return false;
    }
  };

  // Afficher le form du générateur
    // Deux conditions :
    // - A la CREATION : le sujet est posté dans la catégorie des fiches
    // - A l'EDITION : le contenu du post édité peut-être parse en JSON
  if (
    document.querySelector('form[action="/post"] input[type="hidden"][name="f"]').value === FICHE_CATEGORY ||
    getCharacterData(POST_CONTENT)
  ) {
    // Affiche le générateur + ajout de l'eventListener sur son bouton
    FORM.style.display = "block";
    document
      .getElementById("generateBtn")
      .addEventListener("click", generateCharacterSheet);
  }

  // Fonction pour remplir le form du générateur à l'édition d'un post
  // Elle attend un objet avec les mêmes clés/valeurs du form
  function fillForm(data) {
    Object.keys(data).forEach((key) => {
      FORM_INPUTS.forEach((input) => {
        if (input.name === key) {
          input.value = data[key];
        }
      });
    });
  }

  // Rétribution du contenu du post dans le form du générateur
  fillForm(getCharacterData(POST_CONTENT));

  // Génération des données de la fiche
  function generateCharacterSheet() {
    const payload = {};
    // Pour chaque input du générateur, on donne son nom en clé et sa valeur correspondante
    Array.from(FORM_INPUTS).forEach((input) => {
      // L'input doit avoir un nom (ça exclu les boutons par exemple)
      if (input.name) {
        payload[input.name] = input.value;
      }
    });

    // On insère le contenu généré dans l'éditeur en le transformant en string
    insertToEditor(JSON.stringify(payload));
  }

  // Insertion du contenu dans l'éditeur du post
  function insertToEditor(data) {
    const editorTextarea = document.querySelector(
      "textarea#text_editor_textarea"
    );
    if (!editorTextarea) {
      console.error("Le textarea de l'éditeur n'a pas été trouvé.");
      return;
    }

    const instance = $(editorTextarea).sceditor("instance");
    if (!instance) {
      console.error("Instance de sceditor non trouvée.");
      return;
    }
    instance.val(data);
  }
});
Kim

Kim


Pronoun(s) : Elle/she
Messages : 157

   
👋

Nouvelle fonctionnalité : ajouter des faits/anecdotes au formulaire (voir démo)
Voyez les post au-dessus pour les explications d'installer 👏

HTML
Code:
<div id="formGenerateur" class="form" style="padding: 20px; display: none">
 <h2>On fait des tests pour un générateur de fiche</h2>

 <label for="triggerWarnings">Trigger Warnings :</label>
 <input type="text" name="triggerWarnings" />
                <br/>
 <label for="prenomNom">Prénom Nom :</label>
 <input type="text" name="prenomNom" />
                <br/>
                
                <div class="anecdotes-list">
 <template id="anecdote">
 <label for="fact">Anecdote</label>
                   <input type="text" name="fact" /><br/>
 </template>
 </div>
                
 <input type="button" id="addFact" style="cursor: pointer;" value="Ajouter une anecdocte" />
 <br/><br/>
                
 <!-- bouton permettant de générer le code -->
 <input type="button" id="generateBtn" style="cursor: pointer;" value="Générer" />
 <!-- fin du bouton -->
              </div>


Javascript
Code:
document.addEventListener("DOMContentLoaded", () => {
  // Variables globales
  const
    FICHE_CATEGORY = 10, // la catégorie des fiches
    FORM = document.querySelector("#formGenerateur"), // Le form de génération de fiche
    FORM_INPUTS = Array.from(FORM.querySelectorAll('input, select, textarea')); // Les champs du form sous forme de tableau
    

  // Réccupérer le contenu du post
  // Renvoi le contenu sous JSON si le contenu peut être parse, sinon renvoi false
  const getCharacterData = () => {
    const postContent = document.querySelector("textarea#text_editor_textarea").value; // Le contenu du post
    try {
      return JSON.parse(postContent);
    } catch {
      return false;
    }
  };
  
  // Fonction pour remplir le form du générateur à l'édition d'un post
  // Elle attend un objet avec les mêmes clés/valeurs du form
  function fillForm(data) {
    Object.keys(data).forEach((key) => {
      if (data[key] !== "Array") { // On exclu les valeurs qui sont des tableaux (comme les anecdotes)
        FORM_INPUTS.forEach((input) => {
          if (input.name === key) {
            input.value = data[key];
          }
        });
      }
    });
  }
 

  // Afficher le form du générateur
    // Deux conditions :
    // - A la CREATION : le sujet est posté dans la catégorie des fiches
    // - A l'EDITION : le contenu du post édité peut-être parse en JSON
  if (
      document.querySelector('form[action="/post"] input[type="hidden"][name="f"]')?.value == FICHE_CATEGORY ||
 getCharacterData()
  ) {
    
    // Affiche le générateur + ajout de l'eventListener sur son bouton
    FORM.style.display = "block";
    document
      .getElementById("generateBtn")
      .addEventListener("click", generateCharacterSheet);
    
    // Ajout d'anecdote
    document.querySelector("#addFact").addEventListener("click", () => {createFactInput("") });
  
  
    // Edit du formulaire
    // Rétribution du contenu du post dans le form du générateur
    fillForm(getCharacterData());
    // Edit anecdote
    getCharacterData().anecdotes?.forEach((anecdote) => {
      createFactInput(anecdote);
    });
  
  }
  
  // Génération des données de la fiche
  function generateCharacterSheet() {
    // Réccupération des inputs d'anecdote
    // Seulement à cette étape du script parce que l'utilisateur a sûrement ajouter des nouveaux inputs entre temps
    const anecdotesInputs = Array.from(FORM.querySelectorAll(`input[name="fact"]`));

    // Format du payload
    let payload = {
      anecdotes: [],
    };

    // Pour chaque input du générateur, on donne son nom en clé et sa valeur correspondante
    Array.from(FORM_INPUTS).forEach((input) => {
      // L'input doit avoir un nom (ça exclu les boutons par exemple)
      if (input.name) {
        payload[input.name] = input.value;
      }
    });

    // Pour chaque input d'anecdote, on réccupère sa valeur et on la met dans le tableau
    anecdotesInputs.forEach((anecdote) => {
      payload.anecdotes.push(anecdote.value);
    });

    // On insère le contenu généré dans l'éditeur en le transformant en string
    insertToEditor(JSON.stringify(payload));
  }

  // Insertion du contenu dans l'éditeur du post
  function insertToEditor(data) {
    const editorTextarea = document.querySelector(
      "textarea#text_editor_textarea"
    );
    if (!editorTextarea) {
      console.error("Le textarea de l'éditeur n'a pas été trouvé.");
      return;
    }

    const instance = $(editorTextarea).sceditor("instance");
    if (!instance) {
      console.error("Instance de sceditor non trouvée.");
      return;
    }
    instance.val(data);
  }
      
  // Création d'un nouvelle input pour ajouter une anecdote
  // (voir <template> dans le html du form)
  function createFactInput(value) {
    const anecdote_template = document.getElementById("anecdote");
    const anecdote_html = document.importNode(anecdote_template.content, true);

    // Insère une valeur à l'input si besoin
    anecdote_html.querySelector(`input[name="fact"`).value = value;

    // Ajoute l'input au DOM
    document.querySelector(".anecdotes-list").appendChild(anecdote_html);
  }
});
Kim

Kim


Pronoun(s) : Elle/she
Messages : 157

   
Ajout du code de présentation de la fiche
(je dois filer je ferai de meilleure explication plus tard)

HTML
posting_body (formulaire)
Code:
<div id="formGenerateur" class="form" style="padding: 20px; display: none">
 <h2>On fait des tests pour un générateur de fiche</h2>
 <label for="prenomNom">Prénom Nom </label>
 <input type="text" name="prenomNom" />
                <br/>
 <label for="triggerWarnings">Age </label>
 <input type="text" name="age" />
                <br/><br/>
                
                <div class="anecdotes-list">
 <template id="anecdoteTemplate">
                  <div class="anecdote">
 <label for="fact">Anecdote</label>
 <input type="text" name="fact" />
                    <input type="button" id="deleteFact" value="X"/>
                    <br/>
                  </div>
                  
 </template>
 </div>
                
 <input type="button" id="addFact" style="cursor: pointer;" value="Ajouter une anecdocte" />
 <br><br>
                
 <!-- bouton permettant de générer le code -->
 <input type="button" id="generateBtn" style="cursor: pointer;" value="Générer" />
 <!-- fin du bouton -->
              </div>

posting_preview (à remplacer si utilisation du blank)
Code:
<div id="preview" class="post row2">
 <div class="h3">{L_PREVIEW}</div>
 <div class="postbody content">
 <div class="content">{MESSAGE_NEW}</div>
 </div>
</div>


Javascript
Code:
document.addEventListener("DOMContentLoaded", () => {
  // VARIABLES GLOBALES
  const
    // la catégorie des fiches
    categorieDesFiches = 10,

    // Formulaire du générateur
    formulaireGenerateur = document.querySelector("#formGenerateur"), // Element HTML du formulaire
    // Champs du formulaire (s'il y a un formulaire)
    champsDuFormulaire = formulaireGenerateur
      ? Array.from(formulaireGenerateur.querySelectorAll("input, select, textarea")) // convertis dans un array
      : null,

    // Le contenu du post à l'édition
    textareaEditeurPost = document.querySelector("textarea#text_editor_textarea"), // Element HTML de l'éditeur
    contenuPostEdition = textareaEditeurPost ? textareaEditeurPost.value : null, // Contenu de l'éditeur (s'il y a l'éditeur)

    // Element HTML du contenu d'un post (ou de sa prévisualisaiton)
    htmlPostFiche = document.querySelector(".postbody.content div");


  // Fonction utilitaire pour réccupérer les données générées par le formulaire
  // Si les données réccupérées peuvent être converties en JSON, on renvoi le JSON, sinon renvoi false
  const reccupererInfosFiches = (data) => {
    try {
      return JSON.parse(data);
    } catch {
      return false;
    }
  };

  // RECCUPERATIONS DES INFOS DE LA FICHE
  const
    // Contenu d'un post (s'il y a un post)
    contenuPostFiche = htmlPostFiche ? htmlPostFiche.innerHTML : null,
    // Données JSON de la fiche
    infosFichePost = reccupererInfosFiches(contenuPostFiche);

  // UTILISATION DES DONNEES DE LA FICHE
  // S'il y a des données réccupérée dans le bon format (JSON)
  if (infosFichePost) {

    // Destructuration des données JSON pour utiliser plus facilement litteral string (ie. ${infos})
    const { prenomNom, age } = infosFichePost;

    // Code de présentation de chaque anecdote enregistrée
    const listeAnecdotes = infosFichePost.anecdotes
      .map((anecdote) => {
        return `<li>- ${anecdote}</li>`;
      })
      .join("");

    // CODE DE PRESENTATION DE LA FICHE
    const htmlFichePresentation = `
        <h3>Je m'apelle ${prenomNom}</h3>
        <p>J'ai ${age} ans et j'aime :<p>
        <ul>
          ${listeAnecdotes}
        </ul>
      `;

    // Remplace les infos JSON par le code de présentation de la fiche
    htmlPostFiche.innerHTML = htmlFichePresentation;
  }

  // --------------------------
  // CREATION-EDITION D'UN POST

  // Afficher le form du générateur
  // Deux conditions :
  // - A la CREATION : le sujet est posté dans la catégorie des fiches
  // - A l'EDITION : le contenu du post édité peut-être parse en JSON
  if (
    document.querySelector(
      'form[action="/post"] input[type="hidden"][name="f"]'
    )?.value == categorieDesFiches ||
    reccupererInfosFiches(contenuPostEdition)
  ) {
    // Affiche le générateur + ajout de l'eventListener sur son bouton
    formulaireGenerateur.style.display = "block";
    document
      .getElementById("generateBtn")
      .addEventListener("click", genererInfosDeFiche);

    // Update les informations dans l'éditeur en "direct"
    champsDuFormulaire.forEach((champs) => {
      champs.addEventListener("input", genererInfosDeFiche);
    });

    // Ajout d'anecdote au clique du bouton "ajouter"
    document.querySelector("#addFact").addEventListener("click", () => {
      creerChampsAnecdote("");
    });

    // EDITION
    // Fonction pour remplir les inputs du formulaire avec les infos enregistrées
    // Elle attend un objet avec les mêmes clés/valeurs du form
    function remplirLeFormulaire(data) {
      Object.keys(data).forEach((key) => {
        if (typeof data[key] !== "Array") {
          // On exclu les valeurs qui sont des tableaux (comme les anecdotes)
          champsDuFormulaire.forEach((input) => {
            if (input.name === key) {
              input.value = data[key];
            }
          });
        }
      });
    }

    // Rétribution du contenu du post dans le form du générateur
    remplirLeFormulaire(reccupererInfosFiches(contenuPostEdition));
    // Rétribution dans les inputs anecdotes
    reccupererInfosFiches(contenuPostEdition).anecdotes?.forEach((anecdote) => {
      creerChampsAnecdote(anecdote);
    });
  }

  // Génération des données de la fiche
  function genererInfosDeFiche() {
    // Réccupération des inputs d'anecdote
    // Seulement à cette étape du script parce que l'utilisateur a sûrement ajouter des nouveaux inputs entre temps
    const champsDesAnecdotes = Array.from(
      formulaireGenerateur.querySelectorAll(`input[name="fact"]`)
    );

    // Format des informations de la fiche
    let infosFiches = {
      anecdotes: [],
    };

    // Pour chaque input du générateur, on donne son nom en clé et sa valeur correspondante
    Array.from(champsDuFormulaire).forEach((input) => {
      // L'input doit avoir un nom (ça exclu les boutons par exemple)
      if (input.name) {
        infosFiches[input.name] = input.value;
      }
    });

    // Pour chaque input d'anecdote, on réccupère sa valeur et on la met dans le tableau
    champsDesAnecdotes.forEach((anecdote) => {
      infosFiches.anecdotes.push(anecdote.value);
    });

    // On insère le contenu généré dans l'éditeur en le transformant en string
    insererInfosDansPost(JSON.stringify(infosFiches));
  }

  // Insertion du contenu dans l'éditeur du post
  function insererInfosDansPost(data) {
    if (!textareaEditeurPost) {
      console.error("Le textarea de l'éditeur n'a pas été trouvé.");
      return;
    }

    const instance = $(textareaEditeurPost).sceditor("instance");
    if (!instance) {
      console.error("Instance de sceditor non trouvée.");
      return;
    }
    instance.val(data);
  }

  // Création d'un nouvelle input pour ajouter une anecdote
  // (voir <template> dans le html du form)
  function creerChampsAnecdote(value) {
    const anecdoteTemplateHtml = document.getElementById("anecdoteTemplate");
    const anecdoteHtml = document.importNode(
      anecdoteTemplateHtml.content,
      true
    );

    // Insère une valeur à l'input si besoin
    anecdoteHtml.querySelector(`input[name="fact"]`).value = value;
    anecdoteHtml
      .querySelector("#deleteFact")
      .addEventListener("click", supprimerChampsAnecdote);
    anecdoteHtml
      .querySelector(`input[name="fact"]`)
      .addEventListener("input", genererInfosDeFiche);

    // Ajoute l'input au DOM
    document.querySelector(".anecdotes-list").appendChild(anecdoteHtml);
    genererInfosDeFiche();
  }

  // Supression d'un input anecdote
  function supprimerChampsAnecdote(e) {
    const input = e.target.closest(".anecdote");
    input.remove();
    genererInfosDeFiche();
  }
});
Contenu sponsorisé