Я хочу включить поиск select 2 в моей форме Symfony, что я пробовал до сих пор:
В моем классе формы у меня есть это:
->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
@Noob, пожалуйста, обновите свой вопрос, указав все параметры и ошибки, чтобы я мог вам помочь. Для меня он работает отлично. Пожалуйста, обновите свой вопрос с помощью Entity, формы, преобразователя данных, если он у вас есть, и представления, а также добавьте ошибки
ты проверил мой последний ответ? то же самое для множественного выбора. вам нужно только установить опцию multiple true в форме и закодировать, чтобы предоставить правильную информацию о сопоставлении




Основная причина в том, что поле создается после того, как вы пытаетесь настроить его таргетинг, с помощью этой строки:
{{ 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, чтобы использовать класс, который вы добавили в поле в построителе форм. Таким образом вы управляете выбранным полем, на которое хотите настроить таргетинг.
Для этого есть хорошая связка: ТетранцБандл
Вы можете настроить поле формы в классе 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",
])
Вы запускаете компоненты select2 без конфигурации, поэтому он не знает, где находится источник данных.
Перед тем, как приступить к кодированию, необходимо установить и настроить FOSJsRoutingBundle. Этот пакет поможет вам получить доступ к маршрутам ajax.
Для полностью настроенной синхронизации symfony-forms ~ select2 вы можете сделать что-то вроде этого.
Entity Person
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;
}
}
Entity Country
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;
}
}
Country repository
класс 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();
}
}
Country controller
Проверьте, как маршрут предоставляется параметру 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);
}
}
Пока все хорошо, теперь переходим к хорошим деталям, давайте настроим нашу форму
PersonType
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, showing the select2
Помните, что вы уже настроили select2 опции с атрибутами, вам просто нужно правильно их использовать
$(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.info(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
}
})
};
}
}
});
});
});
после этого все готово. Весь код работает, пока я тестировал себя
Надеюсь, поможет!
Попробуй это :
<script type = "text/javascript">
$(document).ready(function() {
$('.select2').select2(); //instead $('select2').select2();
});
</script>
см. Как выбрать класс в JQuery и пример базового использования
Это точное содержание вашего шаблона или вы просто разместили соответствующие части?