i.a*_*iel 23 forms validation symfony doctrine-orm
如何在Symfony中使用相关的选择框?
比方说,我有一个包含compagnies的选择列表,另一个包含所选公司的员工.我如何在Symfony中定义它们?我已经创建了所有与Javascript相关的代码,但在提交表单并在某些字段上出错时,所有"sub"选择字段都将重置为null.
有任何想法吗?
谢谢,
编辑:由于这个问题似乎被误解了,我将添加一些精确性:
不工作,没有办法开箱即用.即使是非开箱即用的解决方案......
但是在创建表单时,值为空.这些值仅在bindRequest上设置.
这实际上是有效的,但我认为除了真正难看的编程之外别无他法.
这里有一个问题,在Symfony2邮件列表,Twitter和官方Symfony 2论坛上.在发布我的问题之前,我当然已经多次搜索过这些.
Flo*_*ian 13
关于你已经尝试过的,我认为你应该重试你的第一个/第二个想法:
我的第一个想法是使用表单实体类型,认为组件可以以某种方式绑定在另一个字段上.即.根据所选公司的价值更新员工列表.
您可以使用entity类型填充员工选择框.您所要做的就是定义好的选择:
class FooType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('employee', 'entity', array(
'class' => 'Entity\Employee',
'query_builder' => function ($repository) use($options) {
return $repository
->createQueryBuilder('e')
->where('e.company = :company')
->setParameter('company', $options['companyId'])
;
},
))
;
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Entity\Foo', 'companyId' => null);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我考虑手动将所选公司作为参数传递给第二个下拉列表的查询构建器.
此处的示例根据companyId表单的选项筛选员工列表.您可以通过直接过滤表单数据中存在的公司来修改此行为.
public function buildForm(FormBuilder $builder, array $options)
{
$companyId = $builder->getData()->getCompanyId();
$builder
->add('employee', 'entity', array(
'class' => 'Entity\Employee',
'query_builder' => function ($repository) use ($companyId) {
return $repository
->createQueryBuilder('e')
->where('e.company = :company')
->setParameter('company', $companyId)
;
},
))
;
}
Run Code Online (Sandbox Code Playgroud)
您仍然需要在类中实现getEmployee()和setEmployee()方法Entity\Foo.
但是在创建表单时,值为空.这些值仅在bindRequest上设置.
不可以.使用表单工厂(第三个参数)创建表单时,或者在调用时设置值$form->setData($foo);.当您bind对表单的新输入时,将修改数据.
这种方法可能存在问题:绑定到表单的员工ID可能在表单选项列表中不可用,因为您更改了公司(以及员工).
我有同样的问题.您必须使用表单事件.我的代码示例包含国家,地区,城市关系.
namespace Orfos\UserBundle\Form\Type;
///import form events namespace
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Event\DataEvent;
class RegistrationFormType extends BaseType
{
private $request;
public function __construct($class, $request, $doctrine)
{
parent::__construct($class);
$this->request = $request;
$this->doctrine = $doctrine;
}
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
//other fields
$locale = $this->request->getLocale();
$builder->add('country', 'entity', array(
'class' => 'Orfos\CoreBundle\Entity\Country',
'property' => $locale . 'name',
'label' => 'register.country.label',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('c')
->select('c', 't')
->join('c.translations', 't');
},
));
$factory = $builder->getFormFactory();
$refreshRegion = function ($form, $country) use ($factory, $locale) {
$form->add($factory->createNamed('entity', 'region', null, array(
'class' => 'Orfos\CoreBundle\Entity\Region',
'property' => $locale . 'name',
'label' => 'register.region.label',
'query_builder' => function (EntityRepository $repository) use ($country) {
$qb = $repository->createQueryBuilder('region')
->select('region', 'translation')
->innerJoin('region.country', 'country')
->join('region.translations', 'translation');
if ($country instanceof Country) {
$qb = $qb->where('region.country = :country')
->setParameter('country', $country);
} elseif (is_numeric($country)) {
$qb = $qb->where('country.id = :country_id')
->setParameter('country_id', $country);
} else {
$qb = $qb->where('country.id = 1');
}
return $qb;
}
)));
};
$factory = $builder->getFormFactory();
$refreshCity = function($form, $region) use ($factory, $locale) {
$form->add($factory->createNamed('entity', 'city', null, array(
'class' => 'Orfos\CoreBundle\Entity\City',
'property' => $locale . 'name',
'label' => 'register.city.label',
'query_builder' => function (EntityRepository $repository) use ($region) {
$qb = $repository->createQueryBuilder('city')
->select('city', 'translation')
->innerJoin('city.region', 'region')
->innerJoin('city.translations', 'translation');
if ($region instanceof Region) {
$qb = $qb->where('city.region = :region')
->setParameter('region', $region);
} elseif (is_numeric($region)) {
$qb = $qb->where('region.id = :region_id')
->setParameter('region_id', $region);
} else {
$qb = $qb->where('region.id = 1');
}
return $qb;
}
)));
};
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) use ($refreshRegion, $refreshCity) {
$form = $event->getForm();
$data = $event->getData();
if ($data == null){
$refreshRegion($form, null);
$refreshCity($form, null);
}
if ($data instanceof Country) {
$refreshRegion($form, $data->getCountry()->getRegions());
$refreshCity($form, $data->getRegion()->getCities());
}
});
$builder->addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($refreshRegion, $refreshCity) {
$form = $event->getForm();
$data = $event->getData();
if (array_key_exists('country', $data)) {
$refreshRegion($form, $data['country']);
}
if (array_key_exists('region', $data)) {
$refreshCity($form, $data['region']);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10326 次 |
| 最近记录: |