Symfony2 覆盖 Twig 中的表单小部件
Symfony2 override a form widget in Twig
我正在尝试按照此文档覆盖 Twig 中的表单小部件:
http://symfony.com/doc/current/cookbook/form/form_customization.html#method-1-inside-the-same-template-as-the-form
但是我有点迷路了。
这是我要细分的 select 字段:
{{ form_widget(edit_form.activities) }}
这是文档中的覆盖过程:
{% form_theme edit_form _self %}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% set attr = choice.attr %}
<option value="{{ choice.value }}" {{ block('attributes') }}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
目的是能够 select select 框中的多个字段,其中包含通过我的控制器发布的一组 ID。
你们知道怎么做吗?
Firstly check if path to your template is correct: app/Resources/views/Form/fields.html.twig
Next, in the template where you are using the form, you have to specify your customized template to be used
{% form_theme form 'AppBundle:Form:fields.html.twig' %}
{{ form_widget(edit_form.activities) }}
用 Twig 做它没有用。所以我在 FormType 端做了。
解决方案:使用 PRE_SET_DATA。我用 'data' 选项覆盖了表单。
这是适合您的代码:
class TagType extends AbstractType
{
/** @var $em EntityManager */
private $em;
/**
* TagType constructor.
*
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', [
'label' => 'Tags',
])
->add('activities', 'entity', [
'label' => 'Affecter à des activitées',
'mapped' => false,
'class' => 'App\TagBundle\Entity\Activity\Activity',
'required' => false,
'multiple' => true,
'attr' => [
'data-js' => 'chosen',
'data-placeholder' => 'Affecter à des activitées',
],
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
}
/**
* @param FormEvent $event
*/
public function onPreSetData(FormEvent $event)
{
$tag = $event->getData();
$form = $event->getForm();
/** Doctrine\ORM\PersistentCollection $taggingCollection */
$taggingCollection = $tag->getTagging();
if ($taggingCollection == null)
return; // leave if no tag (probably a new action)
$activitiesIds = array();
/** @var \App\TagBundle\Entity\Activity\Tagging $tagging */
foreach( $taggingCollection as $tagging){
$activitiesIds[] = $tagging->getResourceId();
}
$em = $this->em;
$activities = new ArrayCollection();
foreach($activitiesIds as $activityId) {
$activity = $em->getRepository('AppTagBundle:Activity\Activity')->find($activityId);
$activities->add($activity);
}
$form->add('activities', 'entity', [
'label' => 'Editer les activitées affectées',
'mapped' => false,
'class' => 'App\TagBundle\Entity\Activity\Activity',
'required' => false,
'multiple' => true,
'attr' => [
'data-js' => 'chosen',
'data-placeholder' => 'Affecter à des activitées',
],
'data' => $activities
]);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'data_class' => 'App\TagBundle\Entity\Activity\Tag',
]);
}
/**
* @return string
*/
public function getName()
{
return 'App_TagBundle_activity_tag';
}
}
我正在尝试按照此文档覆盖 Twig 中的表单小部件: http://symfony.com/doc/current/cookbook/form/form_customization.html#method-1-inside-the-same-template-as-the-form
但是我有点迷路了。 这是我要细分的 select 字段:
{{ form_widget(edit_form.activities) }}
这是文档中的覆盖过程:
{% form_theme edit_form _self %}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% set attr = choice.attr %}
<option value="{{ choice.value }}" {{ block('attributes') }}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
目的是能够 select select 框中的多个字段,其中包含通过我的控制器发布的一组 ID。
你们知道怎么做吗?
Firstly check if path to your template is correct: app/Resources/views/Form/fields.html.twig
Next, in the template where you are using the form, you have to specify your customized template to be used
{% form_theme form 'AppBundle:Form:fields.html.twig' %}
{{ form_widget(edit_form.activities) }}
用 Twig 做它没有用。所以我在 FormType 端做了。
解决方案:使用 PRE_SET_DATA。我用 'data' 选项覆盖了表单。
这是适合您的代码:
class TagType extends AbstractType
{
/** @var $em EntityManager */
private $em;
/**
* TagType constructor.
*
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', [
'label' => 'Tags',
])
->add('activities', 'entity', [
'label' => 'Affecter à des activitées',
'mapped' => false,
'class' => 'App\TagBundle\Entity\Activity\Activity',
'required' => false,
'multiple' => true,
'attr' => [
'data-js' => 'chosen',
'data-placeholder' => 'Affecter à des activitées',
],
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
}
/**
* @param FormEvent $event
*/
public function onPreSetData(FormEvent $event)
{
$tag = $event->getData();
$form = $event->getForm();
/** Doctrine\ORM\PersistentCollection $taggingCollection */
$taggingCollection = $tag->getTagging();
if ($taggingCollection == null)
return; // leave if no tag (probably a new action)
$activitiesIds = array();
/** @var \App\TagBundle\Entity\Activity\Tagging $tagging */
foreach( $taggingCollection as $tagging){
$activitiesIds[] = $tagging->getResourceId();
}
$em = $this->em;
$activities = new ArrayCollection();
foreach($activitiesIds as $activityId) {
$activity = $em->getRepository('AppTagBundle:Activity\Activity')->find($activityId);
$activities->add($activity);
}
$form->add('activities', 'entity', [
'label' => 'Editer les activitées affectées',
'mapped' => false,
'class' => 'App\TagBundle\Entity\Activity\Activity',
'required' => false,
'multiple' => true,
'attr' => [
'data-js' => 'chosen',
'data-placeholder' => 'Affecter à des activitées',
],
'data' => $activities
]);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'data_class' => 'App\TagBundle\Entity\Activity\Tag',
]);
}
/**
* @return string
*/
public function getName()
{
return 'App_TagBundle_activity_tag';
}
}