[RESOLU] transfert d'informations d'un select multiple à une page php

Petit nouveau ! | 8 Messages

29 janv. 2016, 20:12

Bonjour,

Après avoir épluché les différents forum dont celui ci, je ne trouve pas la solution a mon dilemme.

Voila, j'ai un formulaire avec 2 select multiple et je fais passer les infos d'une case à l'autre à l'aide de 2 boutons (ajouter/retirer)

Le soucis c'est que comme c'est fait, je n'arrive pas à transmettre le contenu d'un des select (attention pas les données sélectionné, mais l'ensemble du contenu, value + text) à la page php via "_POST"

J'ai trouvé des solutions sur les forums en utilisant [] dans le nom du select
<SELECT name="serveursjoint[]" size="10" multiple>

Le soucis, c'est que si je fais ça pour transmettre le contenu du select, je bousille mon programme en javascript qui permet de passer les données d'une liste à l'autre.

Je suis preneur donc de solutions.

Mes 2 fonctions javascript :
function ajoute_serveur()
{
// déclaration des tableaux
var selectedList = [];

// initialisation des variables
selectnum = 0; // contient le nombre de serveur à ajouter
nbserveurs = document.formappli.serveurs.options.length; // contient le nombre de serveurs non affectés
nbserveursjoint = document.formappli.serveursjoint.options.length; // contient le nombre de serveurs affectés


// on boucle pour récuperer la liste des serveurs à ajouter à l'application
for (i=0; i < document.formappli.serveurs.options.length; i++)
{
	if ( document.formappli.serveurs.options[i].selected )
	{
		// on affecte l'objet selectionné au tableau
		selectedList.push(document.formappli.serveurs.options[i]);
		// on incrémente la valeur
		selectnum++;		
	}
}
	
for (i=0; i < document.formappli.serveurs.options.length; i++)
{
	if ( document.formappli.serveurs.options[i].selected )
	{
		// on supprime la valeur pour la déplacer dans l'autre case
		document.formappli.serveurs.removeChild(document.formappli.serveurs.options[i]);
		i--;
	}
}
	
	
	//une boucle pour parcourir l'ensemble des objets selectionnés (value = id_serveur) (text = nom_serveur)
	for (i=0; i < selectnum ; i++)
	{
	 longueur = parseInt(nbserveursjoint) + parseInt(i); // on incrémente la valeur max du select
	 //alert("liste " + selectedList[i].value + " " + selectedList[i].text + "inserer en " + longueur + "position");
	 // on rajoute les valeurs selectionné dans le select "serveursjoint"
	 document.formappli.serveursjoint.options[longueur] = new Option(selectedList[i].text, selectedList[i].value, false, false);		
	}
}

function retire_serveur()
{
// déclaration des tableaux
var selectedList = [];

// initialisation des variables
selectnum = 0; // contient le nombre de serveur à ajouter
nbserveurs = document.formappli.serveurs.options.length; // contient le nombre de serveurs non affectés
nbserveursjoint = document.formappli.serveursjoint.options.length; // contient le nombre de serveurs affectés


// on boucle pour récuperer la liste des serveurs à ajouter à l'application
for (i=0; i < document.formappli.serveursjoint.options.length; i++)
{
	if ( document.formappli.serveursjoint.options[i].selected )
	{
		// on affecte l'objet selectionné au tableau
		selectedList.push(document.formappli.serveursjoint.options[i]);
		// on incrémente la valeur
		selectnum++;
	}
}

for (i=0; i < document.formappli.serveursjoint.options.length; i++)
{
	if ( document.formappli.serveursjoint.options[i].selected )
	{
		// on supprime la valeur pour la déplacer dans l'autre case
		document.formappli.serveursjoint.removeChild(document.formappli.serveursjoint.options[i]);
		i--;
	}
}

	
	// une boucle pour parcourir l'ensemble des objets selectionnés (value = id_serveur) (text = nom_serveur)
	for (i=0; i < selectnum ; i++)
	{
	 longueur = parseInt(nbserveurs) + parseInt(i); // on incrémente la valeur max du select
//	 alert("liste " + selectedList[i].value + " " + selectedList[i].text + "inserer en " + longueur + "position");
	 // on rajoute les valeurs selectionné dans le select "serveurs"
	 document.formappli.serveurs.options[longueur] = new Option(selectedList[i].text, selectedList[i].value, false, false);		
	}
Je me doute que je pourrais améliorer le code, ça viendra plus tard :wink:

Voici maintenant mon formulaire
<FORM name="formappli" method="POST" action="modif_appli.php">

<?php echo '<input type="hidden" name="id_appli" value="'.$ligne['id_APPLI'].'" >'?>
<B>Code Application</B>
<?php echo '<input type="text" name="code_appli" value="'.$ligne['CODE_APPLI'].'" >'?>
<BR>
<B>Application</B>
<?php echo '<input type="text" name="nom_application" value="'.$appli.'" >'?>
<BR>

<B>Serveurs associés</B>
<BR>
<SELECT name="serveursjoint" size="10" multiple>

<?php
while ($ligne2 = $resultat2->fetch_assoc()) 
{ 
 echo '<OPTION value="'.$ligne2['id_SERVEUR'].'">'.$ligne2['NOM_SERVEUR'].'</OPTION>';
}
?>
</SELECT>
<input type="button" value="<<<<<" onclick="ajoute_serveur();"><input type="button" value=">>>>>" onclick="retire_serveur();">
<SELECT name="serveurs" size="10" multiple>

<?php
while ($ligneserveurs = $resultatserveurs->fetch_assoc()) 
{ 
 echo '<OPTION value="'.$ligneserveurs['id_SERVEUR'].'">'.$ligneserveurs['NOM_SERVEUR'].'</OPTION>';
}
?>
</SELECT>

<BR>
<?php echo '<textarea rows="20" cols="50" name="commentaire">'.$ligne['COMMENTAIRE'].'</textarea>'?>
<BR>
<input type="submit" value="Mettre à jour"><input type="reset" value="Annuler">

</FORM>

Dans la page modif_appli.php

Je voudrais récupérer dans une variable l'équivalent de

$serveursjoint = $_POST['serveursjoint'];

Merci d'avance

Avatar du membre
Mammouth du PHP | 1609 Messages

29 janv. 2016, 20:27

Bonsoir, le select est fait pour transmettre l'option ou les options sélectionnées lors de la soumission du formulaire. Pourquoi vouloir transmettre tout son contenu ?
Modifié en dernier par Saian le 30 janv. 2016, 00:37, modifié 1 fois.
Développeur web depuis + de 20 ans

Petit nouveau ! | 8 Messages

29 janv. 2016, 20:47

Je n'ai pas élargie le sujet sur les [], mais la solution trouvé était qu'au moment de l'envoi du formulaire on faisait une sélection de tout le SELECT
Le SELECT contient la liste des serveurs relié à mon application.
Si je retire des serveurs ou en ajoute, je dois mettre à jour la table correspondante.

Apres si il y a possibilité de faire autrement je suis preneur.

Avatar du membre
Mammouth du PHP | 1609 Messages

29 janv. 2016, 21:08

Tu peux essayer quelque chose comme ça, ajouter un input hidden serveursjoint_hidden et ajouter une fonction submit_form sur le submit du formulaire.

La fonction javascript :
function submit_form() { 
	var sj = document.formappli.serveursjoint;
	var datas = [];

	for (i = 0; i < sj.options.length; i++)
		datas.push(sj.options[i].value + '|' + sj.options[i].text);

	document.formappli.serveursjoint_hidden.value = datas.join(';');
	return true;
}
Traitement php :
$serveursjoint = explode(';', $_POST['serveursjoint_hidden']);
foreach($serveursjoint as $serveur)
	list($value, $text) = explode('|', $serveur);
Code non testé donc erreurs potentielles. ^^
Développeur web depuis + de 20 ans

Petit nouveau ! | 8 Messages

01 févr. 2016, 16:43

Merci, ton idée semble sympa.
Je dois juste me familiariser avec certaines commande que tu utilises pour savoir comment récupérer mes valeurs par la suite.

Avatar du membre
Mammouth du PHP | 1609 Messages

01 févr. 2016, 17:30

La fonction submit_form consiste à concaténer la valeur et le texte de chaque serveur et à mettre ça dans l'attribut value de l'input hidden qui devrait ressembler à ça :
value s1|text s1;value s2|text s2;...

Le traitement php permet de décomposer cette chaîne à chaque itération du foreach sont récupérés la valeur et le texte d'un serveur.
Développeur web depuis + de 20 ans

Petit nouveau ! | 8 Messages

01 févr. 2016, 18:17

Oui merci j'ai compris après plusieurs relectures.
Je m'efforce maintenant à mettre les valeurs dans un tableau dans la boucle foreach.
J'ai le choix entre 2 tableaux ou un tableau plus complexe genre montableau [][value][text]
J'y réfléchirais au travail demain.

Petit nouveau ! | 8 Messages

08 févr. 2016, 12:36

Bonjour,

Donc sur le principe ça fonctionne.

J'essaye de récupérer les valeurs et le texte dans 2 tableaux
$value=array();
$text=array();
...
...
$serveursjoint = explode(';', $_POST['serveursjoint_hidden']);
$h = 0;
foreach($serveursjoint as $servj)
{
  list($value[$h], $text[$h]) = explode('|', $servj);
  print("serveurs : $value[$h] : $text[$h]<BR>"); // débug pour vérifier la ligne
  $h++;
 } 
...
Le soucis, j'ai une erreur d'offset

Notice: Undefined offset: 1 in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\projects\admin\modif_appli.php on line 57

La ligne 57 est la suivante
list($value[$h], $text[$h]) = explode('|', $servj);

J'ai cherché un peu partout, pas compris ou est l'erreur.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

09 févr. 2016, 00:15

Bonjour,

"Erreur d'offset : 1", cela veut dire qu'à la ligne indiqué tu as un tableau dont tu demandes la valeur de la position "1" qui n'est pas défini.

Vu la ligne qui provoque l'erreur, cela veut dire que quand $h est à 1, soit $value[1] n'existe pas, soit $text[1] n'existe pas
Quand tout le reste a échoué, lisez le mode d'emploi...

Petit nouveau ! | 8 Messages

09 févr. 2016, 16:42

Pourtant je déclare bien un tableau sans définition de taille

$value=array();
$text=array();

Ce qui devrait me donner un pointeur (réflexe du C) qui incrémente le tableau au fur et a mesure

Ce qui me semble bizarre, c'est que $h = 0 au début

j'ai mis un print pour débuguer
print("serveurs n° $h : $value[$h] : $text[$h]<BR>");
dans la boucle afin de voir si les valeurs sont bien ajoutés

et voila ce qu'il m'affiche
Notice: Undefined offset: 1 in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\projects\admin\modif_appli.php on line 56
serveurs n° 0 : :

donc il tombe en erreur avant l'offset 1

Avatar du membre
Mammouth du PHP | 1609 Messages

09 févr. 2016, 17:24

Salut un print_r de $serveursjoint (et éventuellement $_POST['serveursjoint_hidden']) donne quoi ?

EDIT
Le undefined offset 1 vient potentiellement de l'appel à list qui ne pourrait pas assigner la deuxième variable car il n'y aurait pas de | dans $servj.

Un peu comme si tu faisais :
$datas = explode('|', $servj);
$text = $datas[1];// undefined offset 1 s'il n'y a pas de | dans $servj
Quand on sait que ça peut être le cas, on fait un @list pour ne pas remonter l'erreur mais dans ton cas il devrait toujours y avoir un |.

Je penche pour un problème côté javascript qui ne renseignerait pas serveursjoint_hidden comme il faut.

EDIT 2
J'ai testé et à priori c'est bien ça :
<?php

error_reporting(E_ALL);
ini_set("display_errors", 1);

$datas = array('value 1|text 1', 'value 2');

foreach($datas as $_datas) {
  list($value, $text) = explode('|', $_datas);// ligne 9
  echo "$value, $text<br/>";
}
Affichage :
value 1, text 1

Notice: Undefined offset: 1 in /.../list.php on line 9
value 2,
Développeur web depuis + de 20 ans

Petit nouveau ! | 8 Messages

10 févr. 2016, 09:59

Bonjour,

Après un peu de repos et de recul, merci pour ton idée du print_r, j'ai compris l'erreur.

J'avais mis l'alimentation de serveursjoint_hidden dans les fonctions d'ajout et suppression de serveur.
En gros, si je mettait à jour sans modifier, la valeur de serveursjoint_hidden est vide.

Je vais donc prendre ce cas en compte dans l'affectation des variables et faire la mise à jour que si les serveurs ont changé.

=> voila ce qui arrive quand on laisse son programme dormir pendant 1 semaine sans y toucher :roll:

Petit nouveau ! | 8 Messages

10 févr. 2016, 17:26

Le sujet peut être clos j'ai la solution.
Merci à vous