Symfony 2 GenemuFormBundle如何用Ajax创建jQuery Select2
我正在尝试使用GenemuFormBundle添加一个Select2输入,如“使用带有Ajax的jQuery Select2”文档中所述。 在jQuery Select2 Field文档之后添加一个jQuery Select2字段工作得很好。
但是关于如何实现Ajax加载Select2表单的文档是非常不确定的。 如果我正确地打开文档,它的目标是创建Select2文档中提到的相同内容。 这正是我想要创建的。 我添加了隐藏字段以及所需的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_*
类型没有实现数据转换器,当您需要ajax-loading select2字段时,它将与实体一起工作。 它似乎并没有被设计成以这种方式工作。 当您使用genemu_jqueryselect2_hidden
类型并将“多个”配置选项设置为true时,它会添加一个ArrayToStringTransformer。 这不适用于实体。
为了解决这个问题,你需要创建一个新的表单字段类型,并定义它的父类是genemu_jqueryselect2_hidden
然后进行一些自定义。 它看起来像这样...
namespace AcmeDemoBundleFormType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use AcmeDemoBundleFormDataTransformerEntityCollectionToIdTransformer;
use DoctrineCommonPersistenceObjectManager;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
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 AcmeDemoBundleFormDataTransformer;
use SymfonyComponentFormDataTransformerInterface;
use SymfonyComponentFormExceptionTransformationFailedException;
use DoctrineORMPersistentCollection;
use DoctrineCommonPersistenceObjectManager;
use DoctrineCommonCollectionsArrayCollection;
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">AcmeDemoBundleFormTypeEntityCollectionSelectorType</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')
));
链接地址: http://www.djcxy.com/p/78391.html
上一篇: Symfony 2 GenemuFormBundle how to create a jQuery Select2 with Ajax
下一篇: include: onload calling a function defined in included controller