phpcakephpcakephp-3.0

CakePHP 3: FormHelper to load <label> after <input>?


Is there any way to load <label> after <input>. By default CakePHP loads <label> before <input> like this:

Php Code:

<?php echo $this->Form->input('email', ['placeholder' => 'Email']); ?>

Generated Code:

<label for="email">Email</label>
<input name="email" placeholder="Enter your email" id="email" type="email">

But what do I when I would like to get it like this:

<input name="email" placeholder="Enter your email" id="email" type="email">
<label for="email">Email</label>

Is there a way to have this besides hacking something?


Solution

  • Templates

    You can use the templating functionality, the template responsible for this is the formGroup one, which by default is {{label}}{{input}}.

    echo $this->Form->input('email', [
        'placeholder' => 'Email',
        'templates' => [
            'formGroup' => '{{input}}{{label}}'
        ]
    ]);
    

    It's also possible to define form group tempaltes per input type, by following the naming convention that is the name of the type, followed by FormGroup. So for the email type that would be emailFormGroup.

    echo $this->Form->create(null, [
        'templates' => [
            'emailFormGroup' => '{{input}}{{label}}',
            'textFormGroup' => '{{input}}{{label}}'
            // ...
        ]
    ]);
    

    That way you can easily apply this option globally to specific types only.

    See also Cookbook > Form Helper > Customizing the Templates FormHelper Uses

    CSS

    And of course you could also use CSS, there's tables

    .input.email {
        display: table;
        width: 100%;
    }
    .input.email input {
        display: table-header-group;
    }
    .input.email label {
        display: table-footer-group;
    }
    

    flex-box ordering

    .input.email {
        display: flex;
        flex-flow: column;
    }
    .input.email input {
        order: 1;
    }
    .input.email label {
        order: 2;
    }
    

    etc...