Bonjour,

Je cherche à faire une liste déroulante avec cakePHP.

Cette liste déroulante devrait-être de la forme :

Catégorie 1:

->Sous-catégorie 1.1

->Sous-catégorie 1.2

Catégorie 2:

->sous catégorie 2.1

Catégorie 3:

->Sous-catégorie 3.1

-> sous catégorie 3.2

-> Sous catégorie 3.3

etc ...

J'ai regardé la doc et je devrais donc avoir quelque de ce style dans ma vue :

<?php
$options = array( //Liste catégories
   'Group 1' => array( //Liste sous-catégories
      'Value 1' => 'Label 1',
      'Value 2' => 'Label 2'
   ),
   'Group 2' => array(
      'Value 3' => 'Label 3'
   )
);

echo $this->Form->select('field', $options);
?>

Si j'écris que ceci ça marche, le problème c'est quand je passe à la pratique, c'est catastrophique, je n'ai aucune idée comment faire ça car je récupère mes informations depuis ma BDD.

Je suis perdu dans mes foreach ... Ça me donne un truc du genre :

<?php

$options = array();

foreach ($categories AS $category) //On affiche les catégories
            {
                    $option'$i'] = $category'Category']'name'];

                    foreach($subcategories AS $subcategory)
                        {

                            if($subcategory'Subcategory']'category_id'] == $category'Category']'id'])
                            {
                                $options'$i']'$a'] = $subcategory'Subcategory']'name'];

                            }
                        }

?>

Quelqu'un pourrait-il m'orienter dans la réalisation de ceci ?

9 réponses


Je penses que tu peux te simplifier la vie avec simplement un find('list') dans ton controller.
cf doc.: http://book.cakephp.org/2.0/fr/models/retrieving-your-data.html#find-list

il suffit simplement de faire comme dans la doc:

$groupesUsername = $this->Article->User->find('list', array(
        'fields' => array('User.username', 'User.first_name', 'User.group') // Récupère une liste par groupe avec username en index et last_name en value
    ));

Ensuite tu fais dans ton formulaire un simple :

echo $this->Form->input('nomduchamp', array(
      'options' => $groupesUsername ,
      'empty' => '(choisissez)'
// etc...
  ));

Bonjour,

Malheureusement je ne souhaite pas faire une simple liste déroulante. Je veux faire une liste déroulante de la forme que j'ai défini au dessus, mes sous-catégories sont donc répartie en fonction de la catégorie à laquelle elles appartiennent.

J'ai avancé, voici mon code :

<?php
$options = array();

foreach ($categories AS $category) //On affiche les catégories
{
    $category_name = $category'Category']'name'];
    foreach($subcategories AS $subcategory) // On affiche les sous catégories
    {   
        if($subcategory'Subcategory']'category_id'] == $category'Category']'id'])
        {
            $options$category_name]'$i'] = $subcategory'Subcategory']'name'];   
        }
    }
}?>

Je peux donc afficher toutes mes catégories et une seule des sous-catégories pour l'instant. J'ai donc un problème dans mon second foreach car je devrais avoir plusieurs sous-catégories qui devraient s'afficher.

Bonsoir,
est ce que t'a essayer d'appliquer le Containable à partir de ton controller, comment ça ? et bien simple en mettant tes relations entres catégories et sous catégories tu peut avoir l'affichage don't ta besoin en paramétrant

$this->Category->contain('Subcategory');

Cordialement.

Bonsoir,

Merci de l'info' je vais regarder cela de plus près.
Je souhaiterais vraiment faire fonctionner ma méthode. Elle ne semble pas si compliquée (pour preuve je suis proche du but) mais personne n'arrive à trouver mon erreur.

Re encore,
tu peux changer et utiliser encore plus simple le TreeBehavior que je trouve plus simple à mettre en place, à toi de voir

Cordialement

Re,

C'est marrant tu n'es pas le premier à m'en parler. Le treebehavior est très sympa(si je devais changer mon code ce serait plus pour ça que pour le containable), mais il complique ma BDD qui est très bien organisée. (d'ailleurs l'utilisation de treebehavior me demande de revoir toute l'organisation de mon site et le rend encore plus difficile à coder, je préfère avoir un truc peu clair juste ici que d'avoir une horreur sur tous mes autres controllers ...)

N'y a-t-il aucune solution proche de mon code de base ? :)

Désolé mais je pige pas trop alors, la solution que je t ai filé plus haut fait une liste déroulante au format voulu il listera des subcategory par categorie.

En fait il va creer la liste deroulante sous cette forme: Regarde l'exemple

Apres certes j ai pas fait attention tu as 2 tables differentes aparemment, il faudra donc en effet comme cité plus haut utiliser un containable.

Ou tout simplement le treeBehavior en effet, mais apremment tu souhaite éviter

Salut,

Oui la solution que tu m'a donné donne bien une liste déroulante avec un format similaire avec ce que je cherche.

Voici ce que ça me donne :

->subcategory.id
=>"Category1"
->category.name 1
->category.id

=>"Category2"
->category.name 2
->category.id

=>"Category3"
->category.name 3

Ce résultat final n'a aucune logique, les catezgory.name devraient-être là où sont écrit "Category1" et "Category2"...

Jusqu'à présent c'est ma solution qui est la plus proche du résultat souhaité ...

Hello, j'ai bien compris que tu ne voulais pas utiliser le TreeBehavior... sauf qu'il est fait pour gérer ce genre de cas... Donc forcément on se retrouve a réinventer la roue en plus mal...
Bref, essayes ca :

$categories = array(
    array(
        'id' => 1,
        'name' => 'Cat1'
    ),
    array(
        'id' => 2,
        'name' => 'Cat2'
    ),
    array(
        'id' => 3,
        'name' => 'Cat3'
    )
);
$subcategories = array(
    array(
        'category_id' => 1,
        'value' => 'value-Sub1_1',
        'label' => 'label-Sub1_1'
    ),
    array(
        'category_id' => 1,
        'value' => 'value-Sub1_2',
        'label' => 'label-Sub1_2'
    ),
    array(
        'category_id' => 2,
        'value' => 'value-Sub2_1',
        'label' => 'label-Sub2_1'
    ),
    array(
        'category_id' => 3,
        'value' => 'value-Sub3_1',
        'label' => 'label-Sub3_1'
    ),
);
$options = array();
foreach ($categories as $k => $category)
{
    $options$category'name']] = array();
    foreach ($subcategories as $l => $subcategory)
    {
        if($subcategory'category_id'] == $category'id'])
        {
            $options$category'name']]$subcategory'value']] = $subcategory'label'];
        }
    }
}

print_r($options);