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 :

Formulaires : pb d'initialisation / validation (pour un débutant...)


Sujet :

Symfony PHP

  1. #1
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut Formulaires : pb d'initialisation / validation (pour un débutant...)
    Je suis en train de paramétrer une page d'administration. L'un des champs du formulaire est une case à cocher, la valeur correspondante en base de données est un booléen.
    Si je déclare juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->widgetSchema['actif'] = new sfWidgetFormInputCheckbox();
    dans la méthode configure() et que je sauvegarde une saisie avec la case cochée, le formulaire me renvoie une erreur : 'on' n'est pas un entier.

    Après quelques recherches sur la toile, je suis tombé sur un validateur "sur mesure" pour les cases à cocher.

    J'ai donc ajouté dans la méthode configure() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	require_once dirname(__FILE__).'/../../../lib/sfCheckboxValidator.class.php';
    	$this->validatorSchema['actif'] = new sfValidatorAnd(
    		$this->validatorSchema['actif'],
    		new sfCheckboxValidator()
    	);
    Du coup, j'ai une erreur PHP : class sfValidator not found.
    Et je ne vois pas très clairement où je dois placer ce fichier pour que l'interpréteur ne plante pas...

  2. #2
    Membre chevronné Avatar de sacricri
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    324
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 324
    Par défaut
    Bonsoir,

    tu t'embêtes un peu, regardes plus de ce côté là : sfValidatorBoolean()

    il s'agit du validator de base des checkbox.

    Sinon, un validator se place dans le répertoire lib/validator/

  3. #3
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Dans la méthode configure de ton formulaire, rajoute un validateur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            $this->setValidator('actif', new sfValidatorBoolean())
    symfony dispose d'un autoload, inutile de te prendre la tête avec un require (en fait, hors le script de configuration, tu ne devrais plus jamais voir require dans ton code.

    Ensuite il faut dans le contrôleur binder ton formulaire avec les données. En cas de question sur ça, demande le

  4. #4
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    OK, merci pour vos réponses, j'ai pu avancer avec ça
    Il reste encore quelques points peu clairs dans mon esprit. En résumé :

    1 - utilisation du sfCheckboxValidator : cela venait du fait que j'ai vu sur la Toile plusieurs articles signalant un problème avec le sfValidatorBoolean() pour les cases à cocher. Par exemple : sfWidgetFormInputCheckbox-sfValidatorBoolean-incompatible. Je suis revenu au sfValidatorBoolean mais dans l'idée où j'aurais à utiliser un validateur "fait main", même en déplaçant le fichier à inclure dans lib/validator, j'ai toujours le message d'erreur "class sfValidator not found". Il doit y avoir un éléphant qui m'échappe...

    2 - mon erreur initiale : en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->validatorSchema['actif'] = new sfValidatorAnd(...)
    je conservais le validateur par défaut en lui ajoutant un autre validateur. Or ce validateur par défaut n'aime pas la valeur envoyée par la case à cocher quand elle est cochée. Par contre, si je fais juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->validatorSchema['actif'] = new sfValidatorBoolean(array('required'   => false));
    seul le sfValidatorBoolean est utilisé et du coup plus de message du type "'on' is not an integer". Ouf.

    3 - et le problème qui me reste : j'ai ajouté un bind() selon les conseils de Michel. Comme je suis dans une application générée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    doctrine:generate-admin backend PhraseJour ....
    j'ai fait cela dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class phrasejourActions extends autoPhrasejourActions {
        protected function processForm(sfWebRequest $request, sfForm $form) {
    	$form->bind(
    		$request->getParameter($form->getName()),
    		$request->getFiles($form->getName())
    	);
    	if ($form->isValid()) {
    	    $job = $form->save();
    	}
        }
    }
    Cependant, si j'édite une PhraseJour, la case à cocher du formulaire est toujours cochée lorsque la page d'édition s'affiche, même si la PhraseJour est inactive.
    NB : La valeur en bdd est bonne. Si je fais save, la mise à jour bdd est correcte et le ré-affichage du formulaire est lui aussi correct. Les autres champs par contre sont correctement initialisés. Il doit donc me manquer un truc pour initialiser la case à cocher, mais quoi ?

  5. #5
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Moi aussi j'avais raté quelque chose !

    Je n'ai pas vu que tu étais sur un module d'administration, je pensais à un module général.

    Pour ton fichier validator, il faut le mettre soit dans lib/validator, celui de ton application, PAS celui de symfony. Tu peux aussi le mettre dans un module que tu créerais toi même pour le réutiliser ensuite lib/plugins/<MonPlugin>/lib/validator ou éventuellement dans un plugin installé dans l'arborescence de symfony. Un coup de CC pour réinitialiser le cache et il doit apparaître dans l'autoload.

    Dans les modules d'administration, symfony effectue automatiquement le bind et tu n'as pas à t'en occuper.

    Par contre, j'ai du mal à comprendre ce que tu veux faire, au départ.

    Ce que j'ai cru comprendre
    Tu as un formulaire, auto généré dans lib/form/doctrine/base sur une de tes tables.
    Tu veux y rajouter une case à cocher qui n'apparait pas dans la base
    Mais où diable enregistres-tu sa valeur ?
    Qu'est-ce que tu entend par initialiser la case à cocher ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Il me semble que le plus simple pour les cases à cocher, c'est de les déclarer en tant que booleans dans le schema.yml, avec une valeur par défaut à 1 si tu veux qu'elle soit cochée par défaut.

    (Car si tu veux placer toi même une checkbox dans ton formulaire, elle aura l'attribut value="on", et une checkbox n'a pas à avoir de value puisque c'est inutile.)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    NomObjet
      columns:
        actif:
          type: boolean
          default: 1
    Ce qui se traduira par un champ tinyint(1) en base de données et par une checkbox directement à checked="checked" dans le formulaire mais sans l'attibut "value", ce qui t'évitera de devoir utiliser la classe sfCheckboxValidator.

  7. #7
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    OK, pour la validation je pense que ça marche maintenant grâce à vos éclaircissements. Le dernier point qui coince est donc le problème de la case à cocher :

    Ma table en base de données correspond au schema :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    PhraseJour:
      actAs: { Timestampable: ~ }
      columns:
        libelle: { type: string(), notnull: true }
        lien: { type: string(128) }
        actif: { type: boolean, notnull: true, default: 1 }
    J'ai appelé là-dessus les CLI doctrine:build-model, doctrine:build-forms, doctrine:build-filters, cache:clear.

    Le formulaire a été configuré dans lib/form/doctrine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class PhraseJourForm extends BasePhraseJourForm {
        public function configure() {
    	unset($this['created_at'], $this['updated_at']);
    	$this->widgetSchema['actif'] = new sfWidgetFormInputCheckbox();
    	$this->validatorSchema['actif'] = new sfValidatorBoolean(array(
    	    'required'   => false
    	));
        }
    Problème : si je clique sur Edit, j'arrive sur le formulaire de modification et la case à cocher est cochée quel que soit le statut (actif = 0 ou actif = 1) de l'objet. Si le statut est à 0, je voudrais que la case ne soit pas cochée par défaut, bien sûr. Et je ne trouve pas où règler ce dernier détail.

  8. #8
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Je ne comprend pas.

    J'ai créé une petite table avec un string et un bolean.
    J'ai généré un admin
    J'ai utilisé l'admin sans aucun problème et la case reste coché suivant ce que je veux.

    Donc, y a un truc que je ne vois pas dans ton exemple, mais où ?

    La partie request me semble correctement alimentée (pareil à mon local).

    Question, pourquoi modifies-tu le widget et le validator dans ton code et n'utilises-tu pas le code généré ?

    Essaye de faire une petite application de test, totalement indépendante, les cases à cocher marchent parfaitement, alors...

    Essaye de mettre "default: true" plutôt que "default: 1" dans le schéma.

  9. #9
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Tu as raison, si je désactive les lignes modifiant le widget et le validator dans la méthode configure() de ma classe, tout marche.
    C'était bien un éléphant.

    Voilà qui m'arrange et va me permettre d'avancer ! Reste que je comprends mal pourquoi ces lignes posent problème. En effet, dans la classe de base, on a bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        $this->setWidgets(array(
          ...
          'actif'      => new sfWidgetFormInputCheckbox(),
     
        ));
     
        $this->setValidators(array(
          'id'         => new sfValidatorDoctrineChoice(array('model' => $this->getModelName(), 'column' => 'id', 'required' => false)),
          'libelle'    => new sfValidatorString(),
          'lien'       => new sfValidatorString(array('max_length' => 128)),
          'actif'      => new sfValidatorBoolean(array('required' => false)),
          'created_at' => new sfValidatorDateTime(),
          'updated_at' => new sfValidatorDateTime(),
        ));

  10. #10
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Tu as raison, si je désactive les lignes modifiant le widget et le validator dans la méthode configure() de ma classe, tout marche.
    C'était bien un éléphant.

    Voilà qui m'arrange et va me permettre d'avancer ! Reste que je comprends mal pourquoi ces lignes posent problème. En effet, dans la classe de base, on a bien dans la méthode setup() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        $this->setWidgets(array(
          ...
          'actif'      => new sfWidgetFormInputCheckbox(),
          ...
        ));
     
        $this->setValidators(array(
          ...
          'actif'      => new sfValidatorBoolean(array('required' => false)),
          ...
        ));
    D'après ce que j'en comprends, les lignes que j'avais ajoutée (inutilement) dans ma méthode configure() devraient juste... ne rien changer.

    En tout cas, merci d'avoir pris le temps pour éclairer ma lanterne, fort embrouillée je l'avoue !

  11. #11
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Et bien, ils ne devraient rien changer.

    J'ai déjà créé des formulaires standalone avec des cases à cocher sans problèmes. Mais avec un autre validator qui s'assure que la case est cochée (pour l'acceptation d'une charte). Et ça marche.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Dans ton code, essaye en remplaçant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $this->widgetSchema['actif'] = new sfWidgetFormInputCheckbox();
    Par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $this->widgetSchema['actif'] = new sfWidgetFormInputCheckbox(array('value_attribute_value' => true));

Discussions similaires

  1. Bouton valider pour formulaire de recherche.
    Par supstoov dans le forum IHM
    Réponses: 5
    Dernier message: 04/02/2013, 13h33
  2. Réponses: 2
    Dernier message: 27/08/2009, 12h01
  3. Réponses: 11
    Dernier message: 08/07/2007, 18h32
  4. SQL et GUID : Valeur de caractère non valide pour la ....
    Par jackfirst72 dans le forum Bases de données
    Réponses: 5
    Dernier message: 06/03/2007, 11h46
  5. [JSP]formulaire de JSP ne valide pas
    Par rivierem dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 21/10/2004, 15h26

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