11521 sujets

JavaScript, DOM et API Web HTML5

Derrière ce titre énigmatique, je m'interroge sur le fait de pouvoir récupérer , avec Ajax, des variables envoyées.
Apparemment je ne récupère que du texte (responseText) ou du xml (responseXML) mais si je voulais récupérer des paramètres passés, je peux?

voir le code ci-joint (c'est une maquette).
en gros j'ai 4 cases à cocher, et dans $result01[0]->task_1; ..2...3...4 il y a une valeur 0 ou 1 (extrait d'une base mysql) qui détermine si la case et cochée ou pas.
J'ai un bouton (#unlock-task) qui me permet de rendre modifiable les cases à cocher.
Par ajax de jQuery, quand je coche une case, j'envoie un champ (task_1, task_2, task_3 ou task_4) ainsi que sa valeur 'avant cochage' (data-state).
Le fichier update_task.php lance donc une requête (avec new_valeur) pour inverser au final la valeur (0 ou 1).
ça fonctionne parfaitement au niveau Mysql... mais je voudrais récupérer data-field et data-set pour mettre à jour les valeurs dans mon html sans avoir à recharger la page web, et je sais pas comment récupérer ces deux valeurs..
Peut-être que c'est trop évident et que je le vois pas...


<div id="planning-live" class="container">
	<div class="row">
		<div class="col-xs-2">
			<button id="unlock-task" type="submit" class="btn btn-default">Modifier une tâche</button>
		</div>
		<div class="col-xs-10">
			<div  id="task-group" class="form">
				<div class="checkbox task-box">
				    <label>
				      <input type="checkbox" 
				      	disabled data-field="task_1" 
				      	data-state="<?php echo $result01[0]->task_1; ?>"
				      	data-id="<?php echo $result01[0]->id_task; ?>" 
				      	<?php echo ($result01[0]->task_1 == 1 ? "checked":""); ?> > Task 1
				    </label>
				</div><!-- /checkbox -->
				<div class="checkbox task-box">
				    <label>
				      <input type="checkbox" 
				      	disabled data-field="task_2" 
				      	data-state="<?php echo $result01[0]->task_2; ?>" 
				      	data-id="<?php echo $result01[0]->id_task; ?>" 
				      	<?php echo ($result01[0]->task_2 == 1 ? "checked":""); ?> > Task 2
				    </label>
				</div><!-- /checkbox -->
				<div class="checkbox task-box">
				    <label>
				      <input type="checkbox" 
				      	disabled data-field="task_3" 
				      	data-state="<?php echo $result01[0]->task_3; ?>" 
				      	data-id="<?php echo $result01[0]->id_task; ?>" 
				      	<?php echo ($result01[0]->task_3 == 1 ? "checked":""); ?> > Task 3
				    </label>
				</div><!-- /checkbox -->
				<div class="checkbox task-box">
				    <label>
				      <input type="checkbox" 
				      	disabled data-field="task_4" 
				      	data-state="<?php echo $result01[0]->task_4; ?>" 
				      	data-id="<?php echo $result01[0]->id_task; ?>" 
				      	<?php echo ($result01[0]->task_4 == 1 ? "checked":""); ?> > Task 4
				    </label>
				</div><!-- /checkbox -->

			</div><!-- /form -->

		</div>
	</div>	

</div><!-- /container -->





$(document).ready(function(){
	if (document.getElementById("planning-live")) {
		/* -----------------------------------------  */
		/*        déblocage edition task              */
		/* -----------------------------------------  */
		// click surle bouton modifier une tâche
		$("#unlock-task").on('click', function() { 
			//console.log('hi');
			$this = $(this)
			$this.hide();
			$(".task-box input").prop('disabled', false);
		});

		/* -----------------------------------------  */
		/*   modifier une case à cocher d'une tâche   */
		/* -----------------------------------------  */
		$(".task-box input").on('change', function() {
			$this = $(this)
			var champ_a_modifier = $this.data('field');
			var valeur_actuelle = $this.data('state');
			var new_valeur = (valeur_actuelle == 0 ? 1 : 0);
			var id_to_change = $this.data('id');

			$.ajax({
				url :"update_task.php",
				data : { the_field : champ_a_modifier,
					the_value : new_valeur,
					the_id : id_to_change
				},
				complete : function(xhr, result){
					var response = xhr.responseText;
					console.log(xhr);
					if (result == 'success') {
						$("#show-result").html('Maj effectuée');
					}
				} 
			});
		});

	} // fin getElementById("planning-live")
}); 




<?php 
try {
	$db = new PDO('mysql:host=localhost;dbname=mkdatetest', 'root', '',array(
			PDO::MYSQL_ATTR_INIT_COMMAND =>'SET NAMES UTF8',
			PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING 
			));
	} catch (PDOException $e) {
		echo $e->getMessage();	
	}

$data = array(
	'id'=>$_REQUEST["the_id"],
	'valeur'=>$_REQUEST["the_value"]
	);
		
$sql = "UPDATE tasks_group 
	SET ". $_REQUEST["the_field"] ." = :valeur 
	WHERE id_task=:id";

$req = $db->prepare($sql);
$retour = $req->execute($data);
echo $retour;

 ?>

Modifié par lionel_css3 (01 Feb 2017 - 22:29)
Modérateur
Salut !

Et bien au moment ou tu as la réponse tu affiches un message de confirmation :
if (result == 'success') {
	$("#show-result").html('Maj effectuée');
}

Il te suffit de remplir les champs en Js ici avec $this.data('state','leNouveauState');

Ou alors je suis passé à coté de la question ^^'
Salut Lionel,

Je ne comprends pas toute la logique de ton script mais ton souci est de récupérer des variables au retour du serveur, dans le "complete" de ton $.ajax(), c'est bien ça ? Après ton traitement en base de données ?

A l'heure actuelle tu récupère juste $retour, c'est bien ça ?
Modifié par MatthieuR (01 Feb 2017 - 22:51)
alors oui effectivement, c'était sous mon nez.... ça marche, je viens de m'en apercevoir, la valeur de data-state change bien dans le html, mais par contre si je re coche la case à nouveau, il envoie tout le temps la valeur initiale de data-state comme si jQuery ne tenait pas compte que cette valeur a changé..


					if (result == 'success') {
						$("#show-result").html('Maj effectuée: valeur:' + new_valeur + ' champ:'+
							champ_a_modifier);
						$this.parent().css('color','#090');
						$this.attr('data-state', new_valeur);
					}


MatthieuR a écrit :
Salut Lionel,

Je ne comprends pas toute la logique de ton script mais ton souci est de récupérer des variables au retour du serveur, dans le "complete" de ton $.ajax(), c'est bien ça ? Après ton traitement en base de données ?

A l'heure actuelle tu récupère juste $retour, c'est bien ça ?


alors en fait $retour ne me sert juste à vérifier (si il est égal à 1) que la requête s'est bien déroulée. en fait les valeurs que j'envoie, je les avais sous le nez dans la fonction javascript, maintenant le problème c'est que même si je fais changer l'attribut data-state dans le html, au retour d'Ajax, jQuery ne s'en aperçoit pas, on dirait.
Modifié par lionel_css3 (01 Feb 2017 - 22:57)
Oui, ça vient du fait peut-être que tu utilises la méthode .on() sur l'élément lui-même, il faudrait tenter une délégation de cet "eventListener".
En effet, tu attaches un événement à un élément qui va par la suite se modifier mais l'événement reste attaché à cet élément dans son premier état connu.

Tu peux donc tenter ça :
$(".task-box").on('change', 'input', function() {
  //...
});

Il faut en effet attacher un événement à un élément fixe parent de ton target.
Modifié par MatthieuR (01 Feb 2017 - 23:10)
Merci Matthieu, en effet il me semblait bien que ça ressemblait à l'histoire que l'on réglait avant avec "l'ancien" live() ou delegate() qui a été supprimé et remplacé par on()

je me rappelais plus qu'on pouvait utiliser la syntaxe que tu mentionnes mais j'ai réussi à faire marcher mon code en remplaçant data-state par un champ <input> caché et en jouant sur sa valeur et là ça fonctionne.

Je ne sais pas trop quelle solution est la meilleure, tout en sachant qu'au final j'aurai une bonne dizaine de cases à cocher..


				<div class="checkbox task-box">
				    <label>
						<input type="checkbox" 
							disabled data-field="task_1" 
							data-id="<?php echo $result01[0]->id_task; ?>" 
							<?php echo ($result01[0]->task_1 == 1 ? "checked":""); ?> > Task 1
						<input class="hid" type="hidden" value="<?php echo $result01[0]->task_1; ?>">			
				    </label>
				</div><!-- /checkbox -->




		/* -----------------------------------------  */
		/*   modifier une case à cocher d'une tâche   */
		/* -----------------------------------------  */
		$(".task-box input").on('change', function() {
			$this = $(this)
			var champ_a_modifier = $this.data('field');
			var valeur_actuelle = $this.next().val();
			var new_valeur = (valeur_actuelle == 0 ? 1 : 0);
			var id_to_change = $this.data('id');

			$.ajax({
				url :"update_task.php",
				data : { the_field : champ_a_modifier,
					the_value : new_valeur,
					the_id : id_to_change
				},
				complete : function(xhr, result){
					var response = xhr.responseText;
					console.log('valeur envoyée data-state: '+ valeur_actuelle);
					if (result == 'success') {
						$("#show-result").html('Maj effectuée: valeur:' + new_valeur + ' champ:'+
							champ_a_modifier);
						$this.parent().css('color','#090').find('input.hid').val(new_valeur);
					}
				} 
			});
		});


Sinon, ton utilisation de $.ajax() n'est pas optimale.
Tu peux envoyer depuis ton serveur (update_task.php) une réponse en json et donc recevoir un réponse riche dans ton callback JS.
Depuis ton PHP tu peux retourner ça :
echo json_encode(
    array(
        'success' => true,
        'test' => 'valeur de l\'entrée test',
    )
);

Ensuite côté JS, ton appel AJAX peut ressembler à ça :
    $.ajax({
        url :"server.php",
        dataType: 'json', //on veut une réponse au format JSON
        method: 'post', //on passe les données via POST, c'est plus propre
        data : {
          the_field : champ_a_modifier,
          the_value : new_valeur,
          the_id : id_to_change
        },
        success : function(response){ //on utilise le callback 'success' plutôt que complete
          console.log(response);
          if (response.success) {
            $("#show-result").html('Maj effectuée');
            //toutes les variables sont disponibles :
            var test = response.test;
          }
        } 
      });

Modifié par MatthieuR (01 Feb 2017 - 23:35)
Meilleure solution
MatthieuR a écrit :
Sinon, ton utilisation de $.ajax() n'est pas optimale.
Tu peux envoyer depuis ton serveur (update_task.php) une réponse en json et donc recevoir un réponse riche dans ton callback JS.


Ah oui, génial !! c'est exactement ça que je cherchais en fait, pouvoir retourner des variables séparées, au lieu d'un seul bloc texte ou xml, car dans ce cas se sont les valeurs actuelles qui sont passées dans le Php.
Je reprends mon code dès demain matin Smiley smile
Un grand merci à toi
Modifié par lionel_css3 (01 Feb 2017 - 23:43)
Ah, je me disais bien que c'était ça que tu cherchais ! Smiley biggrin
Modifié par MatthieuR (01 Feb 2017 - 23:44)
MatthieuR a écrit :
Ah, je me disais bien que c'était ça que tu cherchais ! Smiley biggrin


Oui, tu me solutionnes mon problème Smiley smile

Après, entre l'attribut data-state (avec délégation) ou le champ input caché je sais pas trop lequel est le plus optimum
MatthieuR a écrit :
Oui, ça vient du fait peut-être que tu utilises la méthode .on() sur l'élément lui-même, il faudrait tenter une délégation de cet "eventListener".
En effet, tu attaches un événement à un élément qui va par la suite se modifier mais l'événement reste attaché à cet élément dans son premier état connu.

Tu peux donc tenter ça :
$(".task-box").on('change', 'input', function() {
  //...
});

Il faut en effet attacher un événement à un élément fixe parent de ton target.


alors j'ai quand même essayé cette 'délégation' mais ça ne prend pas en compte le changement de la valeur de data-state, alors je suis resté sur le champ hidden supplémentaire.
Sinon, ton amélioration pour mon code $.ajax .. impéccable Smiley smile