forms - blocks - Symfony2 prototipo de formas anidadas mĂșltiples
variable block twig (2)
Quiero incluir un tipo de colección dentro de otro tipo de colección. Debe tener un aspecto como este:
Usar solo una colección funciona bien, pero necesito editar el prototipo de la forma externa, por lo que representa el prototipo de la forma interna de cada línea.
¿Alguna idea de cómo podría hacer eso? Además, ¿cuál sería la mejor manera de ahorrar?
EDITAR: ahora estoy tratando de renderizar el prototipo de la forma anidada:
<ul class="characteristics-container" data-prototype="{{ form_widget(form.characteristics.vars.prototype)|e }}" data-prototype-options="{{ form_widget(form.characteristics.options.vars.prototype|e ) }}">
{# iterate over each existing tag and render its only field: name #}
{% for characteristic in form.characteristics %}
<li>{{ form_row(characteristic.name) }}</li>
<div class="characteristics-options">
{% for opt in form.characteristics.options %}
{% endfor %}
</div>
{% endfor %}
</ul>
Da error en form_widget(form.characteristics.options.vars.prototype|e
Method "options" for object "Symfony/Component/Form/FormView" does not exist in
Intenté las características [0], y dice que la clave no existe
Aquí están mis clases de formulario:
PromotionType (la forma base)
$builder
->add(''characteristics'',''collection'', array(
''label'' => ''Caracteristicas'',
''type'' => new PromotionCharacteristicType(),
''allow_add'' => true,
''allow_delete'' => true,
''by_reference'' => false
))
PromotionCharacteristicType
$builder
->add(''name'',NULL, array(''label'' => ''Nome''))
->add(''options'', ''collection'', array(
''type'' => new PromotionCharacteristicOptionType(),
''allow_add'' => true,
''allow_delete'' => true,
''prototype'' => true,
''by_reference'' => false,
))
;
PromotionCharacteristicOptionType
$builder
->add(''name'',NULL, array(''label'' => ''Nome''))
;
El primer prototipo de nivel funciona bien.
formas y prototipos
Debes conservar dos prototipos de diferentes colecciones. Symfony ofrece almacenarlos en un atributo de prototipo de datos de la etiqueta div, que envuelve la colección. En tu situación, es muy ineficiente. Entonces puedes simplemente renderizarlo a mano en div vacío
Ejemplo que tienes forma de personajes
class CharacterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(''opts'', ''collection'', array(
''type'' => new OptionType(),
''allow_add'' => true,
''allow_delete'' => true,
''prototype'' => true,
''prototype_name'' => ''__opt_prot__''
));
$builder->add(''char_desc'', ''text'');
}
public function getName()
{
return ''char'';
}
}
Luego crea una forma que tenga colección de personajes
$form = $this->createFormBuilder()
->add(''chars'', ''collection'', array(
''type'' => new CharacterType(),
''allow_add'' => true,
''allow_delete'' => true,
''prototype_name'' => ''__char_prot__''
))
->getForm();
# example data
$form->setData(
array(
''chars'' => array(
array(''options'' => array(), ''char_desc'' => 1),
array(''options'' => array(), ''char_desc'' => 2),
),
)
);
y obtener prototipos
<div
id="prots"
data-prototype-opt="{{ form_widget(form.chars.vars.prototype.children[''opts''].vars.prototype) | e }}"
data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>
Y luego renderizar la colección como en este example o anular el bloque collection_widget
{% for char in form.chars %}
{{ form_row(char.char_desc) }}
<label for="">opts</label>
{% for opt in char.opts %}
{{ form_row(opt.text) }}
{% endfor %}
{% endfor %}
cómo guardarlo
Use la base de datos nosql si puede. O use el modelo EAV para las bases de datos de relaciones. Pero si no necesita buscar entre las opciones u ordenarlas, puede almacenar una matriz serializada en la base de datos y usar la array
tipos de doctrina.
Agregando a la respuesta de , usualmente no necesito usar prototype.children[''opts'']
para poder acceder al prototipo de la colección. Solo uso el prototype.<collection_name>
siguiente manera:
<div
id="prots"
data-prototype-opt="{{ form_widget(form.chars.vars.prototype.opts.vars.prototype) | e }}"
data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>