11550 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour à tous

J'essaye de réaliser une sorte de bouton "publié/non publié".
J'utilise la fonction ajax de jquery.
Jusque là, tout va bien.
Mes requêtes fonctionnent et la DB est mise à jour.
Par contre, je voudrais pouvoir changer l'état de mon bouton pour qu'il passe de "publié" à "non publié" et vice versa une fois la requete ajax terminé.
Mon problème, c'est que je n'arrive pas à cibler mon élément.


$(document).ready(function() {
	// clique sur le bouton
	$(".promo").click(function(){
		$.ajax({
   			type: "GET",
   			url: "ajax.php",
   			data: "id=" + $(this).attr("name"),
			success : function(msg){
						if(msg == 1){
							$(this).text("actif");
						}else{
							$(this).text("inactif");
						}
					 }
 		})
	});	
});


Je comptais sur le "this" mais vu qu'il est dans une fontion, il ne trouve plus mon ".promo"

Des idées ?
Modifié par sharky (17 Mar 2009 - 13:54)
Si ton bouton est le seul élément de la page avec la classe .promo alors :



	if(msg == 1){
	  $(".promo").text("actif");
	}else{
	  $(".promo").text("inactif");
	}



devrait te suffire. Si c'est le cas autant utiliser un id pour ton code alors.
Justement, non ...
'.promo' n'est pas le seul.
J'utilise ceci dans un listing.

Merci tout de même pour ton aide.
éventuellement :


if (msg == 1) {
  this.text("actif");
} else {
 this.text("inactif");
}
Hello,

Il faudrait écrire quelque chose ressemblant à :
$(document).ready(function() {
  // clique sur le bouton
  $(".promo").click(function(){
    var button = $(this);
    $.ajax({
      type: "GET",
      url: "ajax.php",
      data: "id=" + button.attr("name"),
      success : function(msg){
        if(msg == 1){
          button.text("actif");
        }else{
          button.text("inactif");
        }
      }
    })
  });	
});

Modifié par Julien Royer (13 Mar 2009 - 14:18)
Il y qd même 1 truc qui me chifonne, on attribue la même fonction à tous les éléments portant la classe .promo ; à priori j'aurai attribué 1 fonction distincte qui écoute le clic pour chaque élément portant .promo via each(), un truc de ce genre :

$(document).ready(function() {

  // clique sur le bouton

  $(".promo").each(function (i) {

    var button = $(this);

    $(this).click(function() {
    $.ajax({
      type: "GET",
      url: "ajax.php",
      data: "id=" + button.attr("name"),
      success : function(msg){
        if(msg == 1){
          button.text("actif");
        }else{
          button.text("inactif");
        }
      }
    })
  });	
  });	
});
PiR2 a écrit :
Il y qd même 1 truc qui me chifonne, on attribue la même fonction à tous les éléments portant la classe .promo

C'est l'un des principes fondamentaux de JQuery : on applique une chaîne de traitements à un objet JQuery sans se soucier du nombre d'objets de l'arbre du DOM qu'il contient en réalité.
C'est pire encore ! La variable locale button n'existe que le temps de la réalisation de la fonction each. Globale, on risquerait fort d'avoir des collisions...

L'utilisation d'une vraie valeur de retour, par exemple l'identifiant du bouton, serait, me semble-t-il, la solution la plus propre et la plus sûre...
Modifié par Julien de Prabere (14 Mar 2009 - 11:15)
Julien de Prabere a écrit :
C'est pire encore ! La variable locale button n'existe que le temps de la réalisation de la fonction each. Globale, on risquerait fort d'avoir des collisions...

Pas sûr d'avoir compris de quoi tu parles. Je ne vois pas de variable button globale dans les exemples de code donnés ci-dessus.
Il n'y a qu'une variable locale button dans les exemples donnés. Même globale, elle ne serait pas satisfaisante.
Modifié par Julien de Prabere (14 Mar 2009 - 18:28)
Julien de Prabere a écrit :
Il n'y a qu'une variable locale button dans les exemples donnés.

Ok, d'où le conditionnel dans ta phrase. (En passant: écrire «Même si elle était globale, on risquerait fort d'avoir des collisions...» aurait été largement plus explicite que «Globale, on risquerait fort d'avoir des collisions...». Smiley cligne )

Je viens de comprendre que ta remarque concernait le code proposé par PiR2, et pas celui de Julien Royer. Si la variable locale n'existe que le temps de la réalisation de la fonction each, cela signifie qu'elle ne sera pas disponible dans la fonction associée au clic? (Ou dans les fonctions si on a des instances différentes en mémoire, une pour chaque élément... ça me dépasse un peu.) J'ai effectué un test à l'instant et ça semble contredire cette interprétation.

PS: désolé si mes questions sont à côté de la plaque, j'essaie juste de comprendre. Smiley smile
Modifié par Florent V. (14 Mar 2009 - 19:49)
Florent V. a écrit :
PS: désolé si mes questions sont à côté de la plaque, j'essaie juste de comprendre. Smiley smile

En tout cas, ça m'intéresse car je ne saisis pas non plus le problème évoqué ici.

Je pense que Julien n'a pas bien compris le fonctionnement des portées en JavaScript, notamment en ce qui concerne les fermetures (closures). C'est vrai qu'il s'agit d'un aspect un peu épineux mais ma foi fort pratique. Smiley smile
Julien Royer a écrit :

En tout cas, ça m'intéresse car je ne saisis pas non plus le problème évoqué ici.


Bon je reprend avec ce que je comprend du pb après lecture des différentes interventions pour proposer une solution que j'ai mise en place et testée et qui fonctionne dans mon cadre.

J'ai 4 boutons avec la classe "test", chacun ayant l'attribut name et id renseignés (pour les puristes : oui l'id et le name n'ont pas la même valeur c'est pour la démonstation cf ci-après).
Au chargement de la page jquery affecte une fonction anonyme sur l'évènement clic de chaque bouton ; on récupère au passage dans la variable cur l'élément courant sur lequel travail jquery pour le rendre disponible ensuite dans la fonction de callback (success : de la partie ajax), cf pb des closures.
Si l'on travaille sur des boutons comme le laisse supposer le message initial, je trouve pratique dans ce cas d'utiliser l'attribut name et la méthode de manipulation associée de jquery attr(attribut, valeur) pour faire varier le contenu en fonction de la réponse ajax.

Soit le code suivant dans le body :

  <input type="button" name="b1" id="ib1" value="b1" class="test" /> <br />
  <input type="button" name="b2" id="ib2" value="b2" class="test" /> <br />
  <input type="button" name="b3" id="ib3" value="b3" class="test" /> <br />
  <input type="button" name="b4" id="ib4" value="b4" class="test" /> <br />


et la partie script dans head :



<script type="text/javascript">
$(document).ready(function(){

  $(".test").click(function(){
    [#red]var cur = $(this);[/#]
	$.ajax({
  	  type: "GET",
   	  url: "ajax.php",
   	  data: "id=" + $(this).attr("name"),

	  success : function(msg){
	      if (msg == 1) {
	       [#red] cur.attr("value","actif"+cur.attr("id"));[/#]
     	      } else {
	        [#red]cur.attr("value","inactif"+cur.attr("id"));[/#]
              }
	    }
	 });
  });
});



</script>


Le résultat est qu'un clic sur un bouton change bien le texte du bouton en fonction de la valeur renvoyé par la partie ajax.
Wouawww Smiley smile

On s'est bien amusé pendant mon absence Smiley smile
Merci à tous pour vos réponses.

Je test cela dés que possible et je vous tiens au courant.
Smiley murf
ok, ca fonctionne nickel.
J'étais pas très loin Smiley smile

A titre informatif :

Le fait de placer 'var' transforme la variable en variable globale. C'est bien cela ?
N'est-ce pas dangereux au niveau de la compatibilité entre plusieurs scripts ?
sharky a écrit :
Le fait de placer 'var' transforme la variable en variable globale. C'est bien cela ?

Non, c'est l'inverse. Smiley smile

En JS, les variables sont globales par défaut et deviennent locales dès lors qu'elles sont déclarées grâce au mot-clé var.

P.S. : désolé, Julien, mais je ne vois pas en quoi ta solution diffère de celles proposées au-dessus.
Je ne sais pas si j'ai bien compris les portées en javascript, mais constate que la variable cur du nouvel exemple de PiR2 n'a pas grand chose à voir avec la balise input cliquée.

Il suffit de modifier quelque peu la fonction success pour le constater :

success : function(msg){

	c='';for (i in cur) c+=' '+i+' val '+cur[ i];
	alert('cur.name '+cur.name+' cur.id '+cur.id+' autre p. et v. : '+c)

  	if (msg == 1) {cur.attr("value","actif"+cur.attr("id"));} 
	else {cur.attr("value","inactif"+cur.attr("id"));}}
});


Autrement dit, c'est une variable de Jquery qui sauve la mise et assure le fonctionnement de l'exemple.

Merci Jquery !
Modifié par Julien de Prabere (17 Mar 2009 - 13:08)
Désolé, j'avais confondu Julien de Prabere et PiR2 dans mon message précédent (cela ne change pas le fait que je ne comprends pas l'intérêt de l'exemple de PiR2).
Julien de Prabere a écrit :
Je ne sais pas si j'ai bien compris les portées en javascript, mais constate que la variable cur du nouvel exemple de PiR2 n'a pas grand chose à voir avec la balise input cliquée.

Non, évidemment, puisque cur est construite grâce à la fonction jQuery (ou du moins par son alias $) : $(this).

Pour conserver l'objet de l'arbre DOM correspondant à l'élément input, il aurait fallu écrire var cur = this;.
Julien de Prabere a écrit :
Autrement dit, c'est une variable de Jquery qui sauve la mise et assure le fonctionnement de l'exemple.

Merci Jquery !

La puissance de JQuery ne va pas encore jusqu'à modifier le comportement des portées en JavaScript. Smiley cligne
Julien Royer a écrit :
cela ne change pas le fait que je ne comprends pas l'intérêt de l'exemple de PiR2)

bin proposer un exemple fonctionnel complet (même imparfait) au demandeur initial puisque personne ne l'a fait... Smiley ohwell
Modifié par PiR2 (17 Mar 2009 - 15:02)
Julien Royer a écrit :

Pour conserver l'objet de l'arbre DOM correspondant à l'élément input, il aurait fallu écrire var cur = this;.


Désolé mais cela est faux et provoque une erreur jquery et un arrêt du script.

Extrait de firebug si l'on applique la correction recommandée :

cur.attr is not a function

Pour vérifier et reproduire l'erreur il vous suffit de modifier ma proposition d'exemple fonctionnel.
Pages :