我正在尝试使用 GenemuFormBundle 添加 Select2 输入如 "Use jQuery Select2 with Ajax" doc 中所述.在 jQuery Select2 Field documentation 之后添加一个 jQuery Select2 字段工作得很好。

但是关于如何实现 Ajax 加载 Select2 表单的文档非常不确定。如果我正确理解文档,它旨在创建与 Select2 documentation 中提到的相同的文档。 .这正是我想要创造的东西。我添加了隐藏字段以及所需的 JavaScript,但我唯一得到的是一个 Variable "id" does not exist in xBundle:x:new.html.twig at line x .

表单构建器(直接取自上述文档):

... 
->add('field_name', 'genemu_jqueryselect2_hidden', array( 
    'configs' => array( 
        'multiple' => true // Wether or not multiple values are allowed (default to false) 
    ) 
)) 
->add('field_name', 'genemu_jqueryselect2_entity', array( 
    'class' => 'xBundle:Entity', 
    'property' => 'foo', 
)) 

查看(也直接从文档中获取):
{% block stylesheets %} 
    {{ form_stylesheet(form) }} 
{% endblock %} 
 
{% block javascript %} 
    {{ form_javascript(form) }} 
{% endblock %} 
 
{% block genemu_jqueryselect2_javascript %} 
 
    <script type="text/javascript"> 
        $field = $('#{{ id }}'); 
 
        var $configs = {{ configs|json_encode|raw }}; 
 
        // custom configs 
        $configs = $.extend($configs, { 
            query: function (query) { 
                var data = {results: []}, i, j, s; 
                for (i = 1; i < 5; i++) { 
                    s = ""; 
                    for (j = 0; j < i; j++) {s = s + query.term;} 
                    data.results.push({id: query.term + i, text: s}); 
                } 
                query.callback(data); 
            } 
        }); 
        // end of custom configs 
 
        $field.select2($configs); 
    </script> 
 
{% endblock %} 

请您参考如下方法:

我只是在这个确切的问题上挣扎,并认为我会为任何碰巧偶然发现的人提供我自己的发现。我确实找到了一个解决方案,但我可能仍然建议只使用 Doug 推荐的 ZenStruckFormBundle,因为它似乎实际上被设计为用于通过 ajax 加载并与实体相关联的 select2 字段类型的解决方案。

这不起作用的真正原因是 genemu_jqueryselect2_* GenemuFormBundle 的类型没有实现 data transformer当您需要 ajax 加载 select2 字段时,它将与实体一起使用。它似乎从未被设计为以这种方式工作。当您使用 genemu_jqueryselect2_hidden键入并将“multiple”配置选项设置为true,然后添加一个ArrayToStringTransformer .这不适用于实体。

要解决此问题,您需要创建一个新的表单字段类型并定义其父项为 genemu_jqueryselect2_hidden然后进行一些自定义。它看起来像这样……

namespace Acme\DemoBundle\Form\Type; 
 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Acme\DemoBundle\Form\DataTransformer\EntityCollectionToIdTransformer; 
use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
 
class EntityCollectionSelectorType extends AbstractType 
{ 
    /** 
     * @var ObjectManager 
     */ 
     protected $om; 
 
    /** 
     * @param ObjectManager $om 
     */ 
    public function __construct(ObjectManager $om) 
    { 
        $this->om = $om; 
    } 
 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
        $transformer = new EntityCollectionToIdTransformer($this->om, $options['configs']['entity']); 
        $builder->resetViewTransformers(); 
        $builder->addModelTransformer($transformer); 
    } 
 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
        $resolver->setDefaults(array( 
            'invalid_message' => 'The selected entity does not exist', 
            'required' => true, 
            'auto_initialize' => false, 
            'configs' => array('multiple' => true), 
            'error_bubbling' => false,  
        )); 
    } 
 
    public function getParent() 
    { 
        return 'genemu_jqueryselect2_hidden'; 
    } 
 
    public function getName() 
    { 
        return 'entity_collection_selector'; 
    } 
} 

然后您还需要添加用于上述表单字段类型的新数据转换器,以便它可以转换表单字段和实体之间的值……
namespace Acme\DemoBundle\Form\DataTransformer; 
 
use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Exception\TransformationFailedException; 
use Doctrine\ORM\PersistentCollection; 
use Doctrine\Common\Persistence\ObjectManager; 
use Doctrine\Common\Collections\ArrayCollection; 
 
class EntityCollectionToIdTransformer implements DataTransformerInterface 
{ 
    /** 
     * @var ObjectManager 
     */ 
    private $om; 
 
    /** 
     * @var string The Doctrine entity type to use 
     */ 
    private $entityType; 
 
    /** 
     * @param ObjectManager $om 
     */ 
    public function __construct(ObjectManager $om, $entityType) 
    { 
        $this->om = $om; 
        $this->entityType = $entityType; 
    } 
 
    /** 
     * Transforms a collection of entities to a comma separated string 
     * 
     * @param  ArrayCollection $entities 
     * @return string 
     */ 
    public function transform($entities) 
    { 
        if (null == $entities || empty($entities)) { 
            return ''; 
        } 
 
        $results = ''; 
        foreach ($entities as $entity) { 
            $results .= $entity->getId() . ','; 
        } 
        $results = trim($results, ' ,'); 
 
        return $results; 
    } 
 
   /** 
    * Transforms a string of comma separated IDs to a PersistentCollection for Doctrine 
    * 
    * @param  string $values 
    * @return PersistentCollection|ArrayCollection 
    * @throws TransformationFailedException if entity is not found. 
    */ 
    public function reverseTransform($values) 
    { 
        if (!$values) { 
            return new ArrayCollection(); 
        } 
        $values = explode(',', $values); 
 
        $collection = array(); 
        foreach ($values as $id) { 
            $item = $this->om->getRepository($this->entityType)->findOneById($id); 
 
            if (!is_null($item)) { 
                $collection[] = $item; 
            } 
            else { 
                throw new TransformationFailedException(sprintf( 
                    'An entity with ID "%s" does not exist!', 
                    $value 
                )); 
            } 
        } 
 
        return new PersistentCollection($this->om, $this->entityType, new ArrayCollection($collection)); 
    } 
} 

现在确保您在配置中为您的服务定义了新的字段类型……
<?xml version="1.0" ?> 
 
<container xmlns="http://symfony.com/schema/dic/services" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> 
 
    <parameters> 
        ... 
        <parameter key="acme_demo.form.type.entity_collection_selector.class">Acme\DemoBundle\Form\Type\EntityCollectionSelectorType</parameter> 
        ... 
    </parameters> 
 
    <services> 
        ... 
        <service id="acme_demo.form.type.entity_collection_selector" 
            class="%acme_demo.form.type.entity_collection_selector.class%"> 
            <argument type="service" id="doctrine.orm.default_entity_manager" /> 
            <tag name="form.type" alias="entity_collection_selector" /> 
        </service> 
        ... 
    </services> 
</container> 

现在你可以这样使用它......
$builder->add('customers', 'entity_collection_selector', array( 
    'configs' => array('entity' => 'AcmeDemoBundle:Customer') 
)); 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!