8791 sujets

Développement web côté serveur, CMS

Bonjour !

**************************************************
edit du 19/09/2014
ce post a été déplacé depuis le section javascript car en fait le problème vient de PHP MysQl
**************************************************



J'ai créé une petite application web perso pour gérer ma collection de CDs.

Dans une liste d'éléments qui sont extraits depuis une BDD Mysql je rends modifiable l'élément h3 qui a la classe 'editable'

lorsque je clique sur ce h3, je rajoute un input type=text dans le h3 et un bouton de validation juste après ce h3 et je peux donc modifier le contenu du h3.
Lorsque je clique sur le bouton, je récupère l'index de l'élément (contenu dans un paragraphe précédent le h3) et le contenu de l'input text dont je me sers pour créer la variable sql.

J'envoie tout ça avec la fonction mettre_a_jour_titre() qui créé une requête Ajax avec le fichier _modif_titre.php qui met à jour la base de données avec le contenu du champ de type input.

Mon code fonctionne bien, je clique sur un titre h3, je le modifie, je clique que le bouton OK et ma BDD se met bien à jour et la requête Ajax retourne 'done' (response du fichier php).

Par contre, si je clique sur un h3 et que finalement je ne modifie rien, c'est à dire en laissant la valeur présente, alors quand je clique sur OK, l'Ajax retourne 'fail' (response du fichier php) et j'affiche le message 'problème avec la requête Sql' du fichier JS.
Le contenu dans la base MySql reste bien sur inchangé dans ce cas.

Je n'arrive pas à trouver de solution pour contourner cela...

code HTML (extrait)


<div id="display-table">
   <div class="row">
    	<div class="col col-left">
            <a class="maj-image" title="425" href="#" ><img alt="425" src="images/425-1410706931-img.jpg" ></a>
        </div>
        <div class="col col-right">
            <p><a href="modif-cd-pdo.php?id=425">425</a> - Rock</p>
            <h2>Chicago</h2>
            <h3 class="title-item editable">I</h3>
            <p class="paru">paru: 1969 -  - C</p>
        </div>
    </div>
	    <div class="row">
    	<div class="col col-left">
            <a class="maj-image" title="426" href="#" ><img alt="426" src="images/426-1410706809-img.jpg" ></a>
        </div>
        <div class="col col-right">
            <p><a href="modif-cd-pdo.php?id=426">426</a> - Rock</p>
            <h2>Chicago</h2>
            <h3 class="title-item editable">III</h3>
            <p class="paru">paru: 1971 -  - C</p>
        </div>
    </div>
   <div class="row">
    	<div class="col col-left">
            <a class="maj-image" title="427" href="#" ><img alt="427" src="images/427-1410706835-img.jpg" ></a>
        </div>
        <div class="col col-right">
            <p><a href="modif-cd-pdo.php?id=427">427</a> - Rock</p>
            <h2>Chicago</h2>
            <h3 class="title-item editable">II</h3>
            <p class="paru">paru: 1971 -  - C</p>
        </div>
    </div>
</div>



code JS (extrait)


/* **********************************************  */
/*        mise à jour titre h3   titre             */
/* **********************************************  */
	var clickable = true;
	var idH3ToChange, h3NewContent, h3Tag, retourH3Update;
	
	$(".col-right h3.editable").on('click', function(e) {
		if (clickable == true)  {
			clickable = false;     //  bloque l'action sur click h3
			var $this = $(this);
			$(".col-right h3").removeClass('editable');
			idH3ToChange = ($this.closest('.col-right').find("p a").text());
			$this.wrapInner( "<input id='new-titre' type='text' size='50' value='" + $this.text() + "' name='new-name' >");
			$this.after("<input id='go-h3' type='submit' value='Go' />");
		}   // fin du if clickable == true
	});  // fin du on()
	
	$(".col-right").on('click', '#go-h3', function(e) {
		var $this = $(this);
		h3Tag = $this.prev();
		h3NewContent = h3Tag.find('input#new-titre').prop('value');
		sql = "id=" + idH3ToChange + "&new_valeur=" + h3NewContent; 
		
		mettre_a_jour_titre(sql, h3Tag, h3NewContent); 
		 
		$(".col-right h3").addClass('editable');	
		clickable = true;
		
	});


/* **********************************************  */ // 
/*            fonction ajax h3  titre              */
/* **********************************************  */

	function mettre_a_jour_titre(options, baliseH3, contenuH3) { 
		var xmlhttp = new XMLHttpRequest();	
		
		xmlhttp.addEventListener('readystatechange', function() {  
			if(this.readyState === 4) {
				if(this.status === 200) {
					retourH3Update = xmlhttp.responseText;  
					$("#go-h3").remove(); 
					$("input#new-titre").remove();
					if (retourH3Update == "done") {
						baliseH3.html(contenuH3);
					} else  {  // fail
						baliseH3.html("problème avec la requête Sql");
					}
				} else {  // status !== 200
					baliseH3.html("problème http request");
				}
			}
		});

		xmlhttp.open('post', "_modif_titre.php", true);
		xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		xmlhttp.send(options);
	}


code PHP


<?php 

$id = $_POST['id'];
$titre= $_POST['new_valeur'];

require_once('connexions/disco_idx_pdo.php');

$req = "UPDATE  disques SET titre = '" . $titre. "' WHERE id =  " . $id ; 

if ($connexion->exec($req)):
	echo 'done';
else:
	echo 'fail';
endif;

?>

Modifié par lionel_css3 (19 Sep 2014 - 10:52)
Bonjour Lionel.

Sans répondre directement à ton problème, est-ce qu'il ne serait pas judicieux de rajouter un bouton annuler qui n'enverrait pas la requête ?
@ Solidsnake, oui bien sur c'est possible de rajouter un bouton annuler, mais ça n’empêcherait pas l'utilisateur de cliquer quand même sur le bouton de validation sans modifier le contenu du champ <input>

le plus drôle c'est qu'en cliquant sur Go sans rien changer il envoi bien la variable javascript sql correctement constituée...
C'est pas faux.

lionel_css3 a écrit :
le plus drôle c'est qu'en cliquant sur Go sans rien changer il envoi bien la variable javascript sql correctement constituée...

Ben oui, vu ton code, il n'a aucune raison (enfin que je vois) pour déterminer si oui ou non ton contenu a changé ! C'est balaise.

Tu as essayé d'appeler ton PHP avec des paramètres identiques à ce qu'il y a déjà dans la base ?

Et pourquoi ne pas utiliser la méthode $.ajax() de jQuery pour ton appel ?
Modifié par SolidSnake (16 Sep 2014 - 13:57)
je n'ai toujours pas résolu le problème évoqué au début mais j'ai un autre problème.

dans les titres que je modifie (les h3), il y a des éléments avec des apostrophes, admettons une chaine comme Bill's cat (contenue au départ dans la base de données Mysql)

la page affiche bien Bill's Cat , mais si je clique sur le h3 pour entrer en édition, il affiche Bill, exit le reste de la chaine (ce qui se comprend)
c'est logique, javascript tronque la chaine après l'apostrophe..

Mais que faire?

Lorsque je créé le champ avec le script PHP, si j'applique la fonction addslashes() avant d'exécuter la requête Mysql, le champ enregistré sera Bill\' Cat dans la base de données mySql et il s'affichera tel quel: Bill\' Cat dans la page web... mais il affichera Bill\ si je clique sur le h3, c'est un cercle vicieux, je sais pas comment faire, pourtant ce doit être un problème récurent, j'imagine.

merci pour votre aide.



Edit: en résumé mon problème c'est ceci:

si la chaine contient une apostrophe, la première ligne (console.log) affiche la chaine avec l'apostrophe, la 2ème ligne (wrappinner) tronque la chaine après l'apostrophe...
un truc de fou....


	console.log($this.text());
	$this.wrapInner( "<input id='new-titre' type='text' size='50' value='" + $this.text() + "' name='new-name' >");

Modifié par lionel_css3 (18 Sep 2014 - 10:44)
Pour ton dernier problème, je te dirais bien d'essayer d'échapper ton apostrophe avec la petite fonction que j'ai trouvé sur le net :
function addslashes(ch) {
  ch = ch.replace(/\\/g,"\\\\")
  ch = ch.replace(/\'/g,"\\'")
  ch = ch.replace(/\"/g,"\\\"")
  return ch;
}

En l'occurence seule la 2ème ligne est importante dans ton cas.
Ça pourrait pitêtre marcher Smiley ravi
j'ai trouvé cette fonction, j'ai essayé et ça résoud pas le problème...

ça rajoute un \ à l'affichage .. et ça coupe le chaine ... Bill\ Smiley decu
je viens de trouver une solution à mon 2ème problème:

je remplace la ligne


$this.wrapInner( "<input id='new-titre' type='text' size='50' value='" + $this.text() + "' name='new-name' >");

par

$this.wrapInner( "<input id='new-titre' type='text' size='50' value='' name='new-name' >");
$("#new-titre").prop('value', $this.text());


dans le fichier php, j'applique addslashes à la variable $titre comme ceci.


$titre= addslashes($_POST['new_valeur']);


maintenant les titres sont sauvegardés en BDD avec les apostrophes correctes (sans le \)
ça marche ais j'ai pas compris pourquoi..

J'ai toujours le premier problème
Je reviens sur le premier problème ( click sur bouton Go sans avoir modifié le champ )
dans le fichier Php , j'ai fait un echo $req pour récupérer la requête, elle est correcte, je l'ai même exécutée avec succès dans phpMyadmin.

Je ne comprends pas pourquoi le fichier php renvoi 'fail' , c'est là que se situe l'erreur en fait
************************************************************
Pour ceux qui prennent le fil en route, c'est à partir d'ici que je me suis aperçu qu'il s'agissait d'un problème PHP MySql
**************************************************************




dans le cas où je clique sur Go sans modifier le champ, la requête UPDATE est bien envoyée, mais avec une valeur du champ titre identique à celle présente dans la base de données.

par exemple:
j'ai un champ titre avec la valeur les années 20

si j’exécute dans PHPMyAdmin une requête
UPDATE disques SET titre = 'Les années 2000' WHERE id = 62

le champ titre devient bien les années 2000

par contre si je re exécute la même requête de suite, PHPMyAdmin me retourne '0 lignes affectées', ça voudrait dire que Php ne modifie pas un champ si la nouvelle valeur est égale à la valeur actuelle?

c'est ce qui correspond au cas de mon erreur, je ne modifie pas un champ et je propose de modifier le champ avec une valeur qu'il possède déjà...

on peut gérer ce problème de quelle façon?
Modifié par lionel_css3 (19 Sep 2014 - 11:19)
voici comment j'ai modifié le fichier PHP pour éviter l'apparition de l'erreur..

bien sur je ne suis pas totalement satisfait..... Smiley cligne



$id = $_POST['id'];
$titre= addslashes($_POST['new_valeur']);  

require_once('connexions/disco_idx_pdo.php');



// test de redondance 
$req0 = "SELECT titre from disques WHERE id = " . $id;
$toto = $connexion->query($req0);

$results = $toto->fetchAll(PDO::FETCH_OBJ);

if ($results[0]->titre == $_POST['new_valeur'])  {
	echo 'done';  // valeur identique, on fait rien
	
	}  else  {
		
	$req1 = "UPDATE  disques SET titre = '" . $titre. "' WHERE id =  " . $id ; 
	if ($connexion->exec($req1))  {
		echo 'done';
	} else {
		echo 'fail';
	}
		
}