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 :

exécution de fonction sur modification de champ texte


Sujet :

JavaScript

  1. #1
    Membre du Club Avatar de Elianora la blanche
    Femme Profil pro
    Développeur Web
    Inscrit en
    Avril 2005
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2005
    Messages : 102
    Points : 59
    Points
    59
    Par défaut exécution de fonction sur modification de champ texte
    Bonjour !

    j'ai un formulaire contenant un champ texte qui me permet, lorsque son contenu est modifié, de mettre à jour en ajax, une liste de valeurs venant d'une base de données affichée en dessous

    rien d'extraordinaire en soi mais :
    - si j'utilise onchange, la fonction n'est exécutée que quand le champ perd le focus, ce que je ne trouve pas pratique du tout dans mon cas
    - si j'utilise onkeyup (ou onkeydown, onkeypress), ça fonctionne comme je voudrais, si ce n'est que la fonction est appelée à chaque frappe (logique)

    est-ce qu'il y aurait un moyen (en javascript, ajax, jquery ou autre) de détecter une 'pause' dans la frappe avant de lancer la fonction (pour éviter 4 ou 5 requêtes ajax en parallèle au fur et à mesure de la frappe) ?

    par exemple, si je veux taper le mot "test", comme ma fonction javascript n'envoie la requête ajax qu'au bout de 2 lettres, j'ai 3 requêtes ajax lancées à la suite

    selon la disponibilité du serveur php derrière, ces requêtes (asynchrones) ne s'exécutent pas forcément dans l'ordre, et pas forcément assez vite

    la requête sql exécutée étant (en plus) un peu complexe, j'ai peur qu'à la longue (en montée en charge), ça devienne horriblement lent pour mettre à jour la liste de valeurs

    j'ai vu, sans regarder le détail, des fonctions permettant "d'observer" un élément toutes les x secondes; ça me permettrait d'espacer les requêtes mais il en resterait encore beaucoup, surtout l'utilisateur tape lentement

    merci d'avance !

  2. #2
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Bonjour,
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    onkeyup="if (lance_ajax) clearTimeout(lance_ajax);lance_ajax=setTimeout(ta_fonction(), 2000);"
    En millisecondes ....

    A+

  3. #3
    Membre du Club Avatar de Elianora la blanche
    Femme Profil pro
    Développeur Web
    Inscrit en
    Avril 2005
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2005
    Messages : 102
    Points : 59
    Points
    59
    Par défaut
    salut !

    j'ai essayé le timeout, ça me permet certes de 'temporiser' l'envoi de requête, mais au bout de 2s (comme dans l'exemple), les 3 requêtes précédemment indiquées sont lancées à la suite

    j'ai essayé de passer par jquery, mais ça se comporte de la même manière

    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
     
    <form id="SearchForm" method="post" action=""
    <input name="dyn_search_text" size="35" value="Rechercher dans les items affichés" id="DynSearchText" type="text" />
    </form>
     
    	<script type="text/javascript">
    		function request_send () {
    			var search_text = jQuery("#DynSearchText").val();
    			if(search_text.length >= 2)
    			{
    				new Ajax.Updater(
    					'update_div_list', 
    					"/items/filter", 
    					{parameters: 
    						{search_text:search_text, 
    						filter_type:'type', 
    						filter_id:'5'}, 
    						asynchronous:true, 
    						evalScripts:true});
    			}
    		}
     
    		jQuery("#DynSearchText").focus(
    			function () {
    				jQuery("#DynSearchText").val('');
    			}
    		);
     
    		jQuery("#DynSearchText").keyup(
    			function () {
    				var ajax_send = null;
    				if(ajax_send)
    				{
    					clearTimeout(ajax_send);
    				}
    				else
    				{
    					ajax_send = setTimeout("request_send()", 2000);
    				}
    			}
    		);
    	</script>
    les paramètres du Ajax.Updater sont écrits en PHP, là j'indique le résultat pour que ce soit plus lisible

  4. #4
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    doit être globale et non locale comme ici.

    De plus si tu la remets à null avant de le tester le test ne fonctionne jamais et tu perds le contrôle sur le timeout ...
    Fonctionnement logique, donc, mais à corriger.

    A+

  5. #5
    Membre du Club Avatar de Elianora la blanche
    Femme Profil pro
    Développeur Web
    Inscrit en
    Avril 2005
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2005
    Messages : 102
    Points : 59
    Points
    59
    Par défaut
    re !

    j'ai donc défini ma variable en global telle que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <script type="text/javascript">
    		var ajax_send;
     
    		[...]
    	</script>
    par contre, rien ne se passe
    je suppose que ça vient du délai mais je ne suis pas sûre d'avoir tout compris

    en gros, à chaque frappe, je définis un compteur à 2000ms sauf s'il existe déjà, auquel cas je le supprime
    donc ça n'est jamais exécuté ?

    j'ai essayé de modifier la valeur du timeout, mais si la valeur devient très faible, seule la requête à 2 caractères est envoyée et si la valeur augmente, il ne se passe rien de plus

    euh... help ^^

  6. #6
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par Elianora la blanche Voir le message
    en gros, à chaque frappe, je définis un compteur à 2000ms sauf s'il existe déjà, auquel cas je le supprime
    donc ça n'est jamais exécuté ?
    A chaque frappe, tu regardes s'il y a un appel Ajax (en attente de 2s)
    Si oui, tu l'annules et tu le redéfinis en fonction de la dernière frappe.

    Normalement, si tu attends 2s après une frappe, il devrait se déclencher
    (sous réserve que ton appel Ajax fonctionne)

    A noter : mon exemple est uniquement JS : pas de JQuery

    A+

  7. #7
    Membre du Club Avatar de Elianora la blanche
    Femme Profil pro
    Développeur Web
    Inscrit en
    Avril 2005
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2005
    Messages : 102
    Points : 59
    Points
    59
    Par défaut
    je me disais que c'est parce que je tape trop vite, mais à la fin de ma frappe ou des 2s, l'appel devrait être fait

    je ne pense pas que jquery change grand chose à l'histoire mais je vais réessayer avec un simple alert pour voir le fonctionnement avant

    mon ajax fonctionne, puisque sans timeout, il me fait 1 requête en base à chaque frappe

    la suite au prochain épisode !

    EDIT : honte à moi, j'avais mal recopié !
    à chaque frappe je supprimais le timeout s'il y en avait un, mais sans jamais le recréer

    cette fois, ça fonctionne, il ne me reste plus qu'à jouer avec le timeout pour trouver une valeur correcte pour éviter d'attendre trop en fin de frappe, sans lancer 36 requêtes ajax ^^

    merci encore pour cette solution !

  8. #8
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par Elianora la blanche Voir le message
    cette fois, ça fonctionne, il ne me reste plus qu'à jouer avec le timeout pour trouver une valeur correcte pour éviter d'attendre trop en fin de frappe, sans lancer 36 requêtes ajax ^^


    Le délai correct sera plus en fonction du temps de réponse de ta base que de la vitesse de frappe de l'utilisateur ...

    Par contre attention : l'appel peut déjà avoir été lancé : le test ne supprime que le timeout, pas l'appel Ajax s'il a déjà été lancé.
    Dans ta fonction Ajax, tu peux ajouter un équivalent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (xhr_object)
       xhr_object.abort();
    Ainsi, même si l'appel Ajax est déjà parti, il sera annulé ...

    A+

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/08/2010, 16h31
  2. Exécuter une fonction sur un mdb distant
    Par wadoo dans le forum VBA Access
    Réponses: 2
    Dernier message: 11/07/2008, 13h35
  3. [C#] Exécuter une fonction sur une form parente
    Par belzeluc dans le forum Windows Forms
    Réponses: 15
    Dernier message: 10/07/2008, 11h04
  4. Réponses: 4
    Dernier message: 30/08/2006, 20h33
  5. Exécuter une fonction sur le onchange d'un select
    Par Lung dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 20/06/2006, 15h05

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