【发布时间】:2016-09-27 13:21:06
【问题描述】:
我想知道是否有一种方法可以以不同于 select 的 symfony 形式“管理”多对一关联(例如,使用 jQuery 自动完成输入)。
我找到了this question,所以我阅读了有关DataTransformers的文档
这是我的变压器类
// src/AppBundle/Form/DataTransformer/ZipcodesTransformer.php
namespace AppBundle\Form\DataTransformer;
use AppBundle\Entity\Issue;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class ZipcodesTransformer implements DataTransformerInterface {
private $manager;
public function __construct(ObjectManager $manager) {
$this->manager = $manager;
}
public function transform($zipcode) {
if (null === $zipcode) {
return '';
}
return $zipcode->getId();
}
public function reverseTransform($zipcodeId) {
if (!$zipcodeId) {
return;
}
$zipcode = ->this->manager->getRepository('AppBundle:Zipcodes')->find($zipcodeId)
;
if (null === $zipcode) {
throw new TransformationFailedException(sprintf(
'An zipcode with number "%s" does not exist!',
$zipcodeId
));
}
return $zipcode;
}
}
然后是选择器类型类
// src/AppBundle/Form/ZipcodeSelectorType.php
namespace AppBundle\Form;
use AppBundle\Form\DataTransformer\ZipcodesTransformer;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class ZipcodeType extends AbstractType
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new ZipcodesTransformer($this->manager);
$builder->addModelTransformer($transformer);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'invalid_message' => 'The selected ZIPCODE does not exist',
));
}
public function getParent()
{
return TextType::class;
}
}
对象形式的类是
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use AppBundle\Form\DataTransformer\ZipcodesTransformer;
class CustomerType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class ,array('label'=>'Customer Name'))
...
->add('email', EmailType::class)
->add('flag', CheckboxType::class, array('required' => false))
->add('zipcode', ZipcodeType::class)
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array('data_class' => 'AppBundle\Entity\Customer'));
}
}
感谢 Kern,代码现在正确且有效。 现在为了“激活”已经测试过的 jQuery 自动完成功能,我修改了 ZipcodeSelectorType.php 并添加了这个函数
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array (
'invalid_message' => 'The selected ZIPCODE does not exist',
'attr' => array('class'=>'zipcodeac'),//ADDED THIS LINE
'placeholder'=>'Type to select a zipcode'//ADDED THIS LINE
)
);
}
但是当渲染表单时输入有这个类
class="zipcodeac form-control ui-autocomplete-input"
和属性
自动完成=“关闭”
并且不会触发 Ajax。
【问题讨论】:
-
我认为您正在寻找实体字段类型:)!文档:symfony.com/doc/current/reference/forms/types/entity.html
-
@Kern - 你完全正确。我使用 EntityType 和 CollectionType 来管理 OneToMany 或 ManyToOne 关联。当可选择的选项数量超过数千时,我需要一些不同的东西。谢谢。
标签: jquery symfony doctrine-orm