IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Conserver les données du formulaire après un refresh


Sujet :

JavaScript

  1. #41
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 205
    Par défaut
    Je pense que tu n'as pas bien analysé les relations entre tes différents objets.
    J'ai dis
    Citation Envoyé par NoSmoking
    En fait la liaison/relation est Réservation -> Chrono et non l'inverse, qu'est ce qui déclenche le Chrono ... la validation de la réservation ... donc la classe Reservation devrait instancier son propre Chrono.
    donc dans le constructor de ta Reservation tu ne devrais pas avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     class Reservation {
        constructor(station, min, sec) {
             // ...
             this.chrono = new Chrono(20);
             // ...
        }
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     class Reservation {
        constructor(station, min, sec) {
             // ...
             this.chrono = null;
             // ...
        }
    ce n'est qu'à la validation de la réservation que tu affectes/déclenches un chrono.

    De même dans le constructor de ta classe Storage tu en devrais pas avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Storage {
     
        constructor(station) {
            this.station = station;
            this.chrono = new Chrono(20);
        }
    pour moi elle devrait être minimum, voire inexistante, elle ne fait que lire et écrire dans le store.

    Dans le onload, tu récupères le Chrono, l'exemple que j'avais fourni était hors ton contexte, juste pour te montrer la faisabilité donc pas utilisable en l'état.
    Tu devrais plutôt récupérer la réservation en cours si existe et l'échéance de celle-ci.

    Peut-être devrais tu prendre un papier et un crayon pour bien analyse les relations entre tes différents objets Map -> Markers -> Formulaire -> Reservation et le rôle attribué à chacun.

  2. #42
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Rien à faire je boss depuis ce matin et là je sature, j'attendrais de voir ça avec mon mentor samedi pour avoir de l'aide.

  3. #43
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Me voila de retour après un mini break (j'en avais besoin, je suis sur ce projet depuis pas mal de temps et il fallait que je déconnecte un peu...)

    J'ai réussi à proposer quelque chose de fonctionnel. Sauf que je ne réussis pas à arrêter le chrono quand je clique sur annuler, mais après un refresh, le chrono s'arrête lorsque j'effectue le clique.

    Je mets le code

    Class Formulaire



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    class Formulaire {
        constructor(station) {
            this.station = station;
            this.champsRequis();
            this.switchButton();
            this.checkFormulaire();
            this.valider();
            this.annuler();
        }
     
        checkFormulaire() {
            const datas = Storage.hasUserInfo();
            if (datas) {
                Dom.firstnameElement.value = Storage.getFirstname();
                Dom.lastnameElement.value = Storage.getLastname();
            }
        }
     
        champsRequis() {
            Dom.reserveElement.addEventListener('click', () => {
     
                if (Dom.firstnameElement.value == '' && Dom.lastnameElement.value == '') {
                    alert('Veuillez renseigner votre nom et votre prénom');
                } else {
                    Dom.canvasElement.style.visibility = 'visible';
                    Dom.canvasElement.style.transitionDuration == "500ms";
                    Dom.signElement.style.display = 'flex';
                    Dom.formElement.style.height = "auto";
                }
            });
        }
     
        switchButton() {
            //Lorsqu'on clique sur le canvas, on switch le bouton réserver par le bouton valider
            Dom.canvasElement.addEventListener('click', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
     
            Dom.canvasElement.addEventListener('touchend', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
        }
     
        valider() {
            Dom.validateElement.addEventListener('click', () => {
                const reservation = new Reservation(this.station);
                reservation.startReservation();
                Dom.validateElement.style.display = 'none';
                Dom.canvasElement.style.display = 'none';
                Dom.textChronoElement.style.display = 'inline';
                Dom.cancelButtonElement.style.display = 'flex';
                //Nouvelle instance de la class Réservation
            });
        }
     
        annuler() {
            Dom.cancelButtonElement.addEventListener('click', () => {
                const resa = new Reservation();
                resa.annulerReservation();
                Dom.cancelButtonElement.style.display = 'none';
                Dom.reserveElement.style.display = 'none';
                //Nouvelle instance de la class Réservation
            });
        }
    }



    Class Reservation


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    class Reservation {
        constructor(station, min, sec) {
            this.min = min;
            this.sec = sec;
            this.station = station;
        }
     
        startReservation() {
     
            //Nouvelle instance de la class Chrono
            const chrono = new Chrono(20);
            chrono.startTimer();
     
            //Nouvelle instance de la class Storage
            const storage = new Storage(this.station, chrono);
            storage.store(this.station);
     
            window.addEventListener('beforeunload', () => {
                const datas = chrono.timeEnd;
                const tempsRestant = datas - Date.now();
                if (tempsRestant > 0) {
                    sessionStorage.setItem('timeEnd', chrono.timeEnd);
                }
            });
     
     
        }
     
        annulerReservation() {
            sessionStorage.clear();
            chrono.stopTimer();
     
        }
    }
     
    const chrono = new Chrono();
     
    window.addEventListener("load", function(event) {
        const timeEnd = +sessionStorage.getItem("timeEnd");
        const tempsRestant = timeEnd - Date.now();
        if (tempsRestant > 0) {
            Dom.textChronoElement.style.display = 'inline';
            Dom.cancelButtonElement.style.display = 'flex';
            chrono.startTimer(timeEnd);
        }
    });



    Class Chrono


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    class Chrono {
        constructor(minutes = 0, secondes = 0) {
            this.duree = ((minutes * 60) + secondes) * 1000;
            this.iTimer = null;
            this.timeEnd;
        }
     
        startTimer(timeEnd) {
            if (timeEnd) {
                this.timeEnd = timeEnd;
            } else {
                this.timeEnd = Date.now() + this.duree;
            }
            this.iTimer = setInterval(() => {
                this.decompteTimer();
            }, 1000);
            this.decompteTimer();
        }
     
        stopTimer() {
            clearInterval(this.iTimer);
            this.iTimer = null;
        }
     
        decompteTimer() {
     
            const reste = Math.ceil((this.timeEnd - Date.now()) / 1000);
            if (reste > 0) {
                Dom.chronoElement.textContent = ('0' + parseInt((reste % 3600) / 60, 10)).slice(-2) + ':' + ('0' + parseInt((reste % 3600) % 60, 10)).slice(-2);
                console.log(Dom.chronoElement.textContent);
            } else {
                this.stopTimer();
                Dom.chronoElement.textContent = parseInt('0') + ' : ' + parseInt('0');
                Dom.textChronoElement.textContent = 'Comptage terminé !';
                Dom.reserveElement.style.display = 'block';
                Dom.cancelButtonElement.style.display = 'none';
            }
     
     
        }
    }


    Class Storage


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    class Storage {
     
        constructor(station, chrono) {
            this.station = station;
            this.chrono = chrono;
        }
     
        store(station) {
            sessionStorage.setItem("timeEnd", this.chrono.timeEnd);
            sessionStorage.setItem("station", JSON.stringify(station)); 
            localStorage.setItem("firstname", Dom.firstnameElement.value);
            localStorage.setItem('lastname', Dom.lastnameElement.value);
     
        }
     
        static clear() {
            return sessionStorage.clear();
        }
     
        static getTimeEnd() {
            return sessionStorage.getItem('timeEnd');
        }
     
        static getStation() {
            return JSON.parse(sessionStorage.getItem("station"));
        }
     
        static getFirstname() {
            return localStorage.getItem("firstname");
        }
     
        static getLastname() {
            return localStorage.getItem("lastname");
        }
     
        static hasUserInfo() {
            return typeof localStorage.getItem('firstname') !== null && localStorage.getItem('lastname') !== null;
        }
     
        static hasStationInfo() {
            return sessionStorage.getItem('station') !== null;
        }
     
        static hasStorageInfo() {
            return typeof sessionStorage.getItem('timeEnd') !== null;
     
        }
    };

    (Le code peut paraitre different de celui que vous aviez proposé, j'ai seulement essayé d'adapter en reprenant depuis le début).


    Donc ma question est pourquoi je n'arrive pas à arrêter le chrono lors du clique, en sachant qu'après un refresh cela fonctionne. (Dans ma méthode annnulerReservation, il me semble bien que je récupère le chrono en cours ? )

  4. #44
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    Rapidement :
    Il y a une erreur qui revient encore :
    Ici, on crée une instance chrono :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    startReservation() {
            const chrono = new Chrono(20);
            chrono.startTimer();
    Mais ici, on ne se réfère pas à la même instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    annulerReservation() {
            sessionStorage.clear();
            chrono.stopTimer();
    Pareil ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            Dom.validateElement.addEventListener('click', () => {
                const reservation = new Reservation(this.station);
                reservation.startReservation();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            Dom.cancelButtonElement.addEventListener('click', () => {
                const resa = new Reservation();
                resa.annulerReservation();
    L'annulation de la réservation ne s'applique pas sur l'instance sur laquelle on l'a démarrée, mais sur une nouvelle.

    C'est exactement pareil que si on faisait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    let conducteur=new Conducteur();
    conducteur.demarrerMonVehicule();
     
    conducteur=new Conducteur(); //on crée un nouveau conducteur, ce n'est plus le même conducteur qu'avant
    conducteur.arreterMonVehicule(); //cela n'arrêtera pas le véhicule du conducteur précédent
    Pour le "storage" :
    - Soit il faut supprimer l'événement "beforeunload" dans annulerReservation.
    - Soit il faut déplacer la création de l'événement "beforeunload" (dans le constructeur ou ailleurs dans le code), et gérer toute l'écriture/mise à jour/effacement dans la fonction exécutée dans le "beforeunload". Dans ce cas, il faut retirer sessionStorage.clear(); de la fonction annulerReservation.

  5. #45
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Merci pour votre analyse,

    Effectivement je n'ai pas fais gaffe, du coup j'ai déclaré une nouvelle instance global dans les 2 classes à savoir Formulaire et Reservation

    Et concernant le storage j'ai essayé votre première proposition à savoir supprimer l'évènement beforeunload dans annulerReservation() avec l'évènement removeEventListener


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
     
    class Reservation {
        constructor(station, min, sec) {
            this.min = min;
            this.sec = sec;
            this.station = station;
            this.beforeunload;
        }
     
        startReservation() {
            chrono.startTimer();
     
            //Nouvelle instance de la class Storage
            const storage = new Storage(this.station, chrono);
            storage.store(this.station);
     
     
            const datas = chrono.timeEnd;
            const tempsRestant = datas - Date.now();
     
            function check() {
                if (tempsRestant > 0) {
                    sessionStorage.setItem('timeEnd', chrono.timeEnd);
                }
            }
     
            this.beforeunload = window.addEventListener('beforeunload', () => {
                return datas + tempsRestant + check();
     
            });
        }
     
        annulerReservation() {
            sessionStorage.clear();
            window.removeEventListener('beforeunload', this.beforeunload);
            chrono.stopTimer();
     
        }
    }
     
    const chrono = new Chrono(20);
     
    window.addEventListener("load", function(event) {
        const timeEnd = +sessionStorage.getItem("timeEnd");
        const tempsRestant = timeEnd - Date.now();
        if (tempsRestant > 0) {
            Dom.textChronoElement.style.display = 'inline';
            Dom.cancelButtonElement.style.display = 'flex';
            chrono.startTimer(timeEnd);
        }
    });



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     valider() {
            Dom.validateElement.addEventListener('click', () => {
                reservation.startReservation();
                Dom.validateElement.style.display = 'none';
                Dom.canvasElement.style.display = 'none';
                Dom.textChronoElement.style.display = 'inline';
                Dom.cancelButtonElement.style.display = 'flex';
                //Nouvelle instance de la class Réservation
            });
        }
     
        annuler() {
            Dom.cancelButtonElement.addEventListener('click', () => {
                reservation.annulerReservation();
                Dom.cancelButtonElement.style.display = 'none';
                Dom.reserveElement.style.display = 'none';
                //Nouvelle instance de la class Réservation
            });
        }
    }
     
    const reservation = new Reservation();
    Cela a corrigé mon problème , je peux maintenant arrêter le chrono après avoir valider sans recharger la page. Mais lorsque j'actualise la page (après avoir validé) j'ai ce message dans la console (qui vient de mon JSON) malgré que le chrono continue de tourner :




    "VM51:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at Function.getStation (Storage.js:29)
    at Map.checking (Map.js:51)
    at new Map (Map.js:12)
    at Map.js:59"



    Par ailleurs le problème est maintenant inverse, je n'arrive pas à arrêter le chrono après avoir rechargé la page....

  6. #46
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Je prends juste le temps de corriger une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            window.addEventListener('beforeunload', this.beforeunload = () => {
                return datas + tempsRestant + check();
     
            });
    Le contenu de la fonction est très étrange !

  7. #47
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Merci pour la correction !

    Pour la fonction j'ai voulu suivre un modèle que j'ai trouvé via le MDN concernant la portée des variables.... mais je pense que je vais laisser les choses comme elles étaient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     window.addEventListener('beforeunload', this.beforeunload = () => {
                const datas = chrono.timeEnd;
                const tempsRestant = datas - Date.now();
                if (tempsRestant > 0) {
                    sessionStorage.setItem('timeEnd', chrono.timeEnd);
                }
            });

    Je testerai ça demain.

    Je précise que pour l'objet chrono je l'instancie dans une portée global afin de pouvoir le récupérer plus facilement. Si j'instancie le chrono à l'intérieur (dans une méthode) je ne vais pas réussir à le récupérer dans une autre méthode ( à moins que cela soit possible ?)

  8. #48
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Après avoir revu le code avec mon mentor, j'ai déjà pu régler mes soucis avec le this, car en effet plutôt que de déclarer une instance en global il fallait rester à l'intérieur des classes. j'avais jusqu'alors pas encore bien compris la différence entre const et this.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    class Reservation {
        constructor(station) {
            this.station = station;
            this.onload();
            this.onbeforeunload();
        }
     
        startReservation() {
            this.chrono = new Chrono(20);
            this.chrono.startTimer();
            Storage.store(this.station, this.chrono);
            console.log(this.station);
        }
     
        onload() {
            window.addEventListener("load", this.loadEvent.bind(this));
        }
     
        onbeforeunload() {
            window.addEventListener('beforeunload', this.handlerChrono.bind(this));
        }
     
        handlerChrono() {
            console.log('datas', this.chrono.timeEnd);
            this.chrono.tempsRestant = this.chrono.timeEnd - Date.now();
            if (this.chrono.tempsRestant > 0) {
                sessionStorage.setItem('timeEnd', this.chrono.timeEnd);
            }
        }
     
        loadEvent() {
     
            this.chrono = new Chrono();
            this.chrono.timeEnd = Storage.getTimeEnd();
            this.chrono.tempsRestant = this.chrono.timeEnd - Date.now();
            if (this.chrono.tempsRestant > 0) {
                this.chrono.startTimer(this.chrono.timeEnd);
                Dom.textChronoElement.style.display = 'inline';
                Dom.reserveElement.style.display = 'none';
                Dom.cancelButtonElement.style.display = 'flex';
     
            }
        }
     
        annulerReservation() {
            Storage.getClear();
            window.removeEventListener('beforeunload', this.handlerChrono());
            this.chrono.stopTimer();
        }
    }


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    class Formulaire {
        constructor(station) {
     
            this.station = station;
            console.log(this.station);
            this.dataUser();
            this.eventUser();
            this.initValidate();
            this.initCancel();
        }
     
        dataUser() {
            console.log('On vérifie si les données users existent')
            this.users = Storage.hasUserInfo();
            if (this.users) {
                console.log(this.users);
                console.log('les données users existent');
                Dom.firstnameElement.value = Storage.getFirstname();
                Dom.lastnameElement.value = Storage.getLastname();
            }
        }
     
        checkDatas() {
            if (sessionStorage.getItem('reservation')) {
                console.log('reservation , ', sessionStorage.getItem('reservation'));
                this.reservation = sessionStorage.getItem('reservation');
            }
        }
     
        eventUser() {
            Dom.reserveElement.addEventListener('click', () => {
     
                if (Dom.firstnameElement.value == '' && Dom.lastnameElement.value == '') {
                    alert('Veuillez renseigner votre nom et votre prénom');
                } else {
                    Dom.canvasElement.style.visibility = 'visible';
                    Dom.canvasElement.style.transitionDuration == "500ms";
                    Dom.signElement.style.display = 'flex';
                    Dom.formElement.style.height = "auto";
                }
            });
            //Lorsqu'on clique sur le canvas, on switch le bouton réserver par le bouton valider
            Dom.canvasElement.addEventListener('click', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
     
            Dom.canvasElement.addEventListener('touchend', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
        }
     
     
        valider() {
            this.reservation = new Reservation(this.station);
            this.reservation.startReservation();
            this.displayResa();
            sessionStorage.setItem('reservation', this.reservation);
            console.log(this.reservation);
        }
     
        annuler() {
            console.log('annuler');
            this.reservation.annulerReservation();
            this.hideResa();
        }
     
        displayResa() {
            console.log('display resa')
            Dom.validateElement.style.display = 'none';
            Dom.canvasElement.style.display = 'none';
            Dom.textChronoElement.style.display = 'inline';
            Dom.cancelButtonElement.style.display = 'flex';
        }
     
        hideResa() {
            Dom.cancelButtonElement.style.display = 'none';
            Dom.reserveElement.style.display = 'none';
        }
     
        initValidate() {
            Dom.validateElement.addEventListener('click', this.valider.bind(this));
        }
     
        initCancel() {
            Dom.cancelButtonElement.addEventListener('click', this.annuler.bind(this));
        }
    }

    Mais lorsque je refresh la page , j'ai toujours le timeEnd de stocké en session mais mon formulaire se réinitialise (plus d'affichage du chrono, comme si je revenais au point de départ)...


    "Storage*{timeEnd: "1598093495024",
    station: "{"status":"OPEN","name":"02- LES HALLES","address"… J Natiere","available_bikes":4,"bike_stands":20}",
    length: 3
    }"



    Je m'attends à ce que ceci s'exécute après le rechargement de la page :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      if (this.chrono.tempsRestant > 0) {
                this.chrono.startTimer(this.chrono.timeEnd);
                Dom.textChronoElement.style.display = 'inline'; //Texte du chrono
                Dom.reserveElement.style.display = 'none'; //Bouton reserver caché
                Dom.cancelButtonElement.style.display = 'flex'; //Bouton Annuler toujours visible
     
            }
    Mais cela ne s'execute pas ou du moins rien d'apparent dans le formulaire.

  9. #49
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    J'ai regardé juste un passage et je vois de nouveau la même erreur qui revient : à un endroit, vous utilisez une référence, et, à un autre endroit, vous n'utilisez plus la même référence.

    Je parle de ces deux lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    window.addEventListener('beforeunload', this.handlerChrono.bind(this));
     
    window.removeEventListener('beforeunload', this.handlerChrono());
    1) On est d'accord que removeEventListener doit utiliser le même écouteur que addEventListener ?

    Or :
    2) this.handlerChrono() se réfère-t-il au même objet que this.handlerChrono.bind(this) ?

    Questions complémentaires :
    3) Comment savoir si deux références/valeurs sont identiques ?

    A partir de là :
    4) this.handlerChrono se réfère-t-il au même objet que this.handlerChrono.bind(this) ?
    5) this.handlerChrono.bind(this) se réfère-t-il au même objet que this.handlerChrono.bind(this) ?
    6) this.handlerChrono se réfère-t-il au même objet que this.handlerChrono ?

    7) Quel moyen très simple permet d'utiliser la même référence dans removeEventListener que dans addEventListener ?
    Indication : Ce moyen a été déjà été donné.

    Si vous trouvez la réponse à toutes ces questions, vous aurez fait un net progrès !

    Citation Envoyé par Lunesti Voir le message
    Après avoir revu le code avec mon mentor, j'ai déjà pu régler mes soucis avec le this, car en effet plutôt que de déclarer une instance en global il fallait rester à l'intérieur des classes.
    Les deux approches sont possibles, mais oui c'est mieux comme ça, c'est ce que j'avais déjà dit.

    Citation Envoyé par Lunesti Voir le message
    j'avais jusqu'alors pas encore bien compris la différence entre const et this.
    Encore une fois, je ne peux que répéter ce que j'avais dit : on ne vous fait pas faire les choses dans le bon ordre.

    Le bon ordre :
    1) Savoir trouver les erreurs (nombreux affichages, désactivation de morceaux de code, tests simples à part, consulter de la documentation, faire des recherches en utilisant les bons mots clés). Cela permet une autonomie quasi-totale.
    2) Bien maîtriser les bases : différences this/const etc.
    3) Seulement enfin s'intéresser aux classes.

    Là vous êtes dans l'ordre inverse, un peu malgré vous.

  10. #50
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Citation Envoyé par Loralina Voir le message
    1) On est d'accord que removeEventListener doit utiliser le même écouteur que addEventListener ?
    Oui !

    Or :
    2) this.handlerChrono() se réfère-t-il au même objet que this.handlerChrono.bind(this) ?
    J'ai essayé de comprendre, au risque encore de me tromper mais j'ai pu faire quelque chose qui ressemble à une des solutions que j'ai pu trouver sur le site stackoverflow : https://stackoverflow.com/questions/...-in-javascript


    J'ai appliqué le même principe.

    le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
        handlerChrono() {
            this.onbeforeunload = function() {
                //console.log('datas', this.chrono.timeEnd);
                this.chrono.tempsRestant = this.chrono.timeEnd - Date.now();
                if (this.chrono.tempsRestant > 0) {
                    sessionStorage.setItem('timeEnd', this.chrono.timeEnd);
                }
            }
            window.addEventListener('beforeunload', this.onbeforeunload());
        }
     
     
        annulerReservation() {
            Storage.getClear();
            window.removeEventListener('beforeunload', this.onbeforeunload());
            this.chrono.stopTimer();
        }
    J'ai bien compris qu'il fallait utiliser le même écouteur que addEventListener. Donc , cette ligne me semble correct :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     window.removeEventListener('beforeunload', this.onbeforeunload());
    car this.onbeforeunload() est bien une fonction, et je la passe en paramètre.

    .... mais cela ne marche (toujours) pas. j'ai toujours le timeEnd de stocké en session mais mon formulaire se réinitialise après un refresh.




    Si vous trouvez la réponse à toutes ces questions, vous aurez fait un net progrès !
    Alors dans le cas que j'ai proposé je pense que lorsque j'utilise l'écouteur removeEventListener la fonction this.onbeforeunload() se réfère au même objet que this.onbeforeunload() dans addEventListener.



    Là vous êtes dans l'ordre inverse, un peu malgré vous.
    Oui, je me suis lancé dans la bataille de ce projet mais au fur et à mesure je me suis rendu compte qu'il me manquait encore pas mal d'élément à assimiler (exemple: forEach(), pouvoir appeler des méthodes dans le constructeur, récupérer des éléments d'une autre class, etc) vous voyez il y a des choses que je ne savais même pas qu'on pouvait faire. Et sur internet on trouve plus de procédural que de code orienté POO.


    Enfin bon, c'était juste une petite parenthèse ^^


    Merci en tout cas pour votre aide.

  11. #51
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Je donne les réponses à mes questions :

    1) On est d'accord.

    2) Non, this.handlerChrono() ne se réfère pas au même objet que this.handlerChrono.bind(this).

    3) Là, c'était la question essentielle !
    La réponse est tellement évidente pourtant :
    Pour savoir si deux choses sont égales, on affiche le résultat de la comparaison de ces deux choses avec console.log ou alert.

    4) Non, en effet console.log(this.handlerChrono===this.handlerChrono.bind(this)) affiche false.

    5) Non, en effet console.log(this.handlerChrono.bind(this)===this.handlerChrono.bind(this)) affiche false.

    6) Oui, en effet console.log(this.handlerChrono===this.handlerChrono) affiche true.

    7) Alors là, c'était pourtant si simple : j'ai mis la solution ici.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    window.addEventListener('beforeunload', this.beforeunload = this.handlerChrono.bind(this));
     
    window.removeEventListener('beforeunload', this.beforeunload);
    Ne paraît-il pas évident qu'en faisant comme ça, removeEventListener utilisera le même écouteur ?
    Où est la difficulté ?


    Citation Envoyé par Lunesti Voir le message
    window.addEventListener('beforeunload', this.onbeforeunload());
    Ne pas confondre un appel de fonction, this.onbeforeunload(), et une référence à la fonction, this.onbeforeunload.
    Ici, l'écouteur serait le retour de la fonction et pas la fonction elle-même, ce n'est pas ce qu'on veut.


    Comme je l'ai montré au-dessus afficher des valeurs en toute simplicité est un réflexe indispensable pour mettre sur la voie.
    Une autre chose très importante que j'ai signalée : faire des tests simples à part.

    En voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>
    const uneConstanteGlobale=new Object();
     
    function tutu() {return new Object()};
    function titi() {return uneConstanteGlobale;};
     
    console.log(tutu===tutu); //true
    console.log(tutu()===tutu()); //false
     
    console.log(titi===titi); //true
    console.log(titi()===titi()); //true
    </script>
    J'espère que les résultats vous paraissent évidents.

    Je complique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>
    const uneConstanteGlobale=function(){alert("fonction uneConstanteGlobale")};
     
    function tutu() {alert("tutu");return function(){alert("fonction retournée par tutu")}};
    function titi() {alert("titi");return uneConstanteGlobale;};
     
    //tester un exemple à la fois
    window.addEventListener('load',tutu);window.removeEventListener('load',tutu); //pas d'affichage
    //window.addEventListener('load',tutu());window.removeEventListener('load',tutu()); //tutu, tutu, fonction retournée par tutu
    //window.addEventListener('load',titi);window.removeEventListener('load',titi); //pas d'affichage
    //window.addEventListener('load',titi());window.removeEventListener('load',titi()); //titi, titi
    </script>

  12. #52
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    J'ai enfin pu résoudre le problème !!!

    Tout d'abord j'ai transféré le load dans la class Formulaire via une méthode car cela ne fonctionnait pas dans la class Reservation.

    Puis j'ai déclaré une nouvelle instance global de l'objet Reservation afin que mes écouteurs d’événements soient pointé vers le même objet.

    J'ai repris et adapté le code de Loralina concernant la récupération du chrono lors du refresh.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    class Formulaire {
        constructor(station) {
     
            this.station = station;
            console.log(this.station);
            this.dataUser();
            this.eventUser();
            this.initValidate();
            this.initCancel();
            this.onloadMethod();
        }
     
        dataUser() {
            console.log('On vérifie si les données users existent')
            this.users = Storage.hasUserInfo();
            if (this.users) {
                console.log(this.users);
                console.log('les données users existent');
                Dom.firstnameElement.value = Storage.getFirstname();
                Dom.lastnameElement.value = Storage.getLastname();
            }
        }
     
        checkDatas() {
            if (sessionStorage.getItem('reservation')) {
                console.log('reservation , ', sessionStorage.getItem('reservation'));
                this.reservation = sessionStorage.getItem('reservation');
            }
        }
     
        eventUser() {
            Dom.reserveElement.addEventListener('click', () => {
     
                if (Dom.firstnameElement.value == '' && Dom.lastnameElement.value == '') {
                    alert('Veuillez renseigner votre nom et votre prénom');
                } else {
                    Dom.canvasElement.style.visibility = 'visible';
                    Dom.canvasElement.style.transitionDuration == "500ms";
                    Dom.signElement.style.display = 'flex';
                    Dom.formElement.style.height = "auto";
                }
            });
            //Lorsqu'on clique sur le canvas, on switch le bouton réserver par le bouton valider
            Dom.canvasElement.addEventListener('click', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
     
            Dom.canvasElement.addEventListener('touchend', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
        }
     
     
        valider() {
            //this.reservation = new Reservation(this.station);
            ob_reservation.startReservation();
            this.displayResa();
            sessionStorage.setItem('reservation', this.reservation);
        }
     
        annuler() {
            console.log('annuler');
            ob_reservation.annulerReservation();
            this.hideResa();
        }
     
        displayResa() {
            console.log('display resa')
            Dom.validateElement.style.display = 'none';
            Dom.canvasElement.style.display = 'none';
            Dom.textChronoElement.style.display = 'inline';
            Dom.cancelButtonElement.style.display = 'flex';
        }
     
        hideResa() {
            Dom.cancelButtonElement.style.display = 'none';
            Dom.reserveElement.style.display = 'flex';
        }
     
        initValidate() {
            Dom.validateElement.addEventListener('click', this.valider.bind(this));
        }
     
        initCancel() {
            Dom.cancelButtonElement.addEventListener('click', this.annuler.bind(this));
        }
     
        onload() {
            if (ob_reservation.checkReservation() === false) {
                Dom.validateElement.addEventListener("click", function(event) {
                    this.disabled = true;
                    ob_reservation.startReservation();
                });
            } else {
                Dom.validateElement.disabled = true;
            }
        }
     
        initOnload() {
            window.addEventListener("load", this.method.bind(this));
        }
    }
     
    const ob_reservation = new Reservation(this.station);





    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    class Reservation {
        constructor(station) {
            this.station = station;
        }
     
        startReservation() {
            console.log('chrono');
            this.chrono = new Chrono(20);
            this.chrono.startTimer();
     
            this.storage = new Storage(this.station, this.chrono);
            this.storage.store(this.station);
     
            window.addEventListener("beforeunload", function(event) {
                // récup. du temps restant
                const tempsRestant = this.chrono.timeEnd - Date.now();
                if (tempsRestant > 0) {
                    // store date de fin du chrono en millisecondes
                    sessionStorage.setItem("timeEnd", this.chrono.timeEnd);
                    // juste pour voir clairement la date dans le storage
                    sessionStorage.setItem("dateEnd", new Date(this.chrono.timeEnd));
                } else {
                    sessionStorage.clear();
                }
            });
        }
     
        checkReservation() {
     
            const timeEnd = +sessionStorage.getItem("timeEnd");
            const tempsRestant = timeEnd - Date.now();
            if (tempsRestant > 0) {
                Dom.reserveElement.style.display = 'none';
                Dom.cancelButtonElement.style.display = 'flex';
                this.chrono = new Chrono();
                this.chrono.startTimer(timeEnd);
                return true;
            }
            return false;
        }
     
        annulerReservation() {
            sessionStorage.clear();
            this.chrono.stopTimer();
        }
    }

    Citation Envoyé par Loralina Voir le message
    Ne paraît-il pas évident qu'en faisant comme ça, removeEventListener utilisera le même écouteur ?
    Où est la difficulté ?
    Je pensais pouvoir récupérer this.handlerChrono.bind(this) sans avoir besoin de lui déclarer une variable.

    Et merci pour vos explications et conseils

  13. #53
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Petite rectification, je me suis débarassé de la constante global new Reservation pour la déclarer dans la fonction valider(), avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        valider() {
            this.ob_reservation = new Reservation(this.station);
            this.ob_reservation.startReservation();
            this.displayResa();
        }
    Cela n'avait pas fonctionné avant car je n'appelais pas la fonction checkReservation() dans mon objet Reservation. Donc aucune constante déclaré à l'extérieur des classes, uniquement pour la class Map qui en est l'exception.

    Je pense que le problème est maintenant résolu, je l'indiquerais après avoir vu avec mon mentor s'il valide.

  14. #54
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    Dans la classe Formulaire, je vois :
    - this.onloadMethod(); : ne serait-ce pas plutôt this.initOnload(); ?
    - window.addEventListener("load", this.method.bind(this)); : ne serait-ce pas plutôt window.addEventListener("load", this.onload.bind(this)); ?

  15. #55
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Bonjour,

    Oui exactement, c'était un oubli de ma part lorsque j'ai copié le code. C'est corrigé

  16. #56
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Sujet résolu, je post ici le processus de réservation (dans l'ordre) à partir de la class Map .


    Map

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
     
    class Map {
        constructor() {
            this.map = L.map('map').setView([49.8941708, 2.2956951], 13);
            this.layer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            }).addTo(this.map);
            this.checkDatas();
        }
     
        //On verifie si les données de la station existent puis on les affiche en envoyant l'objet station au formulaire
        checkDatas() {
            if (Storage.hasStationInfo()) {
                this.initForm(Storage.getStation());
            } else {
                Storage.getClear();
            }
        }
     
        //On passe en paramètre l'url + la fonction appelé en cas de succès
        ajaxGet(url, callback) {
     
            let req;
            //IE5 et 6 utilisant un objet ActiveX au lieu de l'objet XMLHttpRequest, on vérifie si le navigateur prend en charge l'objet XMLHttpRequest, sinon créer un objet ActiveX;
            //XMLHttpRequest est un objet qui est utilisé pour échanger des données avec un serveur
            if (window.XMLHttpRequest) {
                req = new XMLHttpRequest();
            } else {
                req = new ActiveXObject('Microsoft.XMLHTTP');
            }
     
            //On specifie le type de requête (GET ou POST) et l'adresse du fichier
            req.open("GET", url);
     
            //Au chargement de la page, si le statut est OK, 
            req.addEventListener("load", function() {
                if (req.status >= 200 && req.status < 400) {
                    //On appel la fonction callback en lui passant la réponse de la requete
                    callback(req.responseText);
                } else {
                    console.error(req.status + " " + req.statusText + " " + url);
                }
            });
     
            req.addEventListener("error", function() {
                console.error("Erreur réseau avec l'URL " + url);
            });
            //On envoie la requête au serveur
            req.send();
        }
     
        //Ajouter Markers
        initMarkers() {
            this.ajaxGet('https://cors-anywhere.herokuapp.com/http://api.jcdecaux.com/vls/v1/stations?contract=amiens&apiKey=86e2bc05a438193dfbc09fcaa44634b7c6641d2c', (reponse) => {
     
                let datas = JSON.parse(reponse);
                //datas.forEach((data) => {
                for (const data of datas) {
     
                    L.marker(Object.values(data.position), {
                            "data": data
                        })
     
                        .addTo(this.map)
                        .on("click", this.initForm.bind(this, data), Dom.canvasElement.style.display = 'inherit');
                }
            });
     
        }
     
        initForm(data) {
            if (this.formulaire == undefined) { 
                this.formulaire = new Formulaire(new Station(data));
            } else {
                this.formulaire.station = new Station(data);
            }
        }
    };
     
    const myMap = new Map();
    myMap.initMarkers();


    Station


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    /*------------------------------------------
    STATION
    ------------------------------------------*/
     
    class Station {
        constructor(data) {
            //Propriété de l'objet station
            this.status = data.status;
            this.name = data.name;
            this.address = data.address;
            this.available_bikes = data.available_bikes;
            this.bike_stands = data.bike_stands;
            this.display();
        }
     
        display() {
            const elements = Dom.stationsElement.querySelectorAll('[id]');
            for (let elem of elements) {
                elem.style.fontWeight = "bold";
            }
     
            Dom.statusElement.innerHTML = this.status;
            //Dom.getEtat().style.fontWeight = 'bold';
            Dom.nameElement.innerHTML = this.name;
            Dom.addressElement.innerHTML = this.address;
            Dom.availableBikesElement.innerHTML = this.available_bikes;
            Dom.bikeStandsElement.innerHTML = this.bike_stands;
        };
     
        getRemoveBike() {
            return this.available_bikes--;
        }
     
     
        getAddBike() {
            return this.available_bikes++;
        }
     
        getAvailableBikes() {
            return this.available_bikes;
        }
    }


    Formulaire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    class Formulaire {
        constructor(station) {
            this.station = station;
            this.dataUser();
            this.eventUser();
            this.initValidate();
            this.initCancel();
            this.initOnload();
     
        }
     
        //Vérifie les données
        dataUser() {
            this.users = Storage.hasUserInfo();
            if (this.users) {
                Dom.firstnameElement.value = Storage.getFirstname();
                Dom.lastnameElement.value = Storage.getLastname();
            }
        }
     
        //Evenements Utilisateur
        eventUser() {
            Dom.reserveElement.addEventListener('click', () => {
     
                if (Dom.firstnameElement.value == '' && Dom.lastnameElement.value == '') {
                    alert('Veuillez renseigner votre nom et votre prénom');
                } else {
                    Dom.canvasElement.style.visibility = 'visible';
                    Dom.canvasElement.style.transitionDuration == "500ms";
                    Dom.signElement.style.display = 'flex';
                    Dom.formElement.style.height = "auto";
                }
            });
            Dom.canvasElement.addEventListener('click', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
     
            Dom.canvasElement.addEventListener('touchend', () => {
                Dom.reserveElement.style.display = 'none';
                Dom.signElement.style.display = "none";
                Dom.validateElement.style.display = 'flex';
            });
        }
     
     
        //Evènement lors de la validation
        validate() {
            console.log('validé')
            this.ob_reservation = new Reservation(this.station);
            //On passe la main à reservation qui contient l'objet station
            this.ob_reservation.startReservation(this.station);
            this.displayResa();
            //On retire un vélo à la station
            this.station.getRemoveBike();
            Dom.availableBikesElement.innerHTML = this.station.getAvailableBikes();
     
        }
     
        //Display du Formulaire lors de la validation
        displayResa() {
            Dom.validateElement.style.display = 'none';
            Dom.canvasElement.style.visibility = 'hidden';
            Dom.textChronoElement.style.display = 'inline';
            Dom.cancelButtonElement.style.display = 'flex';
        }
     
        //Evénement lors de l'annulation
        cancel() {
     
            if (confirm("Voulez vous annuler votre réservation ?")) {
                // Code à éxécuter si l'utilisateur clique sur "OK"
                this.ob_reservation.annulerReservation();
                this.hideResa();
                //On réinitialise le nb de vélo
                this.station.getAddBike();
                this.canvas = new Canvas();
                this.canvas.clearCanvas();
                Dom.availableBikesElement.innerHTML = this.station.getAvailableBikes();
     
            }
        }
     
     
        //Display du Formulaire lors de l'annulation
        hideResa() {
            Dom.cancelButtonElement.style.display = 'none';
            Dom.reserveElement.style.display = 'flex';
        }
     
        //Evénements lors du rechargement de la page
        onload() {
            this.ob_reservation = new Reservation(this.station);
            //Si la condition est vérifié, on récupère la réservation
            if (this.ob_reservation.checkReservation(this.station) === false) {
                Dom.validateElement.addEventListener("click", () => {
                    // this.disabled = true;
     
                    this.ob_reservation.startReservation();
                });
                /*} else {
                    Dom.validateElement.disabled = true;
                }*/
            }
        }
     
        initValidate() {
            Dom.validateElement.addEventListener('click', this.validate.bind(this));
        }
     
        initCancel() {
            Dom.cancelButtonElement.addEventListener('click', this.cancel.bind(this));
        }
     
        initOnload() {
            window.addEventListener("load", this.onload.bind(this));
        }
    }


    Réservation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    class Reservation {
        constructor(station) {
            this.station = station;
        }
     
        //Démarrer la résa
        startReservation(station) {
            console.log(station)
            this.chrono = new Chrono(20);
            this.chrono.startTimer();
     
            //On stocke les données dans le storage
            Storage.store(station, this.chrono)
     
            //Storer les données avant le rechargement de la page
            window.addEventListener("beforeunload", () => {
     
                const tempsRestant = this.chrono.timeEnd - Date.now();
                if (tempsRestant > 0) {
                    // store date de fin du chrono en millisecondes
                    sessionStorage.setItem("timeEnd", this.chrono.timeEnd);
                } else {
                    Storage.getClear();
                }
            });
        }
     
        //On vérifie si les données existent et on relance le chrono lors du refresh du navigateur
        checkReservation(station) {
     
            const timeEnd = +sessionStorage.getItem("timeEnd");
     
            const tempsRestant = timeEnd - Date.now();
            if (tempsRestant > 0) {
                Dom.reserveElement.style.display = 'none';
                Dom.cancelButtonElement.style.display = 'flex';
                //On récupère le nb de vélo en temps réel
                station.getRemoveBike();
                Dom.availableBikesElement.innerHTML = station.getAvailableBikes();
     
                this.chrono = new Chrono();
                this.chrono.startTimer(timeEnd);
                return true;
            }
            return false;
        }
     
        annulerReservation() {
            Storage.getClear();
            this.chrono.stopTimer();
     
            /*setTimeout(function() {
                window.location.reload(true);
            }, 800);*/
        }
    }

    Chrono

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class Chrono {
        constructor(minutes = 0, secondes = 0) {
            this.duree = ((minutes * 60) + secondes) * 1000;
            this.iTimer = null;
            this.timeEnd;
            console.log('instancie timer')
        }
     
        startTimer(timeEnd) {
            Dom.textChronoElement.style.display = 'inline';
            if (timeEnd) {
                this.timeEnd = timeEnd;
            } else {
                this.timeEnd = Date.now() + this.duree;
            }
            this.iTimer = setInterval(() => {
                this.decompteTimer();
            }, 1000);
            //this.decompteTimer();
        }
     
        stopTimer() {
            sessionStorage.clear();
            clearInterval(this.iTimer);
            this.iTimer = null;
            console.log('je stop')
            Dom.textChronoElement.style.display = 'none';
            Dom.textChronoAnnulerElement.style.display = 'flex';
        }
     
        decompteTimer() {
            const reste = Math.ceil((this.timeEnd - Date.now()) / 1000);
            if (reste > 0) {
                Dom.chronoElement.textContent = ('0' + parseInt((reste % 3600) / 60, 10)).slice(-2) + ':' + ('0' + parseInt((reste % 3600) % 60, 10)).slice(-2);
                console.log(Dom.chronoElement.textContent = ('0' + parseInt((reste % 3600) / 60, 10)).slice(-2) + ':' + ('0' + parseInt((reste % 3600) % 60, 10)).slice(-2));
            } else {
                this.stopTimer();
                Dom.chronoElement.textContent = parseInt('0') + ' : ' + parseInt('0');
                Dom.textChronoElement.textContent = 'Comptage terminé !';
                Dom.reserveElement.style.display = 'block';
                Dom.cancelButtonElement.style.display = 'none';
            }
        }
    }


    Et enfin Storage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    class Storage {
     
        static store(station, chrono) {
            sessionStorage.setItem("timeEnd", JSON.stringify(chrono.timeEnd));
            sessionStorage.setItem("station", JSON.stringify(station));
            localStorage.setItem("firstname", Dom.firstnameElement.value);
            localStorage.setItem('lastname', Dom.lastnameElement.value);
     
        }
     
        static getClear() {
            return sessionStorage.clear();
        }
     
        static getTimeEnd() {
            return +sessionStorage.getItem('timeEnd');
        }
     
        static getDateEnd() {
            return sessionStorage.getItem('dateEnd');
        }
     
        static getStation() {
            //console.log(JSON.parse(sessionStorage.getItem("station")));
            return JSON.parse(sessionStorage.getItem("station"));
        }
     
        static getFirstname() {
            return localStorage.getItem("firstname");
        }
     
        static getLastname() {
            return localStorage.getItem("lastname");
        }
     
        static hasUserInfo() {
            return typeof localStorage.getItem('firstname') !== null && localStorage.getItem('lastname') !== null;
        }
     
        static hasStationInfo() {
            return sessionStorage.getItem('station') !== null && sessionStorage.getItem('station') !== undefined;
        }
     
        static hasStorageInfo() {
            return typeof sessionStorage.getItem('timeEnd') !== null;
     
        }
    };

  17. #57
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2020
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2020
    Messages : 119
    Par défaut
    Et merci à noSmoking et Loralina pour leur aide

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 3 PremièrePremière 123

Discussions similaires

  1. Réponses: 12
    Dernier message: 10/12/2017, 15h38
  2. Thread Threapool: main() continue de tourner même après réalisation des tâches
    Par jamesleouf dans le forum Concurrence et multi-thread
    Réponses: 1
    Dernier message: 09/05/2011, 16h07
  3. include et refresh de page
    Par Prosis dans le forum Langage
    Réponses: 4
    Dernier message: 22/01/2007, 15h39
  4. Refresh de page initiale après saisie dans une popup
    Par muppetshow dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 16/03/2005, 12h21
  5. Kill procédure qui continue de tourner en bas. 9i
    Par nuke_y dans le forum Oracle
    Réponses: 10
    Dernier message: 15/11/2004, 10h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo