Boucle ne prend que le dernier élément en compte

Petit nouveau ! | 4 Messages

01 avr. 2012, 23:24

Bonjour à tous,

Je n'ai pas pour habitude de demander de l'aide sur un forum mais là urgence et grosse galère oblige.

Voilà je suis actuellement en train de créer une feuilles d'heures que des employés devront compléter tous les jours.
J'ai donc créer un BDD de données avec, entre autre, pour tables employes et taches.

Pour chaque employés j'affiche les taches qui lui sont attribuées.
Les taches sont composées d'un id, d'un nom, d'un descriptif et d'un état (en cours ou fini).
J'ai donc fait une boucle afin d'afficher chaque tache.
Par défaut les taches ont un état "en cours". Cependant, si l'employés l'indique comme "fini" à l'aide de la liste déroulante alors celle ci devra changer dans la BDD.
Pour changer l'état j'ai fait : mysql_query("UPDATE taches SET etatTache='" . $etat_tache ."' WHERE idTache=" . $idTache."");

Mon souci est le suivant : seul le dernier élément de ma boucle est pris en compte. Il n'y a donc que le dernier élément qui peut changer l'état de la tache en "fini".

Voici ma boucle :

$result = mysql_query('SELECT * FROM taches');

while($sql = mysql_fetch_assoc($result)){
if ($sql["idEmp"]==$fiche[0] && $sql["momentTache"]=="apresmidi" ){

echo '<input type="text" name="idTache" value='.$sql["idTache"].'><br />';
echo '<input type="text" name="etat_tache" value='.$sql["etatTache"].'><br />';
echo '<div id="titre_tache">'.$sql["nomChantier"].' : </div><br />';
echo '<div id="descriptif_tache">'.$sql["descriptifTache"].'</div><br />';

echo '
<select name="etat_tache">
<option selected value="encours">En cours</option>
<option value="fini">Fini</option>
</select>
<br /><br />';

}


}

Pourriez vous m'éclaircir ? Merci d'avance

Eléphant du PHP | 267 Messages

01 avr. 2012, 23:38

salut,

chaque "select" doit avoir un attribut "name" unique
donc il faut mettre quelque chose du genre :
echo '
<select name="etat_tache_'.$sql["idTache"].'">
<option selected value="encours">En cours</option>
<option value="fini">Fini</option>
</select>
';

@+
dix2

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

01 avr. 2012, 23:41

Salut,

Le problème n'est pas du a la boucle (regarde la source html). Il est du au fait que tu a x select avec le même nom, donc un seul sera prit en compte.
Deux solutions :
- php + html : tu utilise la notation tableau pour nom les champs sélect et le champs input de l'id (qui devrait être de type hidden) cela te permettras de faire la correspondance entre le sélect et le sujet.
Un boucle pour traiter le résultat (et une requête préparée pour l 'update).

- avec Ajax : que tu modife l'état une fonction JS appelle une fichier php qui va faire la mise à jour de la base. Il faut pour cela passer en paramètre la valeur de l'Element.


@+
Il en faut peu pour être heureux ......

Petit nouveau ! | 4 Messages

02 avr. 2012, 00:04

Merci pour vos conseils je comprend déjà mieux mon erreur.
J'ai donc créé une variable $id_etat="etat_tache'.$id.'"; afin de la placer dans le name du select.

Cependant, je rencontre encore un problème avec le UPDATE.
Comment appeler la value du select (en gras ci-dessous)

mysql_query("UPDATE taches SET etatTache='" . $_POST[$id_etat] ."' WHERE idTache=" . $sql["idTache"]."");

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

02 avr. 2012, 05:34

Le problème avec ce type de notation c'est de savoir ou tu en ai. À priori tu peux pas savoir ou tu commence ni ou faut s'arrêter.

Ce n'est une bonne idée que lorsque le nom n'est pas trop significatif.
Utilisé plutôt la notation tableau (par exemple name="etat[]" et name="idTache[]")
À partir de la tu obtient des tableaux dans $_POST ($_POST['etat'] et $_POST['idTache']).
Le traitement du formulaire est "simple" tu parcourt l'un des tableaux avec la boucle foreach et fait un update dans la boucle.

exemple
<form action="" method="post">
    <input type="hidden" name="idTache[]" value=" ...." />
    <select name="etat[]"><option value="en cours">en cours</option><option value="finie">finie</option>
    </select>
    <input type="submit" />
</form>
validation
<?php
if (!empty($_POST['etat']) && !empty($_POST['idTache'])) {
    if (is_array($_POST['etat'])) && is_array($_POST['idTache']){
        foreach($_POST[idTache'] as $id => $key) {
            // requete SQL le mieux c'est une requete préparée
        }
    }
}
?>
Autre possibilité tu force les clefs du tableau et les utilisent pour la requete
par exemple
<form action="" method="post">
<?php
	// requete sql
	while($data = mysql_query($sql)) {
	echo $data['truc'].'<br />';
		echo '<select name="etat['.$data['idTache'] .']"><option value="en cours">en cours</option><option value="finie">finie</option></select><br />';
	}
	?>
    <input type="submit" />
</form>
Validation
<?php
if (!empty($_POST['etat']) && is_array($_POST['etat'])) {
	$pdo = new PDO('mysql:host=leserveurmysql;dbname=leNomDeLaBase;','user','passwd');
	$stmt = $pdo->prepare('update table set etat=:etat where idTache=:idTache');
	foreach($_POST['etat'] as $key => $value) {
		$stmt->execute(array(
			':etat'=>$value,
			':idTache'=>$key
		));
	}
}
?>
Perso j'utiliserais plutôt une Checkbox pour indiquer s'il faut changer d'état afin d'éviter les requête inutile.


@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 2278 Messages

02 avr. 2012, 10:07

Perso j'utiliserais plutôt une Checkbox pour indiquer s'il faut changer d'état afin d'éviter les requête inutile.
Pour chaque employé:
non pas un select, mais
un champ (caché ou pas mais non modifiable) indiquant l'état actuel de la tâche
autant de boutons radio que d'états possibles de la tâche
un truc dans ce genre:
<input type= 'text' name = 'etat_passe[]'  readonly = 'readonly' value ='Encours' />
<input type= 'text' name = 'id_employe[]' readonly = 'readonly' value ='1' />
<input type= 'text' name = 'id_tache[]' readonly = 'readonly' value ='1' />
<input type = 'radio' name ='etat_actuel' value = 'Encours'>En cours
<input type = 'radio' name ='etat_actuel' value = 'Achevé'>Achevé
<input type = 'radio' name ='etat_actuel' value = 'Afaire'>A faire
répété pour chaque employé
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 4 Messages

02 avr. 2012, 18:09

j'ai enfin pu résoudre mon problème :)
Merci beaucoup !