Hello,

Je m'arrache les cheveux !

J'ai un formulaire avec une mise en forme précise. Cependant, dès que j'utilise le FormHelper, un malheureux <div style="display:none";> me casse et ma mise en page et les bijoux de famille !

Ce <div> est placé par la fonction create() pour entourer des champs "hidden".

Voici le code :

echo $this->Form->create('User', array('controller' => 'users', 'action' => 'add', 
'class' => false, 'role' => 'form', 'fieldset' => false, 'inputDefaults' => 
array('label' => false, 'div' => false)));

Et sa sortie :

<form action="/monsite/users/add" controller="users" role="form" id="UserAddForm" method="post" accept-charset="utf-8">
<div style="display:none;">
<input type="hidden" name="_method" value="POST"/>
<input type="hidden" name="data[_Token][key]" value="34ddd77335df445357tcf5d4fc47bbb14fbob152" id="Token1654124614"/>
</div>

J’ai bien sûr investigué pour découvrir que c’était bien cette balise responsable du « cassage » de la mise en forme de mon formulaire.

Ma question est donc : Comment enlever cette balise <div> ?

Je cherche depuis ce matin sans trouver aucune solutions et je suis à bout !

Avez-vous une idée ?

14 réponses


Pourquoi tu as des 'div'=>false, 'class'=>false ?

Pour le 'class'=>false, c'est un artefact de mes recherches. Il est inutile.

Pour le 'div'=>false, c'est pour que CakePHP ne génère pas lui-même les <div>. Car dans une partie de mon formulaire des <div> sans 'class' particulière doivent être ajouté pour la mise ne forme. Ca m'évite de devoir écrire X fois 'div' => array('class' => false) où 'div' => false).

Ah d'accord, pardon je ne connais pas encore toutes les ficelles de CakePhp ^^

Après je ne sais pas, j'ai regardé la doc ils l'utilise mais en dehors de dire que c'est pour désactiver le rendu de la div ils disent pas qu'il y a des effets secondaires ^^

Le soucis c'est que si ça désactive bien les <div> des "input" cela ne retire pas ceux des champs "hidden" rajouté par le composant security. Peut-être faut-il chercher plus du coté de ce composant mais... prrrrr

En quoi une balise html en display none peut casse une mise en page ? Tu peux m'expliquer car le but du display none est justement de ne pas s'afficher ....

Bonsoir,

Je pense (je ne suis pas sûr) que la partie "Form tampering prevention" de la documentation du composant Security devrait t'intéresser

Re,

En quoi une balise html en display none peut casse une mise en page ? Tu peux m'expliquer car le but du display none est justement de ne pas s'afficher...

Je me suis dis la même chose et pourtant c'est bien l'ajout d'une <div> juste après le <form> qui casse ma mise en forme. J'ai 2 éléments de formulaire aligné plus bas dans le formulaire et, dès que je rajoute une <div>, paf ils ne le sont plus (aligné). Et même avec un display:none ça ne change rien. Utilisant Bootstrap,j'ai même fait des tests avec un class="hide" ou class="hidden" rien !

La seule solution c'est de réussir à virer ce <div> auto-généré par le create().

Bonsoir,
Je pense (je ne suis pas sûr) que la partie "Form tampering prevention" de la documentation du composant Security devrait t'intéresser

Non cette partie ne concerne pas mon problème.

Personne n'a d'idées ? On peu pas demander à Cake de pas afficher cette <div> pour entouré les input hidden ?

Bonsoir,

Tu peux me faire une capture d'ecran ou est ce qu'il y a un accès web pour voir ton formulaire ?

Je pense reelment que tu fais fausse route car j'utilise bootstrap avec cakephp et je n'ai jamais eu ce probleme.

Cordialement

J'aurai tendance à aller plus loin dans le raisonnement : CakePHP génère une structure particulière mais logique et conforme aux standards W3C.

Si un div ou tout autre élément en display: none casse ta mise en page, c'est que le souci est ailleurs.

J'utilise également le bootstrap, et j'ai sur mes différents projets tous les types de formulaires que le bootstrap gère.

On a systématiquement au moins un input hidden qui est le contient la méthode d'envoie du formulaire.
Et je n'ai jamais rencontré ce problème.

Donc à mon sens, il faut retravailler la structure de tes champs.

Petit exemple avec mon formulaire de connexion :
En page statique :

<div class="col-md-12">
    <div class="page-header">
        <h1>Connexion</h1>
    </div>
    <div class="col-md-6">
    <?php echo $this->Form->create('User', array('id' => 'Users-login', 'class' => 'form-horizontal')); ?>
    <?php
    echo $this->Form->input('User.username', array(
        'div' => 'form-group',
        'label' => array(
                'div' => false,
                'class' => 'col-sm-4 control-label',
                'text' => 'Pseudo'
            ),
            'between' => '<div class="col-sm-8">',
            'after' => '</div>',
            'class' => 'validationPush form-control',
        'id' => 'username'
    ));
    echo $this->Form->input('User.password', array(
        'div' => 'form-group',
        'label' => array(
                'div' => false,
                'class' => 'col-sm-4 control-label',
                'text' => 'Mot de passe'
            ),
            'between' => '<div class="col-sm-8">',
            'after' => '</div>',
            'class' => 'validationPush form-control',
        'id' => 'password'
    ));
    echo $this->Form->end(array('label' => 'Connexion','div' => 'col-sm-offset-4 col-sm-8', 'class' => 'btn btn-info'));
    ?>
    </div>
</div>

En ajax (dans le menu du site) :

<ul class="dropdown-menu">
    <?php echo $this->Form->create('User', array('id' => 'Users-login')); ?>
    <?php
    echo $this->Form->input('User.username', array(
        'div' => 'form-group',
        'label' => array(
            'div' => false,
            'class' => '',
            'text' => 'Pseudo'
        ),
        'class' => 'form-control',
        'id' => 'username'
    ));
    echo $this->Form->input('User.password', array(
        'div' => 'form-group',
        'label' => array(
            'div' => false,
            'class' => '',
            'text' => 'Mot de passe'
        ),
        'class' => 'form-control',
        'id' => 'password'
    ));
    echo $this->Form->end(array('label' => 'Se connecter','div' => 'form-group submit', 'class' => 'btn btn-info ajax-submit'));
    ?>
    <?php echo $this->Form->end(); ?>
</ul>

Avec ça, j'ai aucun souci, et je ne surcharge pas le CSS du Bootstrap.

Merci pour vos réponses et votre aide.

J'ajoute une précision. J'utilise Bootstrap par le biais du Startup Framework de DesignModo qui ce base sur Flat ui. Vous pouvez voir ici le type de formulaire que j'utilise.

Voici le code du formulaire brut:

<div class="signup-form">
                                <form>
                                    <div class="form-group">
                                        <input class="form-control" type="text" placeholder="Your E-mail">
                                    </div>
                                    <div class="form-group">
                                        <div>
                                            <input type="password" class="form-control" placeholder="Password">
                                        </div>
                                        <div>
                                            <input type="password" class="form-control" placeholder="Confirmation">
                                        </div>
                                    </div>
                                    <div class="form-group">
                                        <button type="submit" class="btn btn-block btn-info">Sign Up</button>
                                    </div>
                                </form>
</div>

On voit que "Password" et "Confirmation" sont aligné.

A ce code, CakePhp y ajoute, entre-autre, ceci entre <form> et le premier <div> :

<div style="display:none;"><input type="hidden" name="_method" value="POST"/><input type="hidden" name="data[_Token][key]" value="6b2e812cb751b1828ab5262c46942acc7b61a398" id="Token1979949152"/></div>

Et là paf, les deux champs (Password et Confirmation), passe l'un en dessous de l'autre en étant "collé".

Il y a forcement une raison que j'ignore et ce que je trouve le plus simple, c'est de ne pas mettre les champs hidden dans une <div>. :/

Arf ! Non ! Même en ne mettant uniquement que les "input hidden" sans les entourer d'une <div> le formulaire est cassé. :/

Il nous faudrait tout le code qui génère ton formulaire, et le rendu obtenu, mais ce que je vois à première vu, ce sont les points suivants :

  • Tout le formulaire doit être encapsulé dans un div.signup-form

  • Chaque input ou groupe d'input que tu veux sur une ligne doivent être encapsulés dans un div.form-group

  • Il semble qu'il faille effectivement avoir les labels des input à false, et que les input aient une class.form-control

  • Si tu as un input sur une seule ligne, il ne faut pas le mettre dans un div

  • Si tu as plusieurs input sur ta ligne, il faut que chaque input soit encapsulé dans un div

En appliquant ces modifications là, qui n'ont rien à voir avec l'ajout d'un div en display none par Cake, ça devrait fonctionner parfaitement.

Si tu te poses des questions sur comment générer telle ou telle chose autour d'un input ou sur l'input lui-même, la doc de Cake sur le form Helper y répondra.

Re,

@Pakito

Le soucis, c'est que chaque point que tu cites ont une réponse positive. :/

Voici le rendu du code du formulaire entier :

<div class="signup-form">
    <form action="/monsite/users/add" controller="users" role="form" id="UserAddForm" method="post" accept-charset="utf-8">
        <div style="display:none;">
            <input type="hidden" name="_method" value="POST"/>
            <input type="hidden" name="data[_Token][key]" value="d5da7558bcfb0994d8d17547b45340b618f0406b" id="Token1381413076"/>
        </div>                    
        <div class="form-group">
            <input name="data[User][email]" class="form-control" placeholder="Votre E-mail" maxlength="100" type="email" id="UserEmail" required="required"/>                    
        </div>
        <div class="form-group">
            <div>
                <input name="data[User][username]" class="form-control" placeholder="Nom d'utilisateur" maxlength="255" type="text" id="UserUsername" required="required"/>                    
            </div>
            <div>
                <input name="data[User][password]" class="form-control" placeholder="Mot De Passe" type="password" id="UserPassword" required="required"/>                    
            </div>
        </div>
        <div class="form-group">
            <input class="btn btn-block btn-info" value="Submit" type="submit"/>
        </div>
        <div style="display:none;">
            <input type="hidden" name="data[_Token][fields]" value="86ad2498f5e14c2151c35100b6aacc9da146b559%3A" id="TokenFields1578320935"/>
            <input type="hidden" name="data[_Token][unlocked]" value="" id="TokenUnlocked1459199830"/>
        </div>
    </form>
</div>

Les voies impénétrable des CSS...

Effectivement, j'ai ajouté le code suivant dans le DOM HTML directement sur http://designmodo.github.io/startup-demo/framework/samples/sample-03/index.html :

<div style="display:none;">
            <input type="hidden" name="_method" value="POST"/>
            <input type="hidden" name="data[_Token][key]" value="d5da7558bcfb0994d8d17547b45340b618f0406b" id="Token1381413076"/>
        </div>

Et en effet, l'ajout d'un div en display none casse tout.

Je t'avoue que je ne comprends pas vraiment ni le pourquoi ni le comment.

Cela dit, le problème de fond vient du CSS utilisé par Startup Framework : dans les faits, un élément en display: none; n'a pas à perturber l'affichage des autres éléments du DOM, puisque c'est justement le but du display; none; : l'élément est dans le DOM, mais n'est pas pris en compte à l'affichage.

Je vais continuer à réfléchir au souci, mais dans l'absolu je te conseillerai de t'orienter vers un bootstrap plus "propre".

Re,

Merci beaucoup pour ton aide. Je me suis résigné, dans un premier temps, à repartir sur un formulaire plus classique. Mais j’aimerais comprendre ce qu'il ne va pas.