Liste déroulante de dictionnaire dans les champs d'un objet

Bonjour,

Je suis en train de découvrir le module builder mais me heurte au problème suivant.
Je souhaite ajouter dans un objet que j’ai créé un champ qui se présente comme une liste déroulante dont les choix proviennent d’un dictionnaire que j’ai ajouté. Je n’ai pas trouvé comment faire.
Ce que j’ai réussi à faire est d’avoir une liste déroulante provenant d’un objet existant, mais la classe cgenericdic n’est pas un objet car il référence différentes tables.
J’ai également réussi à faire en sorte a ce que mon champ soit validé par les valeur disponible dans le dictionnaire à l’aide de l’option validation d’un champ d’objet, mais cela ne m’affiche pas de liste déroulante.
La solution que j’ai pour le moment trouvée est de faire un extrafield dans mon objet qui est une liste déroulante provenant de la table du dictionnaire, mais ce qui ne me plait pas est que les extrafield sont en fin de formulaire alors que j’aimerais que ces champ soient positionnées ailleurs dans le formulaire.

Je n’ai pas trouvé de réponses en cherchant sur google, ni dans la documentation et le tutoriel du module builder.

Quelqu’un a-t-il une idée comment résoudre cela ?

Salut,

Si tu trouves une résolution, je suis preneur.
Je suis resté coincé ici perso :

Salut Kusco,

En faisant mes recherches j’avis lu ce fil :slight_smile:
Pour le moment je pense que je vais coder une liste déroulante simple dans la mesure où mes dictionnaires n’ont pas beaucoup de valeurs, je n’ai donc pas besoin de la dropdown avec l’option autofill / recherche.
Quand je l’aurais fait je posterais ce qui en est ressorti en espérant que cela puisse t’aider.
A moins que quelqu’un passe par là et nous donne une solution plus élégante et mieux intégrée et conforme aux structures de Dolibarr.

Movix

1 « J'aime »

Bonjour à tous, Salut Kusco,

Voici la solution que j’ai trouvée.
J’ai include core/class/html.formother.class.php, instancié un objet de cette classe et utilisé la methode select_dictionnary pour générer le code HTML d’un select pour mes dictionnaires.

Afin de récupérer cela pour l’affichage j’ai surchargé la méthode commonobject::ShowInputFields, y ai apellé la methode parent après quoi j’ai conditionnellement remplacé la valeur retournée pour les champ de mes dictionnaires que j’ai identifiés à l’aide de l’argument $key de la methode.

C’est un peu condensé comme réponse, mais je pense que cela décrit la solution que j’ai trouvée.

Movix

Merci pour ta réponse, c’est top !
Un peu trop condensé pour moi effectivement, mais ça me donne du grain à moudre.

Si jamais tu trouves un moment pendant l’été pour détailler un peu plus, je serai preneur, sinon je m’attelerai aux recherches.

Merci !

Salut Kusco,

Avant tout je précise que je ne suis pas un expert Dolibarr et qu’il est possible qu’il y a une manière plus élégante ou plus correcte de faire cela. En attendant ça produit le résultat voulu chez moi.

Dans le module Builder, dans ton objet tu trouve le fichier qui s’intitule MYOBJECT.class.php où MYOBJET est le nom que tu as donné à ton objet. C’est ce fichier qu’il faut modifier, soit avec l’éditeur intégré au modulebuilder ou directement si tu as un accès direct.

Tu devras ajouter deux nouvelles fonctions dans ce fichier. Ajoute les après a la fonction « doSheduledJob() {… } »

Avant cela en début de fichier, là où se trouvent les lignes qui commentcent par include_once (…); tu ajoute la ligne suivante qui permettra d’utiliser la classe formOther
require_once DOL_DOCUMENT_ROOT.‹ /core/class/html.formother.class.php ›;

Voici ces deux fonctions

// la fonction output va être apellée pour chaque champ de l'object si le champ doit juste être affiché.

/**
	 * Return HTML string to show a field into a page
	 * Code very similar with showOutputField of extra fields
	 */
public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
	{
		global $object, $db, $langs;
                // ici on apelle la focntion d'origine de dolibar pour tous les champs de ton objet
		$ret = parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
                Nous inspectons si le champ traité est celui que l'on souhaite modifier
		if ($key == "leNomDuChampAModifier") {
			// le code qui va produire ce qui sera affiché pour ton champ que tu stockes dans une variable $ret. dans mon a cas je fais appel à la focntion de tradcution, car j'ai mis en plac des traductions pour mon dictionnaire.
                        $ret = $langs->trans("c_mondictionaire".$value);
		}
                 // On retourne tout ça à l'apellant
		return $ret;
	}

		/**
	 * Return HTML string to put an input field into a page
	 * Code very similar with showInputField of extra fields
	 */
	public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
	{
		global $object, $db;
                // on apelle la focntion d'origine pour tous les champs
		$ret = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss = 0, $nonewbutton = 0);

		if ($key == "leNomDuChampAModifier") {
                       // on instancie un objet de la classe formOther
	        	$formother = new FormOther($db);
                        // on apelle la method select_dictionary qui nous retourne une select box
			$ret = $formother->select_dictionary($key, 'c_'.$key, "code", "label", $value);
		}
                // on retourne ça à l'apellant
		return $ret;
	}

pour plus de detail sur ces deux fonctions, tu retrouveras leur version d’origne dans le fichier core/class/commonobject.class.php.

Voilà, j’espère que cela te permettra d’avancer.

Movix

Bonjour @Movix68 @Kusco
Cela fait quelques jours que je cherche une solution au même problème que vous et je pense avoir trouver la solution en restant compliant dolibarr.
Dans la déclaration du champs dans l’objet, dans le type, il faudrait mettre :
sellist:nom_table:champ_a_afficher:id_clé_table::(active:=:1)
J’espère que cela vous sera utile à vous et à d’autre.

Noritaka971
Edit : modification par rapport à la mise a jour dans la V19 de la syntaxe du filtre
on ne mets plus (active=1) mais (active:=:1) pour éviter les injections SQL.

Salut @noritaka971
Désolé, je n’ai pas mis la tête dans le développement depuis un moment.
Merci pour ces recherches, je vais passer ma version en V20.1 pour avoir la bonne version.

Par contre, tu veux dire que plutôt que :
'fk_monchamps' => array('type'=>'integer:Contact:contact/class/contact.class.php:1:(statut:=:1)'

Il faudrait faire :
sellist:nom_table:champ_a_afficher:id_clé_table::(active:=:1)

Ou bien c’est à un autre endroit du code ?
Merci pour ton aide !

Bonjour @Kusco
Oui c’est exactement ça.

1 « J'aime »