IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Utiliser un formfilter sans module admin [1.x]


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 58
    Points : 42
    Points
    42
    Par défaut Utiliser un formfilter sans module admin
    Bonjour,
    Voilà mon problème : j'aimerais utiliser les (form)filtres dans un module "classique".
    J'ai cherché un peu partout sur le web, j'ai trouvé kedall, et j'ai tenté d'examiner le code fourni par un module admin, mais c'est à s'arracher les cheveux.

    Quelqu'un aurait un lien ou saurait comment mettre en place, de A à Z, un formfilter (perso) sur un module classique perso ?

    Merci.

    PS: j'utilise sf 1.4.x & doctrine 1.2

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    C'est pas simple...

    Et la meilleur solution, pour l'instant, c'est de singer le comportement du module admin qui est bien fait.

    J'ai quelques bouts de code (tirés du module admin) pour faciliter l'affichage de la liste, mais c'est un peu tiré par les cheveux.

    Je suis en train de travailler sur un objet list, qui va intégrer un objet filter, un objet pager et des fonctionnalités de tris, et gérer la liste tout seul, mais c'est au début. J'arrive juste a afficher les entête de colonnes pour l'instant. Tous va dépendre du temps disponible.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 58
    Points : 42
    Points
    42
    Par défaut
    D'accord, donc c'est pas fait pour être utilisé seul ? Jtrouve ca vraiment bête :/

    Si je trouve quelque chose de mon coté, j'en ferais part sur ce post.

  4. #4
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    L'objet filter est conçu pour proposer un formulaire de saisie qui permet de saisir et valider des paramètres de filtre, de plus il est capable de générer la partie query nécessaire au filtre affiché, ce qui est déjà beaucoup

    Par contre, tous le reste doit être fait à la main.

    Oui, il manque quelque chose.

    Je travaille actuellement sur un objet list qui utilisera un filter et un pager pour générer des listes, mais il est encore au state alpha et totalement inutilisable (mais j'affiche les entête de colonne, presque...).
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 58
    Points : 42
    Points
    42
    Par défaut
    C'est vraiment dommage qu'il n'y ai aucune documentation par rapport à l'utilisation des formfilter, parce-qu'au final, c'est relativement simple.

    J'ai fait comme toi, je me suis inspiré du module admin et voilà se que j'en ai sorti (en espérant que cela puisse aider) :

    CreatedAtFactureFormFilter.class.php
    (J'utilise un filtre "perso" calqué sur un déjà existant, je cherche d'ailleurs à pouvoir utiliser un filtre qui serait rattaché au behavior Timestampable de Doctrine de façon automatique, si quelqu'un a une idée de comment faire ...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CreatedAtFactureFormFilter extends FactureFormFilter
    {
      public function configure()
      {
        $this->useFields(array('created_at'));
     
        parent::configure();
      }
    }
    FactureTable.class.php
    (Il est important que la fonction renvoie la requête NON exécutée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class FactureTable extends Doctrine_Table
    {
      public function getFromClientId($client_id)
      {
        $q = $this->createQuery('a')
          ->where('a.client_profile_id = ?',$client_id)
          ->orderBy('a.created_at desc');
     
        return $q;
      }  
    }
    action.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    class factureActions extends sfActions
    {
      public function executeIndex(sfWebRequest $request)
      { 
        $this->filters = new CreatedAtFactureFormFilter($this->getFilters());
     
        $this->factures = $this->buildQuery(Doctrine::getTable('Facture')->getFromClientId($this->current_profile->getId()));
      }
     
      public function executeFilter(sfWebRequest $request)
      {
        // RESET
        if ($request->hasParameter('_reset'))
        {
          $this->setFilters(array()); //reset, filtre vide
          $this->forward('facture','index');
        }
     
        $this->filters = new CreatedAtFactureFormFilter($this->getFilters());
     
        $this->filters->bind($request->getParameter($this->filters->getName()));
        if ($this->filters->isValid())
        {
          $this->setFilters($this->filters->getValues());
          $this->forward('facture','index');
        }
     
        $this->setTemplate('index');
      }
     
      protected function getFilters()
      {
        return $this->getUser()->getAttribute('factures.filters', array());
      }
      protected function setFilters(array $filters)
      {
        return $this->getUser()->setAttribute('factures.filters', $filters);
      }
     
      protected function buildQuery($q)
      {
        if(!isset($this->filters))
          $this->filters = $this->getFilters();
     
        $this->filters->setQuery($q);
     
        $query = $this->filters->buildQuery($this->getFilters());
        return $query->execute();
      }
    }
    Comme dans le module admin, les filtres sont enregistrés en session.

    indexSuccess.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //[...]
    <?php include_partial('filters', array('filters' => $filters)) ?>
    //[...]
    _filters.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    <?php use_stylesheets_for_form($filters) ?>
    <?php use_javascripts_for_form($filters) ?>
     
     
      <?php if ($filters->hasGlobalErrors()): ?>
        <?php echo $filters->renderGlobalErrors() ?>
      <?php endif; ?>
     
    <form class="lien_ajax" action="<?php echo url_for('@facture_filter') ?>" method="post">
      <?php echo $filters ?>
     
      <?php echo $filters->renderHiddenFields() ?>
      <input type="submit" value="Filter" /> &nbsp; <a class="lien_ajax" href="<?php echo url_for('@facture_filter_reset?_reset=1') ?>">Reset</a>
    </form>
    On peut noter que les formFilters se comportent exactement de la même façon qu'un form normal, dans la vue.

  6. #6
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Oui, rien de bien compliqué.

    Juste un truc pour les form (et les formFilter). La méthode configure() est toujours vide sauf dans la dernière instance, il n'est donc pas nécessaire de faire un parent::configure().

    L'objet est configuré par le système dans la méthode setup() exécutée juste avant la méthode configure.

    Un partiel pour intégrer le formFilter en entête de colonne...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    <!-- Entête du tableau -->
    <tr>
        <?php foreach ($fields as $field) : ?>
        <th class="<?php echo 'col_' . $field['name'] ?>">
                <?php if ($field['sort']) :?>
                    <?php if($sort == $field['name']): ?>
            <a href="<?php echo url_for($route . '?sort=' . $field['name'] . '&sort_type=' . ($sort_type == 'asc' ? 'desc' : 'asc')) ?>" class="<?php echo $sort_type ?> active" title="<?php echo __('X_tries_X', '', $translate) . __($field['name'], '', $translate) ?>">
                            <?php echo __($field['name'], '', $translate) ?>
                            <?php if($sort_type == 'asc'): ?>
                <img src="/images/arr_up.gif" alt="Up" title="Up" />
                            <?php else: ?>
                <img src="/images/arr_down.gif" alt="Dw" title="Dw" />
                            <?php endif ; ?>
            </a>
                    <?php else: ?>
            <a href="<?php echo url_for($route . '?sort=' . $field['name'] . '&sort_type=asc') ?>" class="<?php echo $sort_type ?>" title="<?php echo __('X_tries_X', '', $translate) . __($field['name'], '', $translate) ?>">
                            <?php echo __($field['name'], '', $translate) ?>
            </a>
                    <?php endif ; ?>
                <?php else: ?>
                    <?php echo __($field['name'], '', $translate) ?>
                <?php endif ; ?>
        </th>
        <?php endforeach ; ?>
        <th>
            <?php echo __('Actions', '', $translate) ?>
        </th>
        <?php if ($filter->hasGlobalErrors() || $filter->hasErrors()): ?>
            <tr>
                <th colspan="<?php count($fields) ?>">
                    <?php echo $filter->renderGlobalErrors() ?>
                    <p>error</p>
                </th>
            </tr>
        <?php endif; ?>
    <tr class="filter">
    <form action="<?php echo url_for('@dossiers', array('action' => 'filter')) ?>" method="get">
        <?php foreach ($fields as $field) : ?>
        <?php if(!($field['name'] == 'actions')): ?>
            <th>
                <?php if(isset($filter[$field['name']])): ?>
                    <?php echo $filter[$field['name']]->render() ?>
                    <?php if($filter[$field['name']]->hasError()): ?>
                        <br />
                        <p>la gaffe !</p>
                    <?php endif; ?>
                <?php endif ; ?>
            </th>
        <?php endif ; ?>
        <?php endforeach ; ?>
        <th>
            <?php echo $filter->renderHiddenFields() ?>
            <input type="submit" value="<?php echo __('X_filter_X', array(), 'stdFilter') ?>" />
            <?php echo link_to(__('X_reset_X', '', 'stdFilter'), '@dossiers?filter_reset=yes', array('action' => 'index'), array('method' => 'get', 'class' =>  'filter-button', 'id' => 'filter_reset')) ?>
        </th>
    </form>
    </tr>
    Il va générer deux lignes, une avec les entêtes de colonne prêtes prêtes pour le tri et la deuxième avec les zones de filtres qui correspondent si elles sont définies dans l'objet filtre...

    L'appel du partial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <table>
        <thead>
            <?php include_partial('generic/ListTh', 
                    array(
                        'fields' => $FieldsTries,
                        'translate' => 'dossier',
                        'route' => '@dossiers',
                        'sort' => $sort['sort'],
                        'sort_type' => $sort['type'],
                        'filter' => $filter
                        ))?>
        </thead>
    • fiels : la liste des champs a générer
    • translate : le nom du ficher de traduction (i18n) pour ce formulaire
    • route : la route a utiliser
    • sort : le nom du field qui est actuellement utilisé pour le tris
    • sort_type : le type de tris (asc ou desc)
    • filter : l'objet filter


    L'array fields :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    array(
                    array('name' => 'nom', 'sort' => TRUE),
                    array('name' => 'type', 'sort' => FALSE)
            );
    on peut donc avoir des colonne qui n'accepterons pas le tris.

    J'aime bien cette présentation.

    Le partiel d'affichage des entêtes peut parfaitement être placé dans un module générique et utilisé pour plusieurs listes.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 58
    Points : 42
    Points
    42
    Par défaut
    Ah j'aime bien cette idée d'avoir tout dans la liste, je garde de coté

    Pour le parent::configure(), il n'est pas vide dans mon FactureFormFilter, d'où l'appel de celui-ci mais c'est vrai que si on étend un baseForm(Filter) on en a pas besoin.

    Je vais m'attaquer au pager maintenant ^^
    En tout cas, merci pour ton aide et tes bouts de codes

  8. #8
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Allez, c'est dimanche !

    un partial pour afficher le pager proprement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    <?php if ($pager->haveToPaginate()): ?>
      <div class="pagination">
        <a href="<?php echo url_for($route . '?page=1') ?>" title="<?php echo __('First page', '', 'pager') ?>" >
          <<
        </a>
     
        <a href="<?php echo url_for($route . '?page=' . $pager->getPreviousPage() )?> title="<?php echo __('Previous page', '', 'pager') ?>"">
           <
        </a>
     
        <?php foreach ($pager->getLinks() as $page): ?>
          <?php if ($page == $pager->getPage()): ?>
            <?php echo $page ?>
          <?php else: ?>
            <a href="<?php echo url_for($route . '?page=' . $page) ?>"><?php echo $page ?></a>
          <?php endif; ?>
        <?php endforeach; ?>
     
        <a href="<?php echo url_for($route . '?page=' . $pager->getNextPage() )?> title="<?php echo __('Next page', '', 'pager') ?>" >
          >
        </a>
     
        <a href="<?php echo url_for($route . '?page=' . $pager->getLastPage()) ?>" title="<?php echo __(' Last page', '', 'pager') ?>" >
          >>
        </a>
      </div>
    <?php endif; ?>
    un argument dans l'appel, le pager dans le tableau sous le nom de pager.

    Note qu'il est i18n près et que c'est là que l'on mettra le texte a afficher pour premier, suivant,...
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utilisation du package listings sans droits admin
    Par Ornith dans le forum Mise en forme
    Réponses: 0
    Dernier message: 05/08/2013, 10h18
  2. [BDE][Access] utilisation de BDDs sans passer par ODBC
    Par Guigui_ dans le forum Bases de données
    Réponses: 4
    Dernier message: 23/01/2005, 14h11
  3. application utilisant BD locale sans installation complexe
    Par snjonjo dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 09/01/2005, 02h44
  4. Réponses: 1
    Dernier message: 08/11/2004, 16h04
  5. Utilisation de MSGraph sans installation D'office
    Par [DreaMs] dans le forum ASP
    Réponses: 8
    Dernier message: 25/08/2003, 14h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo