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 :

Paramètres pour événement onkeypress


Sujet :

JavaScript

  1. #1
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut Paramètres pour événement onkeypress
    Bonjour,

    Je ne sais pas encore si c'est un bug de JavaScript mais je ne trouve pas de solution.

    Voici le problème :

    Chaque champ d'un tableau (balise input) est identifiée de manière unique. L'événement onkeypress d'un champ appelle une fonction avec 3 arguments :
    - l'identifiant du champ,
    - le type de données,
    - le nb. de champs sur la ligne.

    Cette fonction a pour but de contrôler ce qui est saisi suivant le type de données, créer une nouvelle ligne en fin de tableau lorsquei l'utilisateur appuie sur la touche Entrée dans le dernier champ de la dernière ligne du tableau, etc.

    Pour que cette fonction s'applique également sur les nouveaux champs créés, il est nécessaire de la déclarer dans le propriété onkeypress de ces derniers.

    La fonction est comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function CheckField(FieldId, DataType, CountField)
    {
    ...
      /** Déclaration de la fonction gérant l'événement onkeypress pour chacun des champs créés **/
      for (i=0; i < CountField; i++)
      {
          NewFieldId=exp + " . " +  i;									
         NewField.onkeypress=function onkeypress (event) {return CheckField(NewFieldId, "varchar", CountField)};					 
      }
    ...
    }
    Lors de l'exécution, au lieu que l'argument NewFieldId soit différent pour chaque champ, il sera = FieldName + (CountField - 1) pour tous les champs.

    Par exemple, si CountField=3 et exp="champ" :

    - l'argument FieldId de la fonction CheckField pour chaque champ sera égal à exp2, exp2, exp2 au lieu de exp0, exp1, exp2.

    Merci pour vos réponses.

  2. #2
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Je précise, un nouveau champ est bien évidemment créé dans la boucle à chaque itération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /** Déclaration de la fonction gérant l'événement onkeypress pour chacun des champs créés **/
     for (i=0; i < CountField; i++)
     {
    NewField=document.createElement("INPUT");
    
     NewFieldId=exp + " . " + i; 
     NewField.onkeypress=function onkeypress (event) {return CheckField(NewFieldId, "varchar", CountField)}; 
     }
    J'ai essayé avec un tableau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var NewField =New Array(x);
    ...
     
     NewField[i]=document.createElement("INPUT"); 
     NewFieldId=exp + " . " + i; 
     NewField[i].onkeypress=function onkeypress (event) {return CheckField(NewFieldId, "varchar", CountField)}; 
    ...
    Cela donne le même résultat.

  3. #3
    Membre chevronné
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Par défaut
    Ce n'est pas un bug de Javascript.
    C'est une méconnaissance du langage de ta part.

    Le problème vient de ce que que tu utilises une cloture : ton gestionnaire d'évènement onkeypress. Tu captures, non pas la valeur contenue dans NewFiledId mais une référence à cette variable. La dernière valeur contenue dans cette variable est la valeur qu'elle a en fin de boucle, soit "champ2" dans l'exemple que tu donnes (exp+"."+i).

    Quand le gestionnaire est activé, il va lire le contenu de la variable NewFieldId qui est bien égal à "champ2".

    D'ailleurs, tu captures aussi CountField et si sa valeur change quelque part ailleurs dans le code, le résultat de ton gestionnaire d'évènement sera aussi différent de ce que tu attends.

    Une option est d'utiliser une fonction pour exécuter cette cloture :

    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
    function CheckField(FieldId, DataType, CountField)
    {
      function onkeypressFactory ( NewFieldId, CountField ) {
        return function onkeypress ( event ) {
          return CheckField(NewFieldId, "varchar", CountField);
        };
      }
      ...
      /** Déclaration de la fonction gérant l'événement onkeypress pour chacun des champs créés **/
      for (i=0; i < CountField; i++)
      {
        NewFieldId=exp + " . " +  i;									
        NewField.onkeypress=onkeypressFactory( NewFieldId, CountField );					 
      }
    ...
    }
    Dans ce cas tu captures aussi une référence mais aux arguments de la fonction onkeypressFactory qui eux ne changerons pas, le Javascript ne possédant pas de passage par référence.

  4. #4
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Merci pour ta réponse cela explique en effet ce comportement, je pensais que la valeur était copiée.

  5. #5
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    Je n'ai rien compris de ton code.

    je ne vois pas comment il peux faire ce que tu décris.

    Je ne comprends pas à quoi sert le paramètre DataType qui n'est jamais exploité.

    si je comprends bien le besoin lorsque on tape "enter" sur le dernier input d'une ligne
    on crée une nouvelle ligne vierge.

    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
    //fonction de vérification
    var verify(event) {
      var verifyType : this..setAttribute("data-type");
      // vérifier la saisie en fonction du type
      ...
    };
     
    //fonction qui gère le dernier input
    var keyPressLastFieldFunction(event) {
      if (13 == event. keyCode) {
        createNewLine();
        this.onkeypress = verify; //on empêche la création de plusieurs lignes si l'utilisateur appuis plusieurs fois sur "enter"
      } else {
        this.verify(event);
      }
    };
     
    var createNewLine = function() {
      for (i=0; i < CountField; i++) {
        var newField=document.createElement("INPUT");
        newField.setAttribute("data-type", "varchar");
        newField.onkeypress = verify; // utiliser la fonction de vérification sur tout les champs
        ...
      }
      //on change la fonction pour le dernier input
      newField.onkeypress = keyPressFunction;
    };
    Comment ça marche ?
    on ajoute un attribut "data-type" aux input ce champ contient le type de vérification

    la fonction verify utilise ce champ pour vérifier la saisie.

    pour le dernier input de la ligne on gère la touche "enter" si elle est pressée on crée une ligne

    la méthode createNewLine crée une nouvelle ligne fixe le type de vérification de chaque champ et associe la bonne fonction à l'événement keypress.

    A+JYT

  6. #6
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Salut Sekaijin,

    La fonction (dont j'ai présenté la partie qui me causait des soucis) me permet d'ajouter des lignes vierges dans un tableau html alimenté par les enregistrements d'une table MySQL, quelle que soit cette table.

    Une ligne vierge est ajoutée automatiquement lorsque l'utilisateur appuie sur la touchée entrée dans le dernier champ modifiable de la dernière ligne (à condition qu'au moins un champ obligatoire soit saisi pour éviter d'avoir plus d'une ligne vierge).

    Une fois les éventuelles mise à jour et/ou l'insertion de nouveaux enregistrements effectuées, j'enregistre le tableau dans la table.

    Cela comporte comme un formulaire-tableau MS-ACCESS (enfin s'il n'a pas trop changé depuis que j'ai utilisé pour la dernière fois).

    Bien à tous.

  7. #7
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    Je pense avoir compris le besoin
    ce que je ne comprends pas c'est

    pourquoi UNE SEULE fonction doit gérer la vérification et l'ajout de ligne vide ?
    pourquoi cette fonction est associé à tous les inputs alors que certains ne doivent pas impliquer l'ajout de ligne et d'autre oui ?

    pour moi il y a une pb de conception. Je ne vois pas en quoi faire une fonction qui fait tout facilite la chose. ton problème est pour moi là. ta fonction fait trop de choses différentes dans trop de contexte différent.

    je pense que la première chose à faire c'est clarifier la situation
    mettre une méthode onkeypress sur chaque input qui fait la vérification et que ça
    définir un fonction qui ajouter un ligne et qui ne fait rien d'autre
    mettre sur les dernier inputs un méthode onkeypress qui fait la vérification et qui gère la touche "enter" et appelle la fonction d'ajout de ligne.

    Ainsi chaque fonction ne fait que ce qu'elle a à faire et il ne peut pas y avoir de confusion

    la deuxième chose est d'utiliser les attributs des objets pour ne pas avoir 50 paramètres dans les fonctions
    si tu ajoute un attribut data-type à un input ta méthode de vérification peut lire cet attribut au travers de this du coup ta méthode n'a pas besoin de paramètre pour vérifier la conformité de l'input
    en agissant ainsi tu isole les problème tu n'a plus de problème de porté des paramètres vu qu'il n'y en a plus.

    A+JYT

  8. #8
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Le problème c'est que le développement Web n'est pas homogène : trop de langages. HTML pour l'affichage des objets d'une page, PHP pour accéder à la base de données serveur, Javascript pour modifier les propriétés des objets, etc. Il faudrait un seul langage de haut niveau capable de tout faire.

    Dans mon cas, je contrôle le contenu saisi dans un champ sur l'événement onkeypress (ou onkeydown) ce qui me permet de créer également de nouvelles vierges quand certaines conditions sont réunies. La plupart du temps, je fais des fonctions qui ne font qu'une seule chose. Dans le cas précis je peux bien évidemment appeler une fonction qui ne fera que créer de nouvelles lignes.

    Mon but est de faire (comme je le faisais avec les langages Pascal, C et C++) des objets génériques capables de s'adapter à de nombreuses situations afin de les utiliser comme je le souhaite.

    Ici, je fais un "objet" capable d'afficher les enregistrements d'une table et des tables qui lui sont liées : la sélection des tables est paramétrable et la présentation également. Les enregistrements peuvent être modifiés, supprimer et nouveaux peuvent être insérés. Les paramètres sont contenus dans des tables.

    Faire ce que je décris avec tous ces langages, ce n'est pas agréable car cela ressemble à du bidouillage.

    Par exemple, j'utilise des cases à cocher (associées à un champ caché pour passer la valeur 0 ou 1 lors d'un submit) pour sélectionner des enregistrements sur lesquels je souhaite appliquer une action : supprimer, mettre à la corbeille, etc.

    Dans le mesure des mes connaissances Javascript et PHP, voici les différentes alternatives que j'ai trouvées pour appliquer l'action :

    - Full PHP : récupérer les valeurs des champs associés aux cases à cocher lors du submit puis exécuter l'action. Pourquoi le champ caché associé à la case à cocher ? J'ai remarqué qu'avec la méthode post, la valeur de la case à cocher n'ai transmise que lorsqu'elle est cochée (ça a été donc pensé pour plusieurs choix).

    - Javascript : récupérer les valeurs des cases à cocher (plus besoin de champs associés) afin de faire une liste des identifiants des enregistrements qui ont été sélectionnés (les champs, et donc l'id. d'un enregistrement, sont identifiés de manière unique avec '<input id= ...i.j (<i> n° de colonne et <j> n° de ligne) ce qui permet d'y accéder avec getElementBydId). Puis trouver un moyen de passer cette liste à PHP. Puis submit PHP et action ... Ca fait bidouillage.

    @+

  9. #9
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Autres choses :

    - j'utilise this pour accéder au champ lors d'un événement (je n'utilise plus son identifiant, j'apprends ). Par contre concernant le data type, comment faire pour ajouter un attribut à un objet alors que je suis en PHP ? Appeler une fonction javascript comme ceci : <script> myfonction (this) </script>. Si pas d'autres moyens je trouve ça lourd ... Déjà que les echos php c'est pénible ...

    cela confirme ma 1ère impression : trop de langages qui s'interpénètrent.

  10. #10
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205

  11. #11
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Merci pour l'info. C'est déjà une bonne chose de pouvoir mettre des attributs au niveau html ça m'évitera de passer des paramètres et de mettre \ pour les ' ...

    Je sais que l'on ne peut pas interroger une base de données à partir de Javascript. Existe-t-il des solutions avec des extensions Javascript ? Ajax ? Comment cela marche ?

  12. #12
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Comment lire les data-attributes à partir de PHP ?

  13. #13
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    ajax envoi un requête HTTP GET ou POST au seveur
    celui-ci la traite comme n'importe quelle requête.

    mais dans la réponse il ne faut que le json
    Code php : 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
    <?php 
    //traitement de la requête.
    try {
      $sql_inc="SELECT id_Evt,name_Evt FROM threat";
      $res_inc=mysql_query($sql_inc); 
     
      $data_row = array();
      while($rows_inc=mysql_fetch_assoc($res_inc)){
        $data_row[] = $rows_inc;
      }
      $response = Array(
        'success' => true,
        'rows' => $data_row
      );
    } catch (Exception $e) {
      $response = Array(
        'success' => false,
        'message' => $e->getMessage()
      );
      header($_SERVER['SERVER_PROTOCOL'] . ' Internal Server Error' , true, 500); //STD HTTP
    }
     
    header("content-Type: text/html; charset=UTF-8");
    echo json_encode($data_row);
    //le ?> final est déconseillé par php

    les points importants sont
    1. aucun echo aucun print aucun ?> dans le code php à part le echo final. il est nécessaire que le script php ne retourne que le JSON et les headers
    2. le chartset doit être UTF-8 utiliser utf8_encode()
    3. même en cas d'erreur retourner un JSON (un header 500 aide à signaler l'erreur)



    à la réception ajax il suffit de faire appel à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var response = JSON.parse(xhr.reponseText);
    if (response.success) {
      //ici on a access au données via response.rows qui est un tableau d'objet javascript 
    } else {
      alert(response.message);
    }
    Je sais qu'on a souvent envie de mettre un écho ici ou là dans le php pour faire du débug
    c'est à bannir. la réponse ne serait plus un json et cela ne fonctionnerait plus.

    deux solution
    la bonne : utiliser le débogeur php
    la moins bonne : définir une varriable $debug (tableau de string) et y cumuler tout les messages. ajouter un membre à $response : 'debug' => $debug utiliser la console javascript pour voir le contenu

    A+JYT

  14. #14
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Salut,

    Merci pour les infos, je vais étudier tout ça.

    Cordialement.

  15. #15
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Sauf erreur de ma part, à chaque fois que l'on fait un submit un réaffichage complet d'une page html se produit.

    J'aimerais réafficher un tableau dont le contenu vient de changer sans devoir réafficher toute la page :

    - ré-exécuter la requête SQL et afficher le tableau sans réafficher d'autres parties de la page.

  16. #16
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    AJAX !

  17. #17
    Membre averti
    Inscrit en
    Janvier 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 17
    Par défaut
    Salut Seka,

    J'ai compris AJAX et JSON.

    Mais je n'arrive pas à lire une propriété de l'objet créé avec le parser avec getAttribute, je souhaite en effet que les propriétés soient des variables.

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    str='{"employees":[{"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"},{"firstName":"Peter", "lastName":"Jones"}]}';
     
    obj=JSON.parse(str);
     
    name=obj.employees[0].firstName //=> ça marche
    name=obj.employees[0].getAttribute("firstName") //=> ça ne marche pas
    Tu sais pourquoi ?

    Cordialement

  18. #18
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Tout simplement parce que getAttribute() n'a jamais servi à récupérer les propriétés d'un objet JSON...
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

Discussions similaires

  1. Suppression de paramètre pour procédure stockée dans le code
    Par 24 faubourg dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 04/01/2006, 10h51
  2. pb de passage de paramètre pour ActiveX
    Par cedyouyou dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 21/12/2005, 14h30
  3. paramètres pour une fonction
    Par bul dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 28/05/2005, 07h49
  4. Réponses: 7
    Dernier message: 10/02/2005, 13h44
  5. Réponses: 3
    Dernier message: 21/05/2003, 11h44

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