wake-up-neo.com

Benutzerdefiniertes Rendern eines "wiederholten" Feldes aus Symfony 2 in Twig

Ich habe gerade mit Twig angefangen und versuche ein Registrierungsformular zu erstellen. Um ein Passwort hinzuzufügen/ein Passwortfeld erneut einzugeben, verwende ich den "wiederholten" Dateityp:

->add('password', 'repeated', array(
    'type' => 'password',
    'invalid_message' => 'Passwords have to be equal.',
    'first_name'      => 'Password',
    'second_name'     => 'Re-enter password',
));

was wie beabsichtigt funktioniert. Das Problem, das ich habe, ist jedoch, dass ich meinem Formular einige benutzerdefinierte Klassen usw. hinzufügen möchte. Meine Vorlage sieht also so aus:

<form action="{{ path('register') }}" method="post" {{ form_enctype(form) }}>
    {{ form_errors(form) }}
    {{ form_errors(form.username) }}
    <div class="form-field">
        {{ form_label(form.username, null, { 'attr': {'class': 'form-label'} }) }}
        {{ form_widget(form.username, { 'attr': {'class': 'form-input'} }) }}
    </div>
    {{ form_errors(form.email) }}
    <div class="form-field">
        {{ form_label(form.email, null, { 'attr': {'class': 'form-label'} }) }}
        {{ form_widget(form.email, { 'attr': {'class': 'form-input'} }) }}
    </div>
    {{ form_errors(form.password) }}
    <div class="form-field">
        {{ form_label(form.password, null, { 'attr': {'class': 'form-label'} }) }}
        {{ form_widget(form.password, { 'attr': {'class': 'form-input'} }) }}
    </div>

    {{ form_rest(form) }}

    <input type="submit" class="contact-submit" />
</form>

dies funktioniert gut für alles außer dem Passwort-Teil. Ich möchte dort beide Felder getrennt rendern, jetzt werden sie nur noch in demselben div gerendert.

Wie kann ich das beheben? Gibt es eine Möglichkeit, die einzelnen Felder in Twig auszuwählen? Oder mache ich nur etwas falsch, weil ich dieses Problem überhaupt erst sehe.

27
teuneboon

Nach einer zufälligen Vermutung löste ich mein eigenes Problem. Ich werde es hier posten, damit auch andere, die durch Suchen zu dieser Frage kommen, die Antwort kennen:

{% for passwordField in form.password %}
    <div class="form-field">
        {{ form_label(passwordField, null, { 'attr': {'class': 'form-label'} }) }}
        {{ form_widget(passwordField, { 'attr': {'class': 'form-input'} }) }}
    </div>
{% endfor %}
55
teuneboon

Wenn Sie beide Kennwörterfelder von einer wiederholten Methode in Ihrer Zweigvorlage trennen möchten, müssen Sie nur die entsprechenden Namen zurückrufen, z.

{{ form_label(form.password.pass, "Password :") }}
{{ form_widget(form.password.pass) }}

{{ form_label(form.password.confirm, "Confirm :") }}
{{ form_widget(form.password.confirm) }}

Und natürlich in Ihrer Funktion:

/..
->add('password', 'repeated', array(
'first_name' => 'pass',
'second_name' => 'confirm',
'type' => 'password'
))

Grüße.

25
Log

Das funktioniert für mich:

....
{{ form_errors(form.password.first) }}
<div class="form-field">
    {{ form_label(form.password.first, null, { 'attr': {'class': 'form-label'} }) }}
    {{ form_widget(form.password.first, { 'attr': {'class': 'form-input'} }) }}
</div>

{{ form_errors(form.password.second) }}
<div class="form-field">
    {{ form_label(form.password.second, null, { 'attr': {'class': 'form-label'} }) }}
    {{ form_widget(form.password.second, { 'attr': {'class': 'form-input'} }) }}
</div>
....
18
cslucano

Wenn Sie ein User-Bundle verwenden, verwenden Sie password.First und Password.second. Versuchen Sie noch besser, mit Ihrem Profiler zu sehen, welche Variablen aus der Ansicht und den Controllern stammen.

3
Luis Lopes

Wenn Sie anwendungsweite Klassen für Ihre Beschriftungen und Eingaben haben möchten, können Sie die Darstellung von Beschriftungen und Widgets anpassen. Check http://symfony.com/doc/current/cookbook/form/form_customization.html

Wenn Sie sich diese Datei ansehen:

vendor/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Sie können die Standardeinstellungen für alle Widgets anzeigen. Um genau das zu erreichen, was Sie benötigen, können Sie den generic_label-Block überschreiben, um eine Formular-Label-Klasse hinzuzufügen:

{% block generic_label %}
{% spaceless %}
    {% if required %}
        {# We add form-label class in the next line! #}
        {% set attr = attr|merge({'class': attr.class|default('') ~ ' required form-label'}) %}
    {% endif %}
    <label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>{{ label|trans }}</label>
{% endspaceless %}
{% endblock %}

Und widget_attributes-Block zum Hinzufügen einer Formulareingangsklasse:

{% block widget_attributes %}
{% spaceless %}
    {# We add form-input class in the next line! #}
    {% set attr = attr|merge({'class': attr.class|default('') ~ ' form-input'}) %}
    id="{{ id }}" name="{{ full_name }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
    {% for attrname,attrvalue in attr %}{{attrname}}="{{attrvalue}}" {% endfor %}
{% endspaceless %}
{% endblock widget_attributes %}

Mit diesen beiden Vorlagen sollten alle Ihre Eingaben mit den von Ihnen benötigten Klassen gerendert werden, ohne die attr-Parameter in Ihren Formularen wiederholen zu müssen.

Ich habe es nicht ausprobiert, aber es sollte sich um das wiederholte Feldproblem kümmern. Selbst wenn dies nicht der Fall ist, können Sie eine wiederholte_widget- und/oder wiederholte_row-Vorlage erstellen, um die Darstellung des wiederholten Widgets anzupassen, wodurch das Widget für alle Formulare, die es verwenden, korrigiert wird.

0
Jens