gpt4 book ai didi

forms - Symfony 2 GenemuFormBundle 如何使用 Ajax 创建 jQuery Select2

转载 作者:行者123 更新时间:2023-12-04 12:21:14 26 4
gpt4 key购买 nike

我正在尝试使用 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')
));

关于forms - Symfony 2 GenemuFormBundle 如何使用 Ajax 创建 jQuery Select2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22683595/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com