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 :

[Form] Form error display avec Tabs


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 13
    Par défaut [Form] Form error display avec Tabs
    Bonjour,

    J'ai une classe Bareme possédant un relation OneToMany (avec reverse) vers une entité Depense.

    Le formulaire correspondant au Bareme contient les champs du Bareme + une collection d'entité de type Depense.

    Pour facilité l'ergonomie j'utilise des onglets, le premier liste les champs du Bareme et le second liste les entités Dépenses.

    Mon problème est situé au niveau de l'affichage, les messages d'erreurs sont bien affiché sous chaque champs en erreur (dans les deux onglets), mais j'aimerais pouvoir ajouter;
    - un message global au dessus de mon form
    - ajouter une classe "error" au tab dont le contenu contient des erreurs afin de changer sa couleur et cela afin d'apporter une aide visuel

    Par exemple, ci le libellé du Bareme n'est pas renseigné, j'ai bien avec mon form_errors(form.label) le message d'erreur affiché en dessous de mon champ, mais j'aimerais en plus affiché un message global au dessus des onglets + ajouter une class au premier onglet. A la limite pas de problème pour les champs de base, par contre ça se complique beaucoup pour les formulaires imbriqués.

    Je ne vois pas du tout comment réaliser ça.

    Avez-vous une idée sur la réalisation?

    Vous remerciant par avance.

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    Bonjour,

    Si tu utilises le form theming pour personaliser les templates d'erreurs et leur attribuer une classe CSS précise, pourquoi ne pas faire cela en jquery

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $('tabs div').each(function(){
     //en considérant que tout les messages d'erreurs ont la classe errors
     if($(this).find('.errors').length){
        var id=$(this).attr('id');
        $('.tabs ul.nav a[href=#'+id+']').addClass('tab-errors');//ajout de la classe sur l'onglet
     }
    });
    if($('.tabs ul.nav a.tab-errors').length){//s'il y a des onglets avec la classe errors on ajoute le message
        $('<div>erreurs de validation !!!</div>').before('.tabs');
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 13
    Par défaut
    Citation Envoyé par arnooo999 Voir le message
    Bonjour,

    Si tu utilises le form theming pour personaliser les templates d'erreurs et leur attribuer une classe CSS précise, pourquoi ne pas faire cela en jquery

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $('tabs div').each(function(){
     //en considérant que tout les messages d'erreurs ont la classe errors
     if($(this).find('.errors').length){
        var id=$(this).attr('id');
        $('.tabs ul.nav a[href=#'+id+']').addClass('tab-errors');//ajout de la classe sur l'onglet
     }
    });
    if($('.tabs ul.nav a.tab-errors').length){//s'il y a des onglets avec la classe errors on ajoute le message
        $('<div>erreurs de validation !!!</div>').before('.tabs');
    }
    Salut, c'est effectivement une solution à laquelle je n'avais pas pensé, mais je ne trouve pas cela très propre.

    J'aurais aimé trouvé une solution simple et global.

    En fait j'arrive bien à faire ce que je veux sur le premier onglet qui ne contient qu'un label
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {% if form.label.vars.errors|length > 0 %}
    label has error
    {% endif %}
    mais c'est contraignant si j'ai 10 champs à tester et cette méthode ne fonctionne pas avec une collection de form puisqu'il faudrait que j'accède à tous les childs afin de tester.

    L'idéal serait d'avoir une erreur au niveau du form (parent) et une autre au niveau de la collection (root+1).

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 13
    Par défaut
    Peut-être une autre solution, mais je la trouve dégueulasse aussi...

    En gros, j'ajoute une méthode dans mon controller qui va me renvoyer toutes les erreurs sous la forme d'un tableau (key|errors) que je passe à la vue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    return $this->render('MyProjectTestBundle:MyController:new.html.twig', array(
                'entity' => $entity,
                'form'   => $form->createView(),
                'formErrors' => $this->getErrorMessages($form)
            ));
    Ensuite dans mon template twig, je conserve l'affichage des erreurs sous chaque champs (sans le error_bubbling), et pour tester s'il y a une erreur dans un onglet je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <ul class="tabs">		
    				<li class="current{% if "label" in formErrors|keys and formErrors["label"]|length %} error{% endif %}"><a href="#bareme">Barème de remboursement</a></li>
    				<li {% if "depenses" in formErrors|keys and formErrors["depenses"]|length %}class="error"{% endif %}><a href="#depenses">Dépenses</a></li>
    			</ul>
    Disons que cela fonctionne mais que ce n'est pas top top.

    C'est quand même hallucinant de devoir passer autant de temps sur une connerie de ce style.

    Si vous avez des remarques quand à la technique, je suis preneur.

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    le plus sûr serait alors de créer une extension twig

    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
    //My/Bundle/Twig/Extension
    class TwigExtension{
     
    public function hasError(FormView $formView){
     if( count( $formView->get('errors') ) ){
        return true;
      }
      foreach($formview->getChildren() as $subFormView){
       if($this->hasError($subFormView)){
        return true;
       }
      }
     return false;
     }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <ul>
    <li {%if hasError(form.depenses)%}class="errors"{%endif%}>
    <a href="#tab1"><a>
    </li>
    </ul>
    pas trés optimisé non plus...


    une idée: dans ton controller peux-tu faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $isValidForm=$form->isValid();
    $depensesIsValid=$form->get('depenses')->isValid();
    $labelIsValid=$form->get('label')->isValid();
     
    puis renvoyer les variables dans ta vue?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 13
    Par défaut
    Merci pour cette suggestion Arnooo999,

    L'extension twig me plait bien, et après quelques tests, cela fonctionne au poil.

    Pour ceux que ça intéresse, il vous faut créer une extension twig et définir un nouveau filtre, dans mon cas je l'ai appeler hasErrorFilter, je vous met toute ma class (matchFilter est en test et permet de checker si une route match un pattern directement dans Twig)

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    <?php
    namespace MyProject\TestBundle\Twig\Extension;
     
    use Symfony\Component\Routing\Matcher\UrlMatcher;
    use Symfony\Component\Routing\RequestContext;
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
     
    class MyProjectTwigExtension extends \Twig_Extension
    {
        public function getFilters()
        {
            return array(
                'number' => new \Twig_Filter_Method($this, 'numberFilter'),
                'match' => new \Twig_Filter_Method($this, 'matchFilter'),
                'hasError' => new \Twig_Filter_Method($this, 'hasErrorFilter'),
            );
        }
     
        public function numberFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
        {
            $number = number_format($number, $decimals, $decPoint, $thousandsSep);
            $number = $number . ' $';
     
            return $number;
        }
     
    	public function matchFilter($route, $pattern = '')
        {
        	$pattern = "/$pattern/";	
        	if(preg_match($pattern, $route))
        	{
        		return true;
        	}
        	else 
        	{
        		return false;
        	}
     
    		return null;
        }
     
    	public function hasErrorFilter(\Symfony\Component\Form\FormView $formView)
    	{		
    		if($formView->has('errors'))
    		{
    			if(!$formView->get('valid'))
    			{
    				return true;
    			}
      		}
    		if($formView->hasChildren())
    		{
    			foreach($formView->getChildren() as $subFormView)
    			{
    				if($subFormView->has('errors'))
    				{
    					if(!$subFormView->get('valid'))
    					{
    						return true;
    					}
    				}
    			}
    		}
     		return false;
     	}
     
        public function getName()
        {
            return 'myproject_twig_extension';
        }
    }
    L'enregistrement se fait via un fichier services.yml dans le répertoire conf de mon bundle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    services:    
        myproject.twig.myproject_twig_extension:
            class: MyProject\TestBundle\Twig\Extension\MyProjectTwigExtension
            tags:
                - { name: twig.extension }
    Et ce fichier est chargé via l'injection de dépendance au chargement du bundle avec la méthode load:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public function load(array $configs, ContainerBuilder $container)
        {
            $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('services.yml');
        }

Discussions similaires

  1. Réponses: 11
    Dernier message: 07/04/2006, 05h34
  2. Pb saut de ligne avec <form></form>
    Par JSuper_Kitten dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 22/10/2005, 16h02
  3. Réponses: 3
    Dernier message: 30/06/2005, 12h50
  4. [xhtml][css] bouton du form ne marche pas avec IE6
    Par chinouk dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 14/06/2005, 14h00
  5. [FORMS] Utilisation de DLL avec ORA_FFI
    Par Nounoursonne dans le forum Forms
    Réponses: 2
    Dernier message: 07/12/2004, 09h19

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