[RESOLU] MultiSelectBox avec Zend 1

Eléphant du PHP | 398 Messages

30 avr. 2014, 12:49

Bonjour,

Dans le cadre du développement de mon CV sous forme de site internet, je suis confronté à un problème de selectBox à choix multiple. Pour restituer le contexte, j'ai deux tables : "competences" et "missions" lié par une relation de type n..n. La table "competences" est liée par FK à la table "competences_principales" et la table "missions" est liée à ma table "emplois" par FK, comme sur le MPD en PJ.
mpd.png
Pour chaque mission, j'y lie des compétences (de type environnement technique). Je développe une section administration (module admin) ou lorsque je souhaite modifier un emploi,j'ai un formulaire classique de modification d'emploi dans un onglet et un deuxième onglet ou je peux modifier les données d'une mission. C'est sur ce deuxième formulaire, où j'ai intégré une liste déroulante de type "multiple" listant toutes les compétences regroupées par compétences principales. Mon problème est que je n'arrive pas à faire surligner (en mode "selected"), les compétences enregistrées en BD pour la mission associée.

Ma selectBox dans ma vue :
class Admin_Form_Missions extends Zend_Form
{
	public function init()
	{
		
		$this->setMethod('post');
		$this->setOptions(array('class' => 'form-horizontal'));
		
		// id mission
		$idMission = new Zend_Form_Element_Hidden("id_mission");
		$idMission//->setValue($this->idExperience)
					->removeDecorator("label");
		$this->addElement($idMission);
		
		// id emploi
		$idExperience = new Zend_Form_Element_Hidden("id_emploi");
		$idExperience//->setValue($this->idExperience)
					->removeDecorator("label");
		$this->addElement($idExperience);
		// liste de champs ...

		// Competences de la mission
		$listeCompetences = new Zend_Form_Element_Multiselect('env_tech');
		$listeCompetences->setOptions(array('class' => 'form-control', 'style' => 'height : 200px;'))
						->setLabel("Environnement technique");
		$this->addElement($listeCompetences);
		
		// bouton submit
		$submit = new Zend_Form_Element_Submit('Envoyer');
		$submit->setAttrib('id', 'submitFrmInscription');
		$submit->setOptions(array('class' => 'btn btn-primary'));
		$this->addElement($submit);
	}
}
Dans mon controller, j'ai une méthode qui récupère une liste complète de competences, regroupées par compétences principales (pour remplir la selectMultipleBox) :
	/**
	 * Generation de la liste de competences classées par competences principales
	 */
	 private function _getListeCompetencesOrderByCp ()
	 {
	 	// Recuperation du contenu de ma table "competences"
	 	$oModelCompetences = new Application_Model_DbTable_Competences();
	 	$tabListe = $oModelCompetences->getAllCompetences();
	 	$tabListeCompetencesByCp = array();
	 	// mise en forme du tableau de données
	 	foreach ($tabListe as $key=>$tabCompetence) {
	 		$tab = array($tabCompetence['id_competence'] => $tabCompetence['lib_competence']);
	 		$tabListeCompetencesByCp[$tabCompetence['lib_competence_principale']][$tabCompetence['id_competence']] = $tabCompetence['lib_competence'];
	 	}
	 	return $tabListeCompetencesByCp;
	 }
La méthode getAllCompetences() du model Application_Model_DbTable_Competences est un simple SELECT :
	/**
	 * Retourne le contenu de la table competence
	 */
	public function getAllCompetences ()
	{
		$select = $this->getDefaultAdapter()->select()
					->from(array('c' => $this->_name), array($this->_primary , 'lib_competence'))
					->joinLeft(array('cp' => 'competences_principales'), 'cp.id_competence_principale = c.id_competence_principale', array('lib_competence_principale'))
					;	
		return $select->query()->fetchAll();
	}
ça me retourne un tableau de type 'competence_principale 1' => array(id => valeur, id => valeur), 'competence_principale 2' => array(id => valeur) etc...

Pour récupérer les compétences liées à ma mission :
Dans ma méthode de récupération de données, j'ai une méthode _getEmploiById() dans le model Application_Model_DbTable_Emplois qui en fonction de la valeur de id_emploi, qui appele une autre méthode propre aux mission :
	/**
	 * Retourne un emploi filtré par son ID
	 */
	public function getEmploiById ()
	{
		$tabInfos['emploi'] = $this->find($this->_id)->toArray();
		$tabInfos['missions'] = $this->_getMissionsByIdEmploi($this->_id);
		return $tabInfos;
	}
	
	/**
	 * Retourne un tableau de missions selon la valeur de id_emploi
	 */
	private function _getMissionsByIdEmploi ()
	{
		$oMissions = new Application_Model_DbTable_Missions();
		return $oMissions->getMissionsByIdEmploi($this->getId());
	}
Et la méthode getMissionsByIdEmploi() qui retourne les informations d'une/des mission(s) :
	public function getMissionsByIdEmploi ($idEmploi)
	{
		$select = $this->select()->from($this->_name, array('id_mission'));
		$select->where('id_emploi = ?', $idEmploi);
		$rowSet = $this->fetchAll($select);
		
		$tabMissionArray = array();
		
		foreach ($rowSet->toArray() as $key=>$row) {
			$this->setId($row['id_mission']);
			array_push($tabMissionArray, $this->_getInfoMission());
		}

		return $tabMissionArray;
	}

	/**
	 * Retourne les données d'une mission
	 */
	private function _getInfoMission ()
	{
		$tabDataMission = $this->find($this->getId());
		
		$rowsetCurrent = $tabDataMission->current();
		
		$tabDataMission = $tabDataMission->toArray();
		$tabDataMission[0]['env_tech'] = $this->_getEnvTechnique($rowsetCurrent);
		
		return $tabDataMission[0];
	}

	/**
	 * Retourne les competences techniques pour une mission
	 */
	private function _getEnvTechnique ($current)
	{
		$competencesByMission = $current->findManyToManyRowset('Application_Model_DbTable_Competences', 'Application_Model_DbTable_MissionsHasCompetences');
		$listeCompetences = array();
		foreach ($competencesByMission as $key=>$competence) {
			$listeCompetences[$competence['id_competence']] = $competence['lib_competence'];
		}
		//$listeCompetences = implode(', ', array_values($listeCompetences));
		
		return $listeCompetences;
	}
C'est cette dernière méthode qui retourne les compétences de ma liste déroulante que je souhaite afficher sous la forme d'un simple array (id => valeur).
Je pensais que le simple fait de faire populate() assignerai directement mes competences liées à ma BD à ma liste déroulante :
// Assignation des données d'une mission au champ du formulaire "mission"
$formMissionsEdit->populate($tabInfoEmploi['missions'][0]);
Mais ma selectBoxMultiple ne "selected" pas les compétences de la mission. J'ai tenté comme ça aussi :
$formMissionsEdit->getElement('env_tech')->setValue($tabInfoEmploi['missions'][0]['env_tech']);
Mais rien...

Donc voila, malgré des recherches, je ne trouve pas de solutiions. Désolé pour le poste très verbeux :D et pour les multiples méthodes mais j'aime bien décomposer mon code et surtout avoir une séparation stricte de mes couches ^^.
Merci beaucoup d'avances :)

PS : et quand il y aura la soltion, je devrai trouver une façon de le faire via jquery avec un tableau JSON...
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Eléphant du PHP | 398 Messages

05 mai 2014, 14:36

J'ai mis en ligne sur GitHub l'application, si quelque trouve la solution...on sait jamais...
https://github.com/HamHamFonFon/cv_fonf ... pplication
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Eléphant du PHP | 398 Messages

05 mai 2014, 16:51

Apres plusieurs jours de recherche, d'arrachage de cheveux et surtout même pas deux heures après avoir créé ce topic, j'ai trouvé la solution...j'ai inversé deux lignes et placé le populate() avant le setValue() soit :
$formMissionsEdit->populate($tabInfoEmploi['missions'][0]);
$formMissionsEdit->getElement('env_tech')->setValue(array_keys($tabInfoEmploi['missions'][0]['env_tech']));
Ce métier me tuera :cry:
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Mammouth du PHP | 571 Messages

05 mai 2014, 17:03

bonjour,

de mémoire pour pré-remplir la liste déroule du formulaire , populate doit recevoir un tableau en paramètre dont la clé doit correspondre au champ du formulaire:
$element = new Zend_Form_Element_MultiCheckbox('missions');
$tab=array('missions'=>array('id'=>5);

$form->populate($tab);
pour pré-remplir les champs de type text, un simple tableau suffit:
$champ=new Zend_Form_Element_Text('mon_champ');
$array = array('mon_champ'=>'toto');
$form->populate($array);

Eléphant du PHP | 398 Messages

05 mai 2014, 17:06

Les champs textes étaient très bien remplis, là n'était pas le soucis :). Mais en plaçant le setValue() après le populate(), le soucis a été résolu.
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Petit nouveau ! | 9 Messages

14 janv. 2015, 02:13

Merci j'avais exactement le même problème :)

Eléphant du PHP | 398 Messages

14 janv. 2015, 10:01

J'espère que tu n'as pas galéré autant que j'ai eu ^^. Ravi que ça pu aider quelqu'un :)
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe