Pregunta

Maybe there's totally different and better approach to what I need, but here's my situation and any comments/suggestions are welcome. I have Entity with:

/**
 * @var string
 * @ORM\Column(name="title", type="string", length=255, nullable=true)
 */
protected $title;

/**
 * @var string
 * @ORM\Column(name="description", type="string", length=1024, nullable=true)
 */
protected $description;

/**
 * @var string
 * @ORM\Column(name="extra_data", type="json_array", nullable=true)
 */
protected $extraData;

Notice $extraData - it's all about this json_array.

I have FormType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('items', 'collection', array(
        'type' => new ItemType(),
        'allow_add' => true,
        'by_reference' => false,
        'allow_delete' => true,
        'options' => array(
            'em' => $options['em'],
        )
    ));
}


public function getName()
{
    return 'form';
}

ItemType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', 'text', array(
            'label' => false,
            'required' => false,
        ))
        ->add('description', 'textarea', array(
            'label' => false,
        ))
        ->add('extra_data', 'collection', array(
            'type' => new ItemExtraDataType(),
            'required' => false,
            'allow_add' => false,
            'by_reference' => false,
            'allow_delete' => false,
        ));
}

public function getName()
{
    return 'item';
}

ItemExtraDataType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('field1', 'text', array(
            'required' => false,
        ))
        ->add('field2', 'text', array(
            'required' => false,
        ));
}

public function getName()
{
    return 'item_extra_data';
}

In Twig:

<form method="post" action="" id="form">
{% for item in form.items %}
    {{ form_row(item.title) }}
    {{ form_row(item.description) }}
    {{ form_row(item.extra_data) }}
    {{ form_rest(item) }}
{% endfor %}
{{ form_rest(form) }}
</form>

Also tried:

{% for field, value in item.extra_data %}
{{ form_row(value) }}<br><br>
{% endfor %}

And also tried just leaving {{ form_rest(item) }}, but no change.

So field1 and field2 never is printed out. I can't enter values for these JSON array fields. Maybe I'm using it wrong? Also I'm wondering how saving of this json_array field works.

Thanks

P.S. Using Symfony 2.3.7

¿Fue útil?

Solución

Bellow I'm leaving the old answer, that worked for me until I had to implement more complex json_array. Here's how it should be done:

ItemType:

->add('extra_data', new ItemExtraDataType(), array(
    'label' => false,
    'required' => false,
))

ItemExtraDataType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('field1', 'text', array(
            'required' => false,
            'label' => false,
        ))
        ->add('field2', 'text', array(
            'required' => false,
            'label' => false,
        ))
        ->add('field3', 'choice', array(
            'choices' => MyChoices::getReadables(),
            'empty_value' => 'empty',
            'required' => false,
            'label' => false,
        ))
    ;
}

public function getParent()
{
    return 'form';
}

Twig template:

{{ form_row(item.extra_data) }}

So now everything works as expected.



Old answer

I believe a better solution is out there, but that's what I did and it worked at last.

Entity:

/**
 * @param array $extra_data
 * @return Entity
 */
public function setExtraData(array $extra_data)
{
    $this->extraData = $extra_data;
    return $this;
}

/**
 * @return array
 */
public function getExtraData()
{
    $rs = $this->extraData;
    return $rs ?: array('field1' => '', 'field2' => '');
}

ItemType (notice the type param):

->add('extra_data', 'collection', array(
    'type' => 'text',
    'label' => false,
    'required' => false,
    'allow_add' => false,
    'by_reference' => false,
    'allow_delete' => false,
))

Twig template:

{% for field, data in item.extra_data %}
    {{ form_row(data, {'attr':{'placeholder':'extra_data.' ~ field}}) }}
{% endfor %}

Both fields are printed out and saved without any problem.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top