1

I want to create form with composition pattern like this: https://symfony.com/doc/current/form/inherit_data_option.html

I use Symfony 3.

and it's working. I have each element like single object and add this.

but finally my form elements names have name like

form[subform][element]

How to make flat structure without subform in name attribute?

use AppBundle\Base\Form\NickType;
use AppBundle\Base\Form\MailType;
use AppBundle\Base\Form\PassType;
use AppBundle\Base\Form\UserType;


class RegisterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nick', NickType::class)
            ->add('mail', MailType::class)
            ->add('password', PassType::class)
            ->add('repeat_password', PassType::class)
(etc...)

and SINGLE ELEMENT

class NickType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nick', TextType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'inherit_data' => true
        ));
    }

}
Stephan Vierkant
  • 9,674
  • 8
  • 61
  • 97
taro
  • 63
  • 6

1 Answers1

0

You don't need to define a NickType if it only inherits a TextType. You can remove NickType, MailType, etc.

You can just do:

class RegisterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nick', TextType::class)
        ;
(etc...)

If you want to reuse a form field, you have to create a Custom Form Field Type:

class NickType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            //...
        ));
    }

    public function getParent()
    {
        return TextType::class;
    }
}

You can remove form[] from the element name, but removing this is not really recommended, because when you read the request to populate form data you can identify the form by its form name. (via)

You can set the name of the root form to empty, then your field name will be just form. Do so via

// the first argument to createNamedBuilder() is the name
$form = $this->get('form.factory')->createNamedBuilder(null, 'form', $defaultData)
    ->add('from', 'date', array(
        'required' => false,
        'widget' => 'single_text',
        'format' => 'dd.MM.yyyy'
    ));

(via)

Stephan Vierkant
  • 9,674
  • 8
  • 61
  • 97
  • Yes but in future I will use nick element in many forms. It is reason why I want to have single object per fields. In one place I will have validation rules etc... – taro Nov 17 '17 at 09:54
  • Ok its better but I got: name="register[nick]" Finally I want to get name="nick". Thank you! – taro Nov 17 '17 at 18:59
  • Is there is a specific reason you really want this? If it's only for the aesthetics or your code: please leave if this way. If there is another technical reason: please let us know, maybe there is a better solution. If you still want this: see my updated answer. – Stephan Vierkant Nov 17 '17 at 23:40
  • In another project we had many subforms and later we should use multidimensional array to receive data, and it is not good. So I think, it is main reason. I use Zend Framework every day and flat array is good to do $row->setFromArray($data); and later $row->save(); So it is reason why I want to do in this way in Symfony :) It is maybe habit. Thank you. – taro Nov 18 '17 at 13:44
  • @taro Does my answer solve your question? If not, please let me know. Otherwise, consider upvoting and/or accepting my answer. I see you haven't cast any votes yet. See https://stackoverflow.com/help/why-vote for more information. – Stephan Vierkant Nov 19 '17 at 21:55
  • yes it's works. Thank you. I want to vote your post and I will do it in future, but now I don't have enough points/reputation to do it. – taro Nov 20 '17 at 20:20
  • Thanks! Sorry, I forgot that voting is only possible at 15+ rep. – Stephan Vierkant Nov 20 '17 at 20:21