在 Symfony 表单中启用 Select2Search
Posted
技术标签:
【中文标题】在 Symfony 表单中启用 Select2Search【英文标题】:Enable Select2Search in Symfony form 【发布时间】:2018-10-29 09:06:25 【问题描述】:我想在我目前尝试过的 Symfony 表单中启用选择 2 搜索:
在我的表单类中,我有这个:
->add('parent', EntityType::class, [
'class' => Category::class,
'choice_label' => 'title',
'attr' => [
'class' => 'select2'
]
])
在我的树枝文件中:
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2-rc.1/css/select2.min.css" rel="stylesheet" />
<!-- Loading jquery here--><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2-rc.1/js/select2.min.js"></script>
</head>
form_start(form)
<script type="text/javascript">
$('select').select2();
</script>
form_widget(form)
form_end(form)
但我没有通过搜索栏获得下拉菜单。只是 Symfony 的默认下拉菜单。我做错了什么
【问题讨论】:
这是您模板的确切内容还是您只是发布了相关部分? @Philippe-B- 树枝文件的确切内容 我已经用代码示例更新了我的答案。 你的问题已经解决了吗? @JuanI.MoralesPestana 不,如果我加载多个 jQuery 会出现一些错误 【参考方案1】:主要原因是该字段是在您尝试定位它之后创建的,通过这一行:
form_widget(form)
之后必须执行 JavaScript 才能定位字段(此外,您的模板的 html 结构是错误的)。
试试这个:
<!DOCTYPE html>
<html>
<head>
<title>Test form</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2-rc.1/css/select2.min.css" rel="stylesheet" />
<!-- Loading jquery here--><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2-rc.1/js/select2.min.js"></script>
</head>
<body>
form_start(form)
form_widget(form)
form_end(form)
<script>
$('select').select2();
</script>
</body>
</html>
通常最好在执行脚本之前等待页面加载,使用 jQuery 可以通过将脚本更改为这样来确保它是这种情况:
<script>
$(document).ready(function()
$('.select2').select2();
);
</script>
请注意,我还更改了 jQuery 选择器以使用您添加到表单构建器中的字段的类。这样您就可以控制要定位的选择字段。
【讨论】:
【参考方案2】:您在没有配置的情况下启动 select2 组件,因此它不知道数据源在哪里。
在开始编码之前,您需要安装和配置FOSJsRoutingBundle。此捆绑包将帮助您访问 ajax 路由
对于完全配置的同步 symfony-forms~select2 你可以这样做。
实体人
class Person
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="person_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", nullable=true)
*/
private $name;
/**
* @var Country
*
* @ORM\ManyToOne(targetEntity="Country")
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="country_id", referencedColumnName="id")
* )
*/
private $country;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Set name
*
* @param string $name
*
* @return Person
*/
public function setName($name)
$this->name = $name;
return $this;
/**
* Get name
*
* @return string
*/
public function getName()
return $this->name;
/**
* Set country
*
* @param \AppBundle\Entity\Country $country
*
* @return Person
*/
public function setCountry(\AppBundle\Entity\Country $country = null)
$this->country = $country;
return $this;
/**
* Get country
*
* @return \AppBundle\Entity\Country
*/
public function getCountry()
return $this->country;
public function __toString()
return $this->name;
实体国家
class Country
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="country_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", nullable=true)
*/
private $name;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Set name
*
* @param string $name
*
* @return Country
*/
public function setName($name)
$this->name = $name;
return $this;
/**
* Get name
*
* @return string
*/
public function getName()
return $this->name;
public function __toString()
return $this->name;
国家资料库
类 CountryRepository 扩展 \Doctrine\ORM\EntityRepository
public function countriesSelect2($term)
$qb = $this->createQueryBuilder('c');
$qb->where(
$qb->expr()->like($qb->expr()->lower('c.name'), ':term')
)
->setParameter('term', '%' . strtolower($term) . '%');
return $qb->getQuery()->getArrayResult();
国家控制员
检查路由如何暴露给 options 参数并返回 JsonResponse。您也可以使用序列化程序。
/**
* Country controller.
*
* @Route("countries")
*/
class CountryController extends Controller
/**
* Lists all person entities.
*
* @Route("/", name="countries",options="expose"=true)
* @Method("GET")
*/
public function indexAction(Request $request)
$countryRepo = $this->getDoctrine()->getRepository('AppBundle:Country');
$data = $countryRepo->countriesSelect2($request->get('q', ''));
//$response = $this->get('serializer')->serialize($data,'json');
return new JsonResponse($data);
到目前为止一切顺利,现在好部分来了,让我们去配置我们的表单
人物类型
class PersonType extends AbstractType
/**
* @inheritdoc
*/
public function buildForm(FormBuilderInterface $builder, array $options)
$builder->add('name')
->add('country',EntityType::class,[
'class' => Country::class,
'attr' => [
'class' => 'select2', // the class to use with jquery
'data-source' => 'countries', //the exposed route name for data-soirce as attr
'data-allow-clear' => 'true'//another extra attr to customize
],
]);
/**
* @inheritdoc
*/
public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Person'
));
/**
* @inheritdoc
*/
public function getBlockPrefix()
return 'appbundle_person';
JS,显示select2
记住,select2 options 已经配置了属性,你只需要正确使用它们
$(document).ready(function ()
$('.select2').each(function () //using the select2 class
if (!$().select2) //checking the script
return;
$.fn.select2.defaults.set("theme", "bootstrap");//some theming if you want
$($(this)).select2(
placeholder: "Select",
width: 'auto',
allowClear: $(this).attr("data-allow-clear") ? $(this).attr("data-allow-clear") : true, //using my options from the form
ajax:
url: Routing.generate($(this).attr("data-source")), //here its the magic
dataType: 'json',
processResults: function (data)
//console.log(data);
return
results: $.map(data, function (item)
return
text: item.name, //you need to map this because the plugin accepts only id and text
id: item.id
)
;
);
);
);
之后,一切都完成了。当我测试我自己时,所有代码都在工作
希望对你有帮助!
【讨论】:
【参考方案3】:有一个不错的捆绑包:TetranzBundle
您可以像这样在 FormType 类中配置表单字段:
->add('product', Select2EntityType::class, [
'label'=>'product',
'required'=>true,
'mapped'=>true,
'multiple' => false,
'remote_route' => 'product_select2_ajax',
'class' => 'AppBundle:Product',
// 'property' => 'name',
'minimum_input_length' => 0,
'page_limit' => 10,
'allow_clear' => true,
'delay' => 250,
'cache' => true,
'cache_timeout' => 60000, // if 'cache' is true
'language' => 'pl',
'placeholder' => "select.product",
])
【讨论】:
【参考方案4】:试试这个:
<script type="text/javascript">
$(document).ready(function()
$('.select2').select2(); //instead $('select2').select2();
);
</script>
请参阅如何选择 a class in Jquery 和 basic usage exemple
【讨论】:
以上是关于在 Symfony 表单中启用 Select2Search的主要内容,如果未能解决你的问题,请参考以下文章
SonataProductBundle(symfony 2.8)而不是显示产品创建表单,而是出现“没有可用的对象类型”按钮
symfony2 中的 Ajax 表单提交,为没有 javascript 的用户提供优雅的降级