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 :

cp-ville ou ville-cp


Sujet :

JavaScript

  1. #21
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Effectivement, la variable sel est correctement remplie. Le problème pour moi est maintenant d'afficher le tout dans le formulaire.
    Mes connaissances se limitent actuellement à afficher des 'alert' ou des 'confirm' Je ne sais rien afficher d'autre.

    Quand j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.getElementById("ville").innerHTML = sel;
    Je le tire de mes recherches sur google, mais je n'en connais pas la portée.

    Ce que je voudrais:
    J'ai actuellement un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td align="left"><input text name="ville" id="ville" value=""></td>
    Il faudrait le transformer/supperposer en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     <td align="left"> contenu de "sel"</td>
    avec un effet de la souris qui en cliquant sur une ligne, inscrit le contenu dans le champ ville.


    Est ce réalisable à chaud sans devoir envoyer le formulaire ?
    J'ai déjà chercher une réponse sur le net, mais je ne dois pas comprendre, car les liens trouvés, n'ont pas répondu à mon attente. Si tu as ça en fond de tiroir, je ne demande qu'à m'instruire.
    Merci de ton aide précieuse.
    Débusqueur de bug et chercheur en améliorations

  2. #22
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Oui c'est réalisable à chaud, c'est à ça que sert JavaScript ;)
    Les méthodes et propriétés du DOM sont indispensables en JS. Tu en connais déjà une : getElementById. Elle t'a permis de sélectionner l'input ville. Mettons-le dans une variable pour garder une référence dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var $ville = document.getElementById("ville");
    À présent je te propose d'utiliser la propriété parentNode, qu'ont tous les nœuds DOM, pour accéder au parent de ville, c'est-à-dire ce <td align="left">.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var $td = $ville.parentNode;
    Maintenant que tu as une référence sur le td, tu peux utiliser sa propriété innerHTML :
    Avec ça ton script est un fusil à un coup : il marche la première fois, mais à la seconde l'input ville a disparu donc il ne peut plus trouver le td. Si tu vex que le script soit réutilisable, utilise la méthode insertAdjacentHTML. Elle fonctionne un peu comme innerHTML, mais elle n'écrase pas le contenu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ville.insertAdjacentHTML("afterend", sel);
    Pour info, le DOM te permet aussi de créer directement des éléments sans utiliser du code HTML avec createElement, et de les insérer où tu veux dans la page avec appendChild ou insertBefore.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #23
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Hou là là, en voila des choses intéressantes. Je sens que je vais faire des progrès...... Permet moi de prendre un temps de réflexion. Je vais parcourir le net pour en savoir un max. De plus j'ai un énorme bouquin, un peu rebutant: "Javascript, la référence" de O'reilly. Je vais aller le dépoussiérer.
    Je suis quelque peu surbooké avec mon boulot, mais ce sujet me passionne. Je reviens bientôt te dire comment ça marche.
    Un grand merci....
    Débusqueur de bug et chercheur en améliorations

  4. #24
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Que c'est intéressant.... Je découvre des possibilités immenses. On recrée des éléments à chaud dans le formulaire......
    Mais je ne maitrise pas tout. En fait si je recommence l'opération (bis), j'ai bien une 2e liste qui s'installe à coté de la 1ere. J'aurais voulu plutôt la remplacer.

    J'ai examiné le code après avoir obtenu la liste par JS. Je ne trouve aucune modification. Le server ne sera pas perturbé par cette liste. C'est bien, mais en attendant comment fait-on pour récupérer notre choix ?
    J'ai essayé:
    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
    function jscode(jscodePoste){
        jscodePoste= jscodePoste.trim();
        console.log('jscode ',jscodePoste);
        if(jscodePoste.length <3) { return; }
     
        var imax = Number(document.form_client.total.value);
        console.log('imax =', imax);
        if (imax < 1) return;  //securité
     
     
        var sel="<select name= 'choix_ville' id= 'choix_ville'onchange=codevalid(this.value)>";
        var i, C,  V ;
        var ville = document.getElementById("ville");
     
        for(i=0;i<imax;i++){
            C = document.form_client['code' + i].value;
            if(C.startsWith(jscodePoste)) {  //  510==510 début de 51000
                V= document.form_client['ville' + i].value;
                sel+= "<option value="+V+"> "+V+"</option>";
            }
     
        }
        sel += "</select>";
        console.log('sel= ',sel);
        console.log('V= ',V);
     
        ville.insertAdjacentHTML("afterend", sel);
     
    }
    function codevalid(nom_ville) {
        console.log('codevalid(nom_ville) ',nom_ville);
        if(nom_ville.length <2) { return }
     
        var ville = document.getElementById("ville");
        ville.value=nom_ville;
     
     
    }
    Sur un nom composé de 2 mots je n'ai que le 1er.
    Ce doit surement être une petite erreur de syntaxe. Mais où ?

    J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       sel+= "<option value="+rawurlencode(V)+"> "+V+"</option>";
    mais j'ai une erreur JS !!

    EDIT: Ça y est, j'ai trouvé. En fait j'encode directement en PHP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        <input type="hidden" name="ville<?php print $i?>" value= "<?php print rawurlencode($row[1])?>">
    Puis en JS j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sel+= "<option value="+V+"> "+unescape(V)+"</option>";
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     var sel="<select name= 'choix_ville' id= 'choix_ville'onclick=codevalid(this.value)>";
    est correcte

    Peut être y a -t-il plus simple, mais en attendant ça marche.....
    I'm happy
    Débusqueur de bug et chercheur en améliorations

  5. #25
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    C'est cool si ça marche

    Je vais essayer d'éclaircir quelques points.
    Citation Envoyé par LampeRouge Voir le message
    En fait si je recommence l'opération (bis), j'ai bien une 2e liste qui s'installe à coté de la 1ere. J'aurais voulu plutôt la remplacer.
    Si tu veux la remplacer, il suffit de retirer l'existante avant d'en insérer une nouvelle. Ça se fait en général avec removeChild en passant par le parentNode.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var $liste = document.getElementById("choix_ville");
    $liste.parentNode.removeChild($liste);
    Il y a aussi la récente méthode remove, mais elle n'est pas supportée sous IE. Je te la mets quand même pour info et parce qu'elle est facile à émuler avec un polyfill.
    J'ai examiné le code après avoir obtenu la liste par JS. Je ne trouve aucune modification.
    Les modifications faites par JS n'apparaissent pas dans le code source HTML. On peut voir le code HTML comme la « matière première » à partir de laquelle le navigateur construit une représentation de la page, qu'il peut afficher et qu'on peut manipuler en JS : c'est ce qu'on appelle le DOM (pour Document Object Model).

    Tu peux voir l'état réel du DOM dans l'onglet inspecteur de ta console. Dans ce même onglet, si tu sélectionnes un élément, tu as automatiquement une référence dessus via la variable $0, que tu peux utiliser en ligne de commande dans la console. Pratique pour faire une vérification rapidement.
    Le server ne sera pas perturbé par cette liste. C'est bien, mais en attendant comment fait-on pour récupérer notre choix ?
    En fait, si tu essayes une instruction PHP comme print_r($_POST); tu verras une entrée choix_ville. Mais pour être plus cohérent, le champ qui doit porter la valeur, c'est le champ code, celui qui appelle jscode. Tu dois donc modifier la valeur (value) de ce champ dans la fonction codevalid, comme tu le fais déjà avec le champ ville.


    Sur un nom composé de 2 mots je n'ai que le 1er.
    Ce doit surement être une petite erreur de syntaxe. Mais où ?
    Ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel+= "<option value="+V+"> "+V+"</option>";
    Il manque des guillemets autour du V qui sert de value. Par exemple si V = "Les Oies", le résultat est "<option value=Les Oies>Les Oies</option>". On voit mieux du coup que seule la partie « Les » est gardée, et que « Oies » est considéré comme un autre attribut, sans valeur, de la balise option.

    J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       sel+= "<option value="+rawurlencode(V)+"> "+V+"</option>";
    mais j'ai une erreur JS !!

    EDIT: Ça y est, j'ai trouvé. En fait j'encode directement en PHP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        <input type="hidden" name="ville<?php print $i?>" value= "<?php print rawurlencode($row[1])?>">
    Puis en JS j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sel+= "<option value="+V+"> "+unescape(V)+"</option>";
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     var sel="<select name= 'choix_ville' id= 'choix_ville'onclick=codevalid(this.value)>";
    est correcte

    Peut être y a -t-il plus simple, mais en attendant ça marche.....
    Si tu répares ton souci de guillemet, normalement tu n'auras plus ce problème.

    Si tu veux toujours utiliser un encodage en plus des guillemets, je ne suis pas sûr que rawurlencode de PHP et unescape de JS soient parfaitement réciproques. escape et unescape ont été dépréciés en JS car ils ne gèrent pas correctement les symboles unicode au-delà des 128 caractères de la plage ASCII basique. Utilise le couple rawurlencode/rawurldecode en PHP, ou bien encodeURIComponent/decodeURIComponent en JS. Comme je te déconseille d'insérer des bouts de PHP dans du code JS, préfère la seconde option.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  6. #26
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Peut être que vu l'heure, j'ai l'esprit embrumé.

    Il me semblait bien que les guillemets étaient bien mis.... ( avant que j'installe mon codage), Je ne saisi pas bien ce que tu veux dire.

    Quand j'insère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    liste.parentNode.removeChild(ville);
    Je n'ai plus de liste apparaissant.
    C'est bien d'enlever la liste précédente, mais si on ne peut pas y remettre la 2e c'est un peu handicapant.
    Je ne comprends pas pourquoi ça fait ça.....


    J'ai enlevé unescape() pour le remplacer par decodeURIComponent(). J'espère bien faire. Je n'ai pas constaté de changement sur le résultat. Donc si unescape est déprécié, je garde cette solution.

    Je me retape en ce moment 4 ans de travail à cause de la dépréciation de mysql en PHP, donc je sais ce que ce mot veut dire. (Au passage j'essaie d'améliorer le développement).

    Comme tu le vois, je n'ai plus l'esprit bien clair. Je reviens dés que possible. Merci pour ton aide. C'est fabuleux.

    Avec ta pédagogie, tu devrais dispenser des cours, car ta méthode d'en dire un peu, mais pas trop, oblige à se creuser la cervelle. Je pense aux enseignants, mais aussi à ceux qui bossent à travers internet. (Cours particulier)
    Débusqueur de bug et chercheur en améliorations

  7. #27
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Donner des cours oui, il y a des gens qui me suggèrent de faire ça

    J'ai édité mon précédent message car j'avais fait une coquille : j'avais oublié le $ dans $liste.parentNode.removeChild($liste);. J'ai l'habitude de préfixer d'un $ les variables représentant des objets du DOM, mais ce n'est pas une obligation.

    D'ailleurs je me rends compte que j'ai sorti une variable choix_liste de nulle part, je vais corriger ça aussi. Il s'agit en fait de choix_ville.

    Quant à ville, si tu la retires, c'est l'histoire du fusil à un coup : ton script ne peut plus insérer de nouvelle liste car il n'y a plus de point de repère dans le DOM autour duquel insérer de nouveaux éléments.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  8. #28
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 952
    Points : 44 069
    Points
    44 069
    Par défaut
    On ne louera jamais assez les qualités de Watilin

    ...car ta méthode d'en dire un peu, mais pas trop, oblige à se creuser la cervelle.
    ce n'est malheureusement pas l'avis de tous les poseurs de question

  9. #29
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    La société est assez injuste quand elle ne permet pas à des gens de valeurs, de s'exprimer.... En attendant, il ne faut pas se décourager et chercher des solutions.

    Pour en revenir au sujet, j'ai tenté ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        if(exist(document.choix_ville)){
           liste.parentNode.removeChild(choix_ville);
        }
    Je me demande comment identifié cette liste qui semble-t-il n'appartient pas à mon formulaire.
    C'est bizarre.
    Débusqueur de bug et chercheur en améliorations

  10. #30
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    exist… N'existe pas Tu n'as pas eu de message dans ta console ?

    Quant à $liste, il n'y a pas de magie : tu y accèdes grâce au code que je t'ai donné dans mon post #25. Je te le remets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var $liste = document.getElementById("choix_ville");
    $liste.parentNode.removeChild($liste);
    Peut-être es-tu embrouillé par cette apparente redondance entre les attributs name et id. En gros, les name dans un formulaire déterminent quelles données doivent être envoyées au serveur, tandis que les id marquent des éléments de la page qui ont une importance pour la navigation (liens contenant un #) ou pour les scripts. Pour résumer :
    - name est plus important pour le serveur ;
    - id est plus important côté client.

    En pratique, les choses sont un peu plus confuses que ça car on peut aussi utiliser les name dans les scripts. C'est ce que tu fais quand tu écris document.form_client. Les choses marchent d'une façon pas si évidente qu'il n'y paraît :
    • Si un formulaire a un attribut name et que la valeur de ce name n'est pas une propriété de document, alors le DOM ajoute une référence vers le formulaire sur document. Exemple : <form name="form_client"> est référencé par document.form_client.
    • Si la valeur du name est déjà une propriété de document (par exemple location), il y a conflit, et la référence n'est pas créée. Exemple : <form name="location"> ne sera pas référencé par document.location car document.location existe déjà.
    • Dans tous les cas, une référence est également créée pour chaque formulaire dans la collection document.forms. Cette collection marche comme les tableaux associatifs de PHP : on peut accéder aux items par index (0, 1, 2…) ou par nom. Exemple : si la page contient ces deux formulaires :
      Code html : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      <form name="location"></form>
      <form name="bidule"></form>
      document.forms[0] et document.forms.location référenceront le premier formulaire, tandis que document.forms[1] et document.forms.bidule référenceront le second.

    Comme tu le vois, le référencement direct sur document a une chance de ne pas marcher, car, les navigateurs évoluant, on ne sait pas si une propriété ne sera pas rajoutée demain sur document qui va rentrer en conflit avec le nom de notre formulaire. Dans le doute, passe toujours par document.forms, ou bien utilise les méthodes du DOM pour sélectionner tes éléments.

    Note que l'utilisation de name sur les formulaires n'est pas du tout obligatoire, cela n'a pas d'influence sur les données envoyées au serveur.

    Cet ajout de références sur document ne concerne que les formulaires. Tu le sais déjà, pour accéder à un champ de formulaire, il faut obligatoirement passer par le formulaire contenant, comme dans document.form_client.total. Cela ne marche qu'avec certains éléments, parmi lesquels les champs de formulaire (heureusement), mais aussi les images, et par contre pas les liens. J'ai fait quelques tests et je ne comprends pas la logique qui se cache derrière (s'il y en a une).

    Au final, j'ai pris l'habitude de ne jamais utiliser les name dans mes scripts, et de les cantonner à leur seul rôle de transmettre les données au serveur. Je mets des id aux éléments qui me semblent importants, et j'y accède avec la méthode getElementById, quel que soit leur emplacement dans le code HTML. C'est quand même vachement plus souple.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  11. #31
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    C'est très intéressant tout ce que tu me dis. Je m'aperçois qu'en tant qu'autodidacte, je prenais de mauvaises habitudes.
    N'étant pas borné, je vais essayer d'adopter ce que tu dis. Ça semble très cohérent.

    Je te remets le code que j'ai corrigé.

    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
       var sel="<select name= 'choix_ville' id= 'choix_ville' onclick=codevalid(this.value)>";
        var i, C,  V ;
        var ville = document.getElementById("ville");
     
        ville.parentNode.removeChild("ville");
     
     
        for(i=0;i<imax;i++){
            C = document.getElementById('code' + i).value;
            if(C.startsWith(jscodePoste)) {  //  510==510 début de 51000
                V= document.getElementById('ville' + i).value;
                sel+= "<option value="+V+"> "+decodeURIComponent(V)+"</option>";
            }
     
        }
        sel += "</select>";
        console.log('sel= ',sel);
        console.log('V= ',V);
     
     
        ville.insertAdjacentHTML("afterend", sel);  // ajoute la liste après le champ ville
    Si je mets la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ville.parentNode.removeChild("ville");
    plus rien ne s'affiche.
    TypeError: Argument 1 of Node.removeChild is not an object.

    Je me suis dis, s'il faut un objet, le seul ayant été créé est "choix_ville" !

    Si je mets la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ville.parentNode.removeChild("choix_ville");
    plus rien ne s'affiche encore.
    TypeError: Argument 1 of Node.removeChild is not an object.

    De plus 1 nouvelle erreur apparait sur la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel+= "<option value="+V+"> "+decodeURIComponent(V)+"</option>";
    si mon code_postal fait moins de 5 caractères ???
    URIError: malformed URI sequence

    Il y a donc un truc que je ne comprends pas. Cependant il me semblait bien faire....


    Je me pose une question, dans ton explication: La recherche d'éléments dans le DOM est préférable par les ID. getElementById
    Donc si j'ai 2 formulaires de créé et c'est le cas, il convient d'y mettre tous des id différends. Si 2 id sont identiques, je pense que sera celui du 1er formulaire qui sera sélectionné.
    A moins qu'il soit possible de différencier chacun des formulaires.
    Mon raisonnement est il juste ?
    Débusqueur de bug et chercheur en améliorations

  12. #32
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par LampeRouge Voir le message
    Si je mets la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ville.parentNode.removeChild("ville");
    plus rien ne s'affiche.
    TypeError: Argument 1 of Node.removeChild is not an object.
    Oui, la console n'est pas très informative sur ce coup. En fait, ton script râle parce que tu lui passes une chaîne, alors qu'il attend un objet du DOM à cet endroit. En l'occurence il attend ville sans guillemets, la référence que tu as obtenue avec getElementById à la ligne d'avant.

    Les objets DOM implémentent toute une hiérarchie d'interfaces allant de la plus commune (Node) à la plus spécifique (HTMLInputElement dans notre exemple). Ces noms d'interfaces apparaissent dans certaines documentations, notamment le MDN, et on est un peu embrouillé quand on ne sait pas de quoi il s'agit.

    Ces interfaces donnent une sorte de « type » aux objets DOM, bien qu'il ne s'agissent pas d'un type au sens JavaScript. Tu peux vérifier qu'un objet implémente telle interface avec l'opérateur instanceof. Par exemple ville instanceof Node renverra true. Examiner le constructeur est parfois utile également : ville.constructor.name.

    De plus 1 nouvelle erreur apparait sur la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel+= "<option value="+V+"> "+decodeURIComponent(V)+"</option>";
    si mon code_postal fait moins de 5 caractères ???
    URIError: malformed URI sequence
    Il y a quelques jours je t'avais conseillé d'utiliser les couples de fonctions qui marchent ensemble : soit rawurlencode avec rawurldecode, soit encodeURIComponent avec decodeURIComponent. Je ne suis pas sûr que tu l'aies fait, et le problème pourrait venir de là. Mais plus important encore, puisqu'à la base le souci vient des espaces dans les noms de certaines villes, je t'avais dit que mettre des guillemets corrigerait la situation en un clin d'œil. Quand on y réfléchit, c'est un peu bête de recourir à une fonction d'encodage alors qu'il n'y a qu'un seul caractère qui pose problème.

    Le message d'erreur maformed URI sequence a deux causes possibles :
    - soit il y a un % qui traîne tout seul ;
    - soit il y a une séquence d'octets qui ne correspond pas à un codage UTF-8.

    Car il faut savoir que le couple encodeURIComponent/decodeURIComponent repose sur l'encodage UTF-8. Prenons par exemple le caractère « é » : son numéro est 233, soit E9 en hexadécimal. rawurlencode le transforme en %E9, alors que encodeURIComponent renvoie %C3%A9. La mécanique d'UTF-8 fait que les séquences commençant par E doivent faire 3 octets (cf. Wikipédia), du coup decodeURIComponent ne sait pas décoder %E9.

    Je me pose une question, dans ton explication: La recherche d'éléments dans le DOM est préférable par les ID. getElementById
    Donc si j'ai 2 formulaires de créé et c'est le cas, il convient d'y mettre tous des id différends. Si 2 id sont identiques, je pense que sera celui du 1er formulaire qui sera sélectionné.
    A moins qu'il soit possible de différencier chacun des formulaires.
    Mon raisonnement est il juste ?
    Oui Même si en fait, on n'est pas censés avoir plusieurs fois le même id dans la page. Dans le cas de plusieurs id identiques, le comportement de getElementById n'est pas défini en théorie, même si en pratique on récupère toujours le premier. Tu peux construire un id unique en concaténant différents mots, comme tu l'as fait par exemple avec document.getElementById('code' + i).

    Tu peux aussi combiner différentes méthodes de sélection, qui font que tu n'es pas toujours obligé de donner un id à tous les éléments que tu souhaites manipuler. Par exemple, si tu n'as qu'un seul <select> :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <form id="form_client">
      <select name="...">
        ...
      </select>
    </form>
    Tu peux y accéder de différentes manières :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    document.getElementById("form_client").getElementsByTagName("select")[0]
    // ou bien
    document.getElementById("form_client").querySelector("select")
    // ou bien
    document.querySelector("#form_client select")
    // ou bien
    ...
    Il y a tout un tas de façons. querySelector permet d'utiliser une expression de sélection CSS, c'est bien pratique. Cette méthode ne renvoie que le premier élément correspondant, mais querySelectorAll renvoie une collection. Ces deux méthodes sont généralement les plus lisibles.
    Pour être exhaustif je te mets également les autres méthodes DOM getElementsBy… qui renvoient des collections, et dont le nom est assez explicite :
    - getElementsByTagName : sélection par le nom de balise ;
    - getElementsByClassName : sélection par l'attribut class ;
    - getElementsByName : sélection par l'attribut name.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  13. #33
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Citation Envoyé par Watilin Voir le message
    Oui, la console n'est pas très informative sur ce coup. En fait, ton script râle parce que tu lui passes une chaîne, alors qu'il attend un objet du DOM à cet endroit. En l'occurence il attend ville sans guillemets, la référence que tu as obtenue avec getElementById à la ligne d'avant.
    J'avais oublié (déjà) que toutes les variables en JS sont des objets....
    Bah, sans les guillemets il me retire bien ville qui est égale à document.getElementById("ville");
    Logiquement il me retire mon <input text..... et pas ma liste créer par le JS. (ou peut être aussi en tant qu'enfant)
    Le résultat escompté n'est pas le bon ou il est exagéré.

    Il faudrait donc reconstitué le <input text.... sans son enfant.

    J'ai essayé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ville.parentNode.removeChild(ville.firstElementChild.nodeName);
    Marche pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ville.parentNode.removeChild(ville.firstElementChild);
    Marche toujours pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var liste = ville.children;
     
        if(liste){
            ville.parentNode.removeChild(liste);  // on retire la précedente liste avant de la recréer.
        }
    TypeError: Argument 1 of Node.removeChild does not implement interface Node.
    Arg... encore pas...
    Doué comme je suis, ce fil va servir de cas d'école. Je continue mes essais.

    Pour le 2e problème, tu me parles de mettre des guillemets au lieu d'encoder... Je veux bien, mais je ne vois pas où.
    En fait la 1ere fonction affiche bien: jscode()
    C'est la 2e codevalid(nom_ville) qui gère mal les noms composés.
    si dans la 1ere function je mets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var sel="<select name= 'choix_ville' id= 'choix_ville' onclick=codevalid(\"this.value\")>";
    j'obtiens this.value
    Si tu me dis que je suis bouché borné etc.... Je te crois sur parole, mais ça ne fait pas avancer le schmilblick.
    Débusqueur de bug et chercheur en améliorations

  14. #34
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Ok, j'admets que ça peut être difficile de trouver à quel endroit il faut mettre les guillemets. Tu te souviens de mon histoire avec cette ville qui s'appelle Les Oies ? Avec V = "Les Oies", quand ton script remplace toutes les occurences de V dans la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel += "<option value="+V+">" + V + "</option>";
    Ça donne ça :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <option value=Les Oies>Les Oies</option>
    On se retrouve donc avec une balise <option> qui a un attribut value=Les, et un attribut Oies qui est « vide ».

    Pour éviter ce coupage en deux des attributs, on voudrait avoir des guillemets autour du nom de ville pour que tout reste dans l'attribut value, comme ceci :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <option value="Les Oies">Les Oies</option>
    Comme tu vois la différence est subtile, mais elle est importante. Alors comment ajouter ces guillemets ? Il y a au moins 3 façons.

    A. Soit tu utilises la séquence d'échappement \" que tu sembles déjà connaître :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sel += "<option value=\""+V+"\">" + V + "</option>";
    //--------------------^^-----^^
    B. Soit tu utilises des guillemets simples (') pour délimiter tes chaînes JS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel += '<option value="'+V+'">' + V + '</option>';
    En JS ça ne fait aucune différence (attention ce n'est pas le cas en PHP, il y a une différence importante).

    C. Soit tu utilises des guillemets simples pour délimiter tes attributs HTML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sel += "<option value='"+V+"'>" + V + "</option>";
    C'est valide en HTML, mais ça t'oblige à échapper les guillemets simples utilisés en tant qu'apostrophes dans les noms de ville (par exemple dans 'L\'Île'), sinon ça pose le même genre de problème qu'avec l'espace. Si tu choisis cette méthode, tu devras appeler replace sur V, ça demande donc un peu de travail supplémentaire au processeur.

    Tu peux trouver tout un tas d'autres variantes de ces solutions en échappant le guillemet simple (\') ou encore en utilisant les codes ASCII des guillemets, "\x22" et "\x27" (écris-les dans ta console pour voir).

    À toi de choisir la solution qui te convient le mieux




    Citation Envoyé par LampeRouge
    Bah, sans les guillemets il me retire bien ville qui est égale à document.getElementById("ville");
    Logiquement il me retire mon <input text..... et pas ma liste créer par le JS. (ou peut être aussi en tant qu'enfant)
    Le résultat escompté n'est pas le bon ou il est exagéré.

    Il faudrait donc reconstitué le <input text.... sans son enfant.
    Alors en fait, <input> est une balise vide, elle n'a pas d'enfant. La liste est sa voisine. Enfin, normalement… Ce qui se passe en réalité, c'est que ton script retire l'input ville, qui du coup se retrouve « en l'air », détaché du DOM. Après ça, il tente d'insérer la liste avec insertAdjacentHTML en utilisant ville comme point d'appui. Le problème, c'est que ville n'est plus dans le DOM. Je viens de vérifier avec ma console, et quand j'essaye ce genre de choses, je reçois une erreur NoModificationAllowedError: Modifications are not allowed for this document. Est-ce que tu vois quelque chose qui ressemble à ça dans ta console ?

    J'ai essayé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ville.parentNode.removeChild(ville.firstElementChild.nodeName);
    Marche pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ville.parentNode.removeChild(ville.firstElementChild);
    Marche toujours pas.
    Le fait que ville n'ait pas d'enfant explique pourquoi ces deux tentatives ont échoué.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var liste = ville.children;
     
        if(liste){
            ville.parentNode.removeChild(liste);  // on retire la précedente liste avant de la recréer.
        }
    TypeError: Argument 1 of Node.removeChild does not implement interface Node.
    Belle tentative Mais tu en demandes trop à cette pauvre removeChild, elle n'est pas capable de retirer plusieurs éléments d'un coup. Quand tu demandes children ou childNodes, tu obtiens une collection (comme avec querySelectorAll par exemple), tu dois ensuite la parcourir avec une boucle. Mais de toutes façons, comme on a vu, ville n'a pas d'enfants. Je te dis ça pour que tu comprennes le message d'erreur : une collection de Node n'est pas un Node.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  15. #35
    Membre actif
    Homme Profil pro
    électronicien
    Inscrit en
    Octobre 2006
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : électronicien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2006
    Messages : 225
    Points : 236
    Points
    236
    Par défaut
    Le problème des guillemets: J'étais persuadé que les " et les ' était différends comme en PHP. J'en apprends encore.
    Ce système de "croisement des sigles " m'était inconnu, mais il est génial. On ne se torture plus à encoder....

    Pour le 2e problème, j'ai bien retenu que tu me dis que "choix_ville" n'est pas enfant de "ville". Et comme tu m'as appris à rechercher des éléments plutôt par leur ID, je ne suis pas gêné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        var liste = document.getElementById('choix_ville');
     
        if(liste){
            ville.parentNode.removeChild(liste);  // on retire la précedente liste avant de la recréer.
            ville.value= null;
        }
    Maintenant, ça fonctionne correctement. Je vais passer à la suite, c'est à dire définir le code postal depuis la ville.
    Le but est que si il n'y a qu'un code, il est inséré directement.
    S'il y en a plusieurs ( ce qui peut arriver sur des cedex) on affichera une liste.
    Je pense que pour plus de clarté on peut ouvrir un autre fil de discussion.

    Je vais essayer de m'en sortir, mais en attendant je te remercie de ce cours magistral, où j'en ai appris pas mal.
    Avec mon amitié.
    Débusqueur de bug et chercheur en améliorations

  16. #36
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 952
    Points : 44 069
    Points
    44 069
    Par défaut
    Tu peux également supprimer tous les enfants d'un élément sans trop te soucier si il en existe !
    Comment supprimer tous les enfants d'un noeud en utilisant les méthodes DOM ?

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

Discussions similaires

  1. Liste des villes et codes postaux
    Par CynO dans le forum Services
    Réponses: 11
    Dernier message: 27/09/2007, 01h07
  2. lista de noms, d'adresses, de pseudo, de ville etc
    Par claudan dans le forum Autres Logiciels
    Réponses: 11
    Dernier message: 08/11/2005, 00h00
  3. Réponses: 2
    Dernier message: 25/09/2005, 17h46
  4. Tableau croisé de température et de ville
    Par NicoNGRI dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 26/07/2005, 11h56
  5. Cherche contenu pour BDD (ville, automobile..)
    Par nesbla dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 29/03/2005, 20h17

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