【问题标题】:Enable Select2Search in Symfony form在 Symfony 表单中启用 Select2Search
【发布时间】: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 会出现一些错误

标签: forms symfony jquery-select2


【解决方案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 Jquerybasic usage exemple

        【讨论】:

          猜你喜欢
          • 2011-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多