0

To allow customisation of the registration form, some form fields are generated from database informations and the form in embedded into the registration form.

While each fields of the embedded form is typed, for some reason, when I render them using twig, some types like url or number are rendered as text type input.

Yet, all fields form the main form (nom, prenom, email, plainPassword) are rendered with the assigned type.

As you can see in the code fragments, I'm properly using form_widget and form_widget to render each input, thus type handling is done by Symfony.

When I dump each formView for each field, within field.vars.block_prefixes (array), I can find the type of the input as it should be.

As example, this is the content of a text input :

"block_prefixes" => array:3 [▼
  0 => "form"
  1 => "text"
  2 => "_security_extraDataCollection_datum-30"
]

The content of a url input :

"block_prefixes" => array:4 [▼
  0 => "form"
  1 => "text"
  2 => "url"
  3 => "_security_extraDataCollection_datum-31"
]

And the content of a number input :

"block_prefixes" => array:3 [▼
  0 => "form"
  1 => "number"
  2 => "_security_extraDataCollection_datum-33"
]

At first, I thought that was because I was using material-component-web, but even without CSS, this problem occur.

Any idea as to why url and number type are turned to text type when I render them from enbedded form?

Registration form

public function buildForm(FormBuilderInterface $builder, array $options) {
    /** @var array $extraData */
    $extraData=$options['extra_data'];

    $builder->add('nom')
            ->add('prenom')
            ->add('email', EmailType::class)
            ->add('plainPassword', PasswordType::class, array(
                'mapped'=>false,
                'constraints'=>array(
                    new NotBlank(array(
                        'message'=>'Please enter a password',
                    )),
                    new Length(array(
                        'min'=>6,
                        'max'=>4096,
                    )),
                ),
            ));

    if($extraData !== null && is_array($extraData) && count($extraData)) {
        $builder->add('extraDataCollection', UnmappedMixedType::class, array(
            'mapped'=>false,
            'data'=>$extraData,
        ));
    }
}

UnmappedMixedType form

public function buildForm(FormBuilderInterface $builder, array $options) {
    /** @var array $extraData */
    $extraData=$options['data'];

    /** @var ExtraData $extraDatum */
    foreach($extraData as $extraDatum) {
        if($extraDatum->getType() == 'text') {
            $builder->add('datum-'.$extraDatum->getId(), TextType::class, array(
                'mapped'=>false,
                'required'=>$extraDatum->getIsObligatoire(),
                'label'=>$extraDatum->getLabel(),
            ));
        } elseif($extraDatum->getType() == 'url') {
            $builder->add('datum-'.$extraDatum->getId(), UrlType::class, array(
                'mapped'=>false,
                'required'=>$extraDatum->getIsObligatoire(),
                'label'=>$extraDatum->getLabel(),
            ));
        } elseif($extraDatum->getType() == 'number') {
            $builder->add('datum-'.$extraDatum->getId(), NumberType::class, array(
                'mapped'=>false,
                'required'=>$extraDatum->getIsObligatoire(),
                'label'=>$extraDatum->getLabel(),
            ));
        } elseif($extraDatum->getType() == 'checkbox') {
            $builder->add('datum-'.$extraDatum->getId(), CheckboxType::class, array(
                'mapped'=>false,
                'required'=>$extraDatum->getIsObligatoire(),
                'label'=>$extraDatum->getLabel(),
            ));
        } elseif($extraDatum->getType() == 'choice' && $extraDatum->getChoix() !== null && count($extraDatum->getChoix()) >= 1) {
            $builder->add('datum-'.$extraDatum->getId(), ChoiceType::class, array(
                'mapped'=>false,
                'required'=>$extraDatum->getIsObligatoire(),
                'label'=>$extraDatum->getLabel(),
                'multiple'=>$extraDatum->getIsChoixMultipleUtilisateur(),
                'choices'=>array_combine($extraDatum->getChoix(), $extraDatum->getChoix()),
            ));
        }
    }
}

Twig view

{% if form.extraDataForm is defined %}
    <div class="app-auth-left-frame-extra">
        <div class="app-form-container">
            <div class="app-form_field-container">
                {% for field in form.extraDataForm %}
                    {{ dump(field) }}
                    {% if field.vars.block_prefixes[1] == 'text' or field.vars.block_prefixes[1] == 'number' %}
                        <div class="mdc-text-field mdc-text-field--outlined">
                            {{ form_widget(field, {'attr': {'class': 'mdc-text-field__input'}}) }}
                            <div class="mdc-notched-outline">
                                <div class="mdc-notched-outline__leading"></div>
                                <div class="mdc-notched-outline__notch">
                                    {{ form_label(field, null, {'label_attr': {'class': 'mdc-floating-label'}}) }}
                                </div>
                                <div class="mdc-notched-outline__trailing"></div>
                            </div>
                        </div>
                    {% elseif field.vars.block_prefixes[1] == 'checkbox' %}
                        <div class="mdc-form-field">
                            <div class="mdc-checkbox">
                                {{ form_widget(field, {'attr': {'class': 'mdc-checkbox__native-control'}}) }}
                                <div class="mdc-checkbox__background">
                                    <!--suppress HtmlUnknownAttribute -->
                                    <svg class="mdc-checkbox__checkmark" viewBox="0 0 24 24">
                                        <path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59"></path>
                                    </svg>
                                </div>
                            </div>
                            {{ form_label(field, null, {'label_attr': {'class': 'app-txt-light-emphasis'}}) }}
                        </div>
                    {% elseif field.vars.block_prefixes[1] == 'choice' %}
                        <div>{{ form_widget(field) }}</div>
                    {% endif %}
                {% endfor %}
            </div>
        </div>
    </div>
{% endif %}

1 Answer 1

1

UrlType Field as the documentations says:

The UrlType field is a text field that prepends the submitted value with a given protocol (e.g. http://) if the submitted value doesn't already have a protocol.

If you would like an input with url type create your own Form Field Type like that:

class MyUrlType extends AbstractType {

    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['type'] = 'url';
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return __NAMESPACE__.'\TextType';
    }
}

From here https://symfony.com/doc/current/form/create_custom_field_type.html

Sign up to request clarification or add additional context in comments.

2 Comments

I see... Then what about NumberType? That one doesn't seems to fall under this exception.
Nvm, found for NumberType, had to add 'html5'=>true in the parameters list. In getParent() for UrlType, it's return UrlType::class;, return __NAMESPACE__.'\TextType'; throw an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.