Garder des données après rafraichissement de la page

Résolu/Fermé
Frank_N Messages postés 42 Date d'inscription dimanche 3 juin 2018 Statut Membre Dernière intervention 8 août 2019 - 17 janv. 2019 à 13:32
Frank_N Messages postés 42 Date d'inscription dimanche 3 juin 2018 Statut Membre Dernière intervention 8 août 2019 - 18 janv. 2019 à 13:05
Bonjour à tous !

J'ai un petit problème depuis quelques jours maintenant avec mon code JS, le fonctionnement de la page est la suivante :

Je rentre des données dans un formulaire, et ces données doivent s'afficher au dessus des autres, mais elles doivent rester visible sur page quand je rafraichis celle-ci.
La subtilité est que les données que je rentre dans mon formulaire sont envoyé sur un serveur à l'aide de la fonction ajaxPost, et je dois récupérer ces données avec ajaxGet pour afficher les dernières données entrées sur le serveur.

Je vous laisse le code HTML, CSS et JS ci dessous :

<body>
    <h1>Activité 3</h1>

    <p>
        <button id="ajoutLien">Ajouter un lien</button>
    </p>
    <div id="resultat"></div>
    
    <!-- Les nouveaux éléments sont ajoutés dans cette balise -->
    <div id="contenu">
    </div>

</body>



<code css>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
background-color: #eee;
margin-left: 30px;
margin-right: 30px;
}

span {
font-weight: normal;
font-size: 80%;
}

.lien {
background: white;
padding: 10px;
margin-bottom: 10px;
}

.info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}</code>

console.clear();

// Exécute un appel AJAX GET
// Prend en paramètres l'URL cible et la fonction callback appelée en cas de succès
function ajaxGet(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url);
    req.addEventListener("load", function () {
        if (req.status >= 200 && req.status < 400) {
            // Appelle la fonction callback en lui passant la réponse de la requête
            callback(req.responseText);
        } else {
            console.error(req.status + " " + req.statusText + " " + url);
        }
    });
    req.addEventListener("error", function () {
        console.error("Erreur réseau avec l'URL " + url);
    });
    req.send(null);
}

function afficher(reponse) {
    console.log(reponse);
}

// Exécute un appel AJAX POST
// Prend en paramètres l'URL cible, la donnée à envoyer et la fonction callback appelée en cas de succès
// Le paramètre isJson permet d'indiquer si l'envoi concerne des données JSON
function ajaxPost(url, data, callback, isJson) {
    var req = new XMLHttpRequest();
    req.open("POST", url);
    req.addEventListener("load", function () {
        if (req.status >= 200 && req.status < 400) {
            // Appelle la fonction callback en lui passant la réponse de la requête
            callback(req.responseText);
        } else {
            console.error(req.status + " " + req.statusText + " " + url);
        }
    });
    req.addEventListener("error", function () {
        console.error("Erreur réseau avec l'URL " + url);
    });
    if (isJson) {
        // Définit le contenu de la requête comme étant du JSON
        req.setRequestHeader("Content-Type", "application/json");
        // Transforme la donnée du format JSON vers le format texte avant l'envoi
        data = JSON.stringify(data);
    }
    req.send(data);
}

/* 
Activité 2
*/

// Liste des liens Web à afficher. Un lien est défini par :
// - son titre
// - son URL
// - son auteur (la personne qui l'a publié)
var listeLiens = [
    {
        titre: "So Foot",
        url: "http://sofoot.com",
        auteur: "yann.usaille"
    },
    {
        titre: "Guide d'autodéfense numérique",
        url: "http://guide.boum.org",
        auteur: "paulochon"
    },
    {
        titre: "L'encyclopédie en ligne Wikipedia",
        url: "http://Wikipedia.org",
        auteur: "annie.zette"
    },
];

function afficherLiens(){
    ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function (reponse) {
        var liens = JSON.parse(reponse);
        var newLink = liens[0]; 
        newLink = creerElementLien(newLink);
        contenuElt.insertBefore(newLink, contenuElt.firstChild)
    });
}

function envoyerLien(lien){
    ajaxPost( "https://oc-jswebsrv.herokuapp.com/api/lien", lien, function(reponse) {
          var messageElt = document.createElement("p");
          messageElt.textContent = "Lien ajouté.";
          document.getElementById("resultat").appendChild(messageElt);
        },
        true);
}

// Crée et renvoie un élément DOM affichant les données d'un lien
// Le paramètre lien est un objet JS représentant un lien
function creerElementLien(lien) {
    var titreElt = document.createElement("a");
    titreElt.href = lien.url;
    titreElt.style.color = "#428bca";
    titreElt.style.textDecoration = "none";
    titreElt.style.marginRight = "5px";
    titreElt.appendChild(document.createTextNode(lien.titre));

    var urlElt = document.createElement("span");
    urlElt.appendChild(document.createTextNode(lien.url));

    // Cette ligne contient le titre et l'URL du lien
    var ligneTitreElt = document.createElement("h4");
    ligneTitreElt.style.margin = "0px";
    ligneTitreElt.appendChild(titreElt);
    ligneTitreElt.appendChild(urlElt);

    // Cette ligne contient l'auteur
    var ligneDetailsElt = document.createElement("span");
    ligneDetailsElt.appendChild(document.createTextNode("Ajouté par " + lien.auteur));

    var divLienElt = document.createElement("div");
    divLienElt.classList.add("lien");
    divLienElt.appendChild(ligneTitreElt);
    divLienElt.appendChild(ligneDetailsElt);

    return divLienElt;
}

var contenuElt = document.getElementById("contenu");
// Parcours de la liste des liens et ajout d'un élément au DOM pour chaque lien
listeLiens.forEach(function (lien) {
    var lienElt = creerElementLien(lien);
    contenuElt.appendChild(lienElt);
});

// Crée et renvoie un élément DOM de type input
function creerElementInput(placeholder, taille) {
    var inputElt = document.createElement("input");
    inputElt.type = "text";
    inputElt.setAttribute("placeholder", placeholder);
    inputElt.setAttribute("size", taille);
    inputElt.setAttribute("required", "true");
    return inputElt;
}

var ajouterLienElt = document.getElementById("ajoutLien");
// Gère l'ajout d'un nouveau lien
ajouterLienElt.addEventListener("click", function () {
    var auteurElt = creerElementInput("Entrez votre nom", 20);
    var titreElt = creerElementInput("Entrez le titre du lien", 40);
    var urlElt = creerElementInput("Entrez l'URL du lien", 40);

    var ajoutElt = document.createElement("input");
    ajoutElt.type = "submit";
    ajoutElt.value = "Ajouter";

    var formAjoutElt = document.createElement("form");
    formAjoutElt.appendChild(auteurElt);
    formAjoutElt.appendChild(titreElt);
    formAjoutElt.appendChild(urlElt);
    formAjoutElt.appendChild(ajoutElt);

    var p = document.querySelector("p");
    // Remplace le bouton d'ajout par le formulaire d'ajout
    p.replaceChild(formAjoutElt, ajouterLienElt);

    // Ajoute le nouveau lien
    formAjoutElt.addEventListener("submit", function(e) {
        e.preventDefault();
        
        var url = urlElt.value;
        // Si l'URL ne commence ni par "http://" ni par "https://"
        if ((url.indexOf("http://") !== 0) && (url.indexOf("https://") !== 0)) {
            // On la préfixe par "http://"
            url = "http://" + url;
        }

        // Création de l'objet contenant les données du nouveau lien
        var lien = {
            titre: titreElt.value,
            url: url,
            auteur: auteurElt.value
        };

        /*var lienElt = creerElementLien(lien);
        // Ajoute le nouveau lien en haut de la liste
        contenuElt.insertBefore(lienElt, contenuElt.firstChild);*/

        // Remplace le formulaire d'ajout par le bouton d'ajout
        p.replaceChild(ajouterLienElt, formAjoutElt);

        // Création du message d'information
        var infoElt = document.createElement("div");
        infoElt.classList.add("info");
        infoElt.textContent = "Le lien \"" + lien.titre + "\" a bien été ajouté.";
        p.insertBefore(infoElt, ajouterLienElt);
        // Suppresion du message après 2 secondes
        setTimeout(function () {
            p.removeChild(infoElt);
        }, 2000);

        envoyerLien(lien)

        afficherLiens();    
    })
});


Mes deux problèmes actuels sont que ce n'est pas le lien que j'ai rentré qui est affiché en dernier (mais l'avant dernier) et le fait que le lien n'est plus présent quand je rafraichis la page..
J'en demande peut être beaucoup mais si vous pouviez m'éxpliquer en même temps la logique d'une possible solution :)

(le code est dispo aussi à cette adresse : https://codepen.io/Frank-Ngy/pen/zyXxxK?editors=1010)

Merci d'avance !

Configuration: Windows / Firefox 64.0
A voir également:

2 réponses

jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
Modifié le 17 janv. 2019 à 14:23
Bonjour,

As tu la main sur le script qui est appellé par tes requêtes ajax ?
https://oc-jswebsrv.herokuapp.com/api/liens

J'ai l'impression que tu es en train de suivre un tuto ... et que la fonction d'enregistrement des liens n'est pas opérationnelle (pour éviter que 100000 personnes s'amusent à ajouter de nouveaux liens )
Il semblerait donc normal que tu ne puisses récupérer que les liens qui avaient été enregistrés par le créateur du webservice.

Après.. au cas où.. il serait bien de regarder dans la console de ton navigateur ce qui se passe lorsque tu ajoutes un nouveau lien...
Pour débuguer de l'ajax, je te conseille de privilégier le navigateur FireFox
Ca te permettra de voir assez facilement le résultat de la requête Ajax
par exemple :








0
Frank_N Messages postés 42 Date d'inscription dimanche 3 juin 2018 Statut Membre Dernière intervention 8 août 2019
17 janv. 2019 à 14:35
Le script des requêtes ajax commence à la ligne 5 du code JS (normalement ajaxGet et ajaxPost sont situés dans un fichier JS a part mais ici il est directement dans le code comme je ne suis plus en local)

Ensuite c'est un exercice (OpenClassrooms) et l'envoi du lien est bien opérationnel (on peut le voir affiché à cette adresse https://oc-jswebsrv.herokuapp.com/api/liens quand le formulaire à été envoyé) il apparait a la première place (emplacement [0] du tableau) mais le souci est l'appel, si on éssaye d'envoyer le lien dans le formulaire, celui ci apparaitra bien dans l'api "liens" mais sur ma page c'est le dernier avant le mien qui sera affiché

Quand je fais ce que tu me dis avec la console j'obtient bien le bon ID de mon lien qui à été envoyé, mais c'est l'ID précédent du tableau qui est affiché en premier sur ma page
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
17 janv. 2019 à 17:31

Le script des requêtes ajax commence à la ligne 5 du code JS (normalement ajaxGet et ajaxPost sont situés dans un fichier JS a part mais ici il est directement dans le code comme je ne suis plus en local)

Je parle du script côté serveur.
Et donc non... vu ta réponse.. tu n'y a pas accès..

Il faut que je teste de mon côté ton tuto... car c'est peut-être juste un souci dans le fonctionnement de l'api et non un problème de code de ton côté.
Donne moi le lien du tuto que je puisse regarder.
0
Frank_N Messages postés 42 Date d'inscription dimanche 3 juin 2018 Statut Membre Dernière intervention 8 août 2019
17 janv. 2019 à 17:35
Merci déjà de prendre du temps pour pouvoir regarder :)
Je te passe le lien de l'éxercice (car oui c'est un exercice et non un tuto) et les éléments que j'ai ajouter jusque là sont les fonctions envoyerLien(), afficherLiens() (lien vers l'exo => https://openclassrooms.zendesk.com/hc/fr/articles/360002865957-%C3%89volution-des-activit%C3%A9s-corrig%C3%A9es-par-les-pairs )
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
17 janv. 2019 à 18:09
Je viens de voir....

Quand tu recharges la page ... tu es sensé récupérer la liste des liens en ajax...
mais il semble que toi, tu as conservé ce que tu avais fait dans l'activité précédente
et ta liste de lien est créée via
var contenuElt = document.getElementById("contenu");
// Parcours de la liste des liens et ajout d'un élément au DOM pour chaque lien
listeLiens.forEach(function (lien) {
    var lienElt = creerElementLien(lien);
    contenuElt.appendChild(lienElt);
});

A aucun moment tu ne sembles faire appel au ws pour récupérer cette liste
0
Frank_N Messages postés 42 Date d'inscription dimanche 3 juin 2018 Statut Membre Dernière intervention 8 août 2019
Modifié le 18 janv. 2019 à 13:27
Merci ! J'ai un autre soucis qui ne viens de je ne sais où ... ma version du code dans codePen fonctionne parfaitement bien, mais en locale j'ai l'érreur "ajaxGet is not defined" pourtant le script du fichier ajax.js où se trouve cette fonction ajaxGet est bien présente dans mon HTML
Voici le nouveau code JS :

/* 
Activité 3
*/

// Crée et renvoie un élément DOM affichant les données d'un lien
// Le paramètre lien est un objet JS représentant un lien
function creerElementLien(lien) {
    var titreElt = document.createElement("a");
    titreElt.href = lien.url;
    titreElt.style.color = "#428bca";
    titreElt.style.textDecoration = "none";
    titreElt.style.marginRight = "5px";
    titreElt.appendChild(document.createTextNode(lien.titre));

    var urlElt = document.createElement("span");
    urlElt.appendChild(document.createTextNode(lien.url));

    // Cette ligne contient le titre et l'URL du lien
    var ligneTitreElt = document.createElement("h4");
    ligneTitreElt.style.margin = "0px";
    ligneTitreElt.appendChild(titreElt);
    ligneTitreElt.appendChild(urlElt);

    // Cette ligne contient l'auteur
    var ligneDetailsElt = document.createElement("span");
    ligneDetailsElt.appendChild(document.createTextNode("Ajouté par " + lien.auteur));

    var divLienElt = document.createElement("div");
    divLienElt.classList.add("lien");
    divLienElt.appendChild(ligneTitreElt);
    divLienElt.appendChild(ligneDetailsElt);

    return divLienElt;
}

function envoyerLien(lien){
    ajaxPost("https://oc-jswebsrv.herokuapp.com/api/lien", lien, function(reponse) {
          var messageElt = document.createElement("p");
          messageElt.textContent = "Lien ajouté.";
          document.getElementById("resultat").appendChild(messageElt);
          afficherLiens();
        },
        true);
}

function afficherLiens(){
    ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function (reponse) {
        var liens = JSON.parse(reponse);
        var newLink = liens[0]; 
        newLink = creerElementLien(newLink);
        contenuElt.insertBefore(newLink, contenuElt.firstChild)
    });
}

var contenuElt = document.getElementById("contenu");

ajaxGet("https://oc-jswebsrv.herokuapp.com/api/liens", function (reponse) {
        var liens = JSON.parse(reponse);
        liens.forEach(function (lien) {
        var newLink = creerElementLien(lien);
        contenuElt.appendChild(newLink)
        });
});

// Crée et renvoie un élément DOM de type input
function creerElementInput(placeholder, taille) {
    var inputElt = document.createElement("input");
    inputElt.type = "text";
    inputElt.setAttribute("placeholder", placeholder);
    inputElt.setAttribute("size", taille);
    inputElt.setAttribute("required", "true");
    return inputElt;
}

var ajouterLienElt = document.getElementById("ajoutLien");
// Gère l'ajout d'un nouveau lien
ajouterLienElt.addEventListener("click", function () {
    var auteurElt = creerElementInput("Entrez votre nom", 20);
    var titreElt = creerElementInput("Entrez le titre du lien", 40);
    var urlElt = creerElementInput("Entrez l'URL du lien", 40);

    var ajoutElt = document.createElement("input");
    ajoutElt.type = "submit";
    ajoutElt.value = "Ajouter";

    var formAjoutElt = document.createElement("form");
    formAjoutElt.appendChild(auteurElt);
    formAjoutElt.appendChild(titreElt);
    formAjoutElt.appendChild(urlElt);
    formAjoutElt.appendChild(ajoutElt);

    var p = document.querySelector("p");
    // Remplace le bouton d'ajout par le formulaire d'ajout
    p.replaceChild(formAjoutElt, ajouterLienElt);

    // Ajoute le nouveau lien
    formAjoutElt.addEventListener("submit", function(e) {
        e.preventDefault();
        
        var url = urlElt.value;
        // Si l'URL ne commence ni par "http://" ni par "https://"
        if ((url.indexOf("http://") !== 0) && (url.indexOf("https://") !== 0)) {
            // On la préfixe par "http://"
            url = "http://" + url;
        }

        // Création de l'objet contenant les données du nouveau lien
        var lien = {
            titre: titreElt.value,
            url: url,
            auteur: auteurElt.value
        };

        // Envoi du lien vers le serveur
        envoyerLien(lien)

        // Remplace le formulaire d'ajout par le bouton d'ajout
        p.replaceChild(ajouterLienElt, formAjoutElt);

        // Création du message d'information
        var infoElt = document.createElement("div");
        infoElt.classList.add("info");
        infoElt.textContent = "Le lien \"" + lien.titre + "\" a bien été ajouté.";
        p.insertBefore(infoElt, ajouterLienElt);
        // Suppresion du message après 2 secondes
        setTimeout(function () {
            p.removeChild(infoElt);
        }, 2000);
    })
});


et mon codePen: https://codepen.io/Frank-Ngy/pen/zyXxxK?editors=0010

EDIT: probleme résolu ! j'ai mis le script dans le <head> de mon HTML tout simplement :)
0