Forums : Xul, Xbl, JS...

Aller à la discussion :  Plus récente Plus ancienne

# [Résolu] Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : Raphael

Date : 27/11/2006 11:09

Bonjour, j'ai un problème assez délicat que je n'arrive pas à régler : Mon interface comprend :

  • Un formulaire comprenant : 1 textbox et 2 menulist filtrant mon listbox ci-dessous.
  • Un listbox qui liste des "Decks" (jeu de 40 cartes comme "Magic" par exemple)
  • Des élements d'affichages qui affichent des informations sur le deck sélectionné.

Jusque-là, je pense que tout va bien... Mon listbox est filtré en temps réel, je n'ai pas de bouton "Rechercher", en fait j'utilise setTimeout() afin de relancer toutes les 100ms mon script de filtrage de cette manière :

function updateDeckExplorer()
{
 // On ne met à jour le listbox que si le formulaire a changé d'état
 if(form_has_modifications){
  // On enlève tout le contenu du listbox, et on le re-remplit selon les nouveaux critères de filtrage
 }
 setTimeout("updateDeckExplorer()",100);
}

Ce script est lancé à l'ouverture de mon application. Il scrute donc tout changement de mon formulaire et filtre mes decks en conséquence. Jusqu'ici, tout fonctionne très bien.

Ensuite, mon listbox "decklist" réagit à un onselect="setDeck();" dont voici le code :

function setDeck()
{
 var Deck_Index = $("decklist").getSelectedItem(0).getAttribute("Deck_Index");
 deck = new currentdeck(Deck_Index);
 deck.setInfos();
 deck.setCards();
}

setInfos et setCards affichent les informations et les cartes de mon deck dans mes éléments d'affichage. Là, encore, aucun souci, tout fonctionne très bien...

Voici donc mon problème : Je veux créer un nouveau deck, j'ai donc un bouton "Nouveau Deck" qui fait appel à une fonction newDeck() que voici :

function newDeck()
{
 // J'ajoute mon deck à ma BDD, je recharge tous mes decks... en passant les détails inutiles.
 // Ensuite je dois réinitialiser mon formulaire de decks :
 $("formdeck_name").value=""; // mon textbox
 $("formdeck_format").selectedIndex = "0"; // mon 1er menulist
 $("formdeck_folder").selectedIndex = "0"; // mon 2nd menulist
 // Enfin, je dois sélectionner mon nouveau Deck :
 var New_Deck = $("decklist").getItemAtIndex(Deck_Index);
 $("decklist").selectItem(New_Deck);
 }

Voilà, la dernière ligne active donc mon setDeck() et donc l'affichage de mon Nouveau Deck.

Ce code marche dans un cas, et pas dans l'autre je m'explique :

  • Si mes menulist sont sur 0 et 0 (donc par défaut) lorsque j'appuie sur mon bouton "Nouveau Deck", bien tout se passe bien : Réinitialisation de mon textbox du formulaire, Affichage de tous les decks, Sélection du nouveau et affichage de ce dernier.
  • Si malheureusement, l'un des menulist de mon formulaire est sur autre chose que sa valeur par défaut : Le script fait la moitié du travail ! A partir du moment où je réinitialise la valeur de mon menulist, la sélection et l'affichage de de mon Nouveau Deck ne fonctionnent plus. Il semble donc que updateDeckExplorer() prenne le relais pour mettre à jour la liste des Decks de mon listbox, mais comme il tourne en boucle, il ne redonne pas "la main" à mon newDeck() et ainsi, mon script ne s'achève jamais. Je suis obligé de recliquer une 2nde fois sur "Nouveau Deck" pour finir le travail (là, ça marche puisque mes menulist sont réglés par défaut).

Chose étonnante : Si j'ajoute par exemple :

alert('Nouveau Deck créé');

juste après :

$("formdeck_folder").selectedIndex = "0"; // mon 2nd menulist

Ce qui donnerait :

 $("formdeck_folder").selectedIndex = "0"; // mon 2nd menulist
 alert('Nouveau Deck créé');
 // Enfin, je dois sélectionner mon nouveau Deck :
 var New_Deck = $("decklist").getItemAtIndex(Deck_Index);
 $("decklist").selectItem(New_Deck);

Et bien là, quand je clique sur le "OK" de mon alert(), mon script newDeck() se poursuit et sélectionne donc mon deck et l'affiche !

Voilà, j'ai beau réfléchir, je ne trouve pas de moyen de résoudre "logiquement" mon problème... Est-ce que je m'y prends mal pour mon filtre temps réel ? Y-a-t-il une meilleure méthode que mon setTimeOut() qui tourne en boucle tout le temps ?

Mais surtout comment résoudre ce problème ? A part laisser une petite alert(), je ne vois pas et ce n'est pas super ergonomique de devoir cliquer sur un pop up à chaque création de decks... =/

J'espère avoir été assez clair, si ce n'est pas le cas, merci de ma le faire savoir, j'essaierai de détailler cela un peu plus avant...

Merci d'avance pour votre aide.

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : papy

Date : 27/11/2006 11:18

A première vue je ne vois pas vraiment d'ou viens le problème. En revanche il y a une solution plus élégante que le setTimeout qui tourne en boucle tout le temps.

Les textbox peuvent être de trois type différent, normal, autocomplete et timed. Ce qui t'intéresse est le dernier type, il provoque un évènement au bout de quelque centaine de milliseconde lorsque l'utilisateur change la valeur du champs.

<textbox type="timed" timeout="200" oncommand="updateDeckExplorer();"/>

Regarde la doc sur XulPlanet

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : Raphael

Date : 27/11/2006 15:01

Pour mon problème, je pensais avoir trouvé un début de solution que je vais essayer de coder : Définir un Timer à l'aide de setIntervall() qui me permettrait de l'allumer et de l'éteindre à volonté.

Cela me permettrait de l'éteindre avant de réinitialiser mon formulaire, ensuite je réinitialise manuellement mon listbox, je sélectionne mon deck et une fois toutes mes actions faites, je relance ma minuterie... A vue d'oeil, je pensais que ça pourrait le faire ^^.

Mais comme tu viens de m'apprendre qu'on peut définir un Timeout sur un textbox, du coup, je n'ai plus besoin de me prendre la tête sur une fonction à exécuter tout le temps en fond.

Je vais essayer ça de ce pas...

EDIT : Ca marche, impeccable, à un léger détail esthétique près... Il semblerait que mon code qui sélectionne une ligne de mon listbox le sélectionne "bizarrement" :

var Deck = $("decklist").getItemAtIndex(Deck_Index);
$("decklist").selectItem(Deck);

En fait, la sélection se fait bien puisque mes infos se chargent, mais on dirait que ma ligne n'a pas le "focus" ? Disons que sur le listbox même, on ne voit pas la ligne sélectionnée (normalement, elle est surlignée). Quand on clique sur les autres lignes, elles se sélectionnent et sont surlignées, mais quand on clique sur la ligne sélectionnée par mon script, ben ça sélectionne bien puisque ça charge mes valeurs, MAIS elle ne surligne plus quand on clique dessus...

Ca doit venir de la méthode selectItem non ? ou bien il faut en plus que je mette un focus ?

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : papy

Date : 27/11/2006 15:33

Alors la je n'en ai aucune idée, si tu peux mettre ton script en ligne quelque part je pourrais y jeter un coup d'oeil vite fait, la comme ca je ne vois pas trop ce que tu veux dire... :D

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : Raphael

Date : 27/11/2006 15:48

Bah c'est facile de tester a priori... tu fais un petit listbox vite fait (3 lignes) avec un bouton "sélectionne la ligne 2" par exemple avec un code comme ça a priori:

var item = $("decklist").getItemAtIndex(2);
$("decklist").selectItem(item);

PS : $("decklist"), en fait c'est document.getElementbyID('decklist'), mais j'ai récupéré cette fonction de thefab parce que c'est pratique.

C'est pourtant bien la syntaxe pour sélectionner un élément d'un listbox non ?

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : papy

Date : 27/11/2006 16:19

Après test, tout ceci est un bien une histoire de focus, et c'est assez normal à priori.

Quand ton action est exécuté, la ligne est bien séléctionnée mais pas 'surlignée' car la listbox n'a plus le focus (tu as cliqué ailleurs pour déclencher l'action)

Tu peux mettre le focus sur la listbox si tu veux, chez moi ca produit bien le résultat attendu.

En revanche tu indique un autre problème :

Quand on clique sur les autres lignes, elles se sélectionnent et sont surlignées, mais quand on clique sur la ligne sélectionnée par mon script, ben ça sélectionne bien puisque ça charge mes valeurs, MAIS elle ne surligne plus quand on clique dessus...

Ce problème n'apparait pas chez moi (FF 1.5 et FF2.0, sous Linux) et je ne vois pas ce qui peut empecher le bon fonctionnement de ce mécanisme

# Re: Délicat : un setTimeout() empêche la suite d'un script...

Envoyé par : Raphael

Date : 27/11/2006 16:47

Ok, c'est donc bien une histoire de focus...

Mais après quelques recherches sur XULPlanet, il s'avère que j'avais complètement zapper une méthode très utilse de listbox ! A savoir "selectedIndex ! En fait, je l'utilise pour sélectionner dans mes menulist mais je n'avais pas vu qu'on pouvait aussi l'utiliser avec des listbox ce qui fait que ça arrange complètement mon affaire :

var Deck = $("decklist").getItemAtIndex(Deck_Index);
$("decklist").selectItem(Deck);

devient :

$("decklist").selectedIndex = Deck_Index;

Ce qui est a priori beaucoup plus simple et pratique... et là, ma ligne est bien surlignée ! Mais je trouve quand même étrange que mes 2 codes ne se valent pas...

Enfin, je vais pas trop chercher à comprendre puisque tout marche très bien ^^.

Encore merci pour ton aide =)

Il n'est plus possible de poster des messages dans ce forum.


Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.