brunops/select24entity-bundle

此包已被废弃,不再维护。未建议替代包。

这是一个 Symfony2 扩展包,它将 Select2 集成为 Symfony 表单中标准实体字段的即插即用替代品。

安装: 347

依赖者: 0

建议者: 0

安全: 0

星标: 2

关注者: 0

分支: 100

开放问题: 0

类型:symfony-bundle

dev-master 2016-06-26 21:21 UTC

This package is not auto-updated.

Last update: 2023-04-01 11:10:24 UTC


README

分支描述

这个扩展包是 Tetranz 的 Select2Entity 的分支。

这个分支的目标是修改扩展包以模仿 Select2 的行为,这意味着将字段的激活和配置留给了用户在 JavaScript 中进行,除非是 AJAX 检索实体。

简介

这是一个 Symfony2 扩展包,它允许将流行的 Select2 组件用作 Symfony 表单中标准实体字段的即插即用替代品。

与标准 Symfony 实体字段(用 html select 渲染)相比,此扩展包提供的主要功能是列表通过远程 AJAX 调用检索。这意味着列表的大小几乎无限。唯一限制是数据库查询或远程 Web 服务检索数据的性能。

它支持单选和复选。如果表单正在编辑一个 Symfony 实体,则这些模式对应于一对多和多对多关系。在复选模式下,大多数人发现 Select2 用户界面比标准 select 标签(多个=true)更容易使用,后者需要使用 Ctrl 键等尴尬的操作。

该项目受到 lifo/typeahead-bundle 的启发,它使用 Bootstrap 2 中的 Typeahead 组件提供类似的功能。Select24Entity 可以在任何 Select2 可以安装的地方使用,包括 Bootstrap 3。

感谢 @ismailbaskin,我们现在有了 Select2 版本 4 兼容性。

截图

这是一个带有展开的单选字段列表的表单。

Single select example

这是一个带有展开的复选字段列表的表单。

Multiple select example

安装

首先必须安装并启用 Select2。

这些文件位于我的一些扩展包的 Resources/public/js 和 Resources/public/css 文件夹中,然后包含在我的主布局.html.twig 文件中。

或者,您可以使用以下两行代码从 CloudFlare CDN 加载 select2.js 和 select2.css 的精简版本:https://select2.github.io。确保脚本标签在 jQuery 加载之后,可能在页面页脚。

  • brunops/select24entity-bundle 添加到您的项目 composer.json 的 "requires" 部分中
{
  // ...
  "require": {
    // ...
    "brunops/select24entity-bundle": "dev-master"
  }
}

请注意,这仅适用于 Select2 版本 4。

  • 在项目根目录中运行 php composer.phar update brunops/select24entity-bundle
  • 更新您的项目 app/AppKernel.php 文件,并将此扩展包添加到 $bundles 数组中
$bundles = array(
  // ...
  new Brunops\Select24EntityBundle\BrunopsSelect24EntityBundle(),
);
  • 更新您的项目 app/config.yml 文件,以提供全局 twig 表单模板
twig:
  form_themes:
    - 'BrunopsSelect24EntityBundle:Form:fields.html.twig'
  • 在页面上加载JavaScript。最简单的方法是将以下内容添加到布局文件中。不要忘记运行 console assets:install。或者,可以使用Assetic做更复杂的事情。
<script src="{{ asset('bundles/brunopsselect24entity/js/select24entity.js') }}"></script>

如何使用

以下适用于Symfony 2.8(可能也适用于Symfony 3,但尚未测试)。

Select24Entity使用简单。在一个表单类型类的buildForm方法中,指定 Select24EntityType::class 作为类型,而不是使用 entity:class

以下是一个示例

$builder
  ->add('country', Select24EntityType::class, [
    'multiple' => true,
    'remote_route' => 'brunops_test_default_countryquery',
    'class' => '\Brunops\TestBundle\Entity\Country',
    'primary_key' => 'id',
    'text_property' => 'name',
    'minimum_input_length' => 2,
    'page_limit' => 10,
    'allow_clear' => true,
    'delay' => 250,
    'cache' => true,
    'cache_timeout' => 60000, // if 'cache' is true
    'language' => 'en',
    'placeholder' => 'Select a country',
  ])

将此代码放在包含表单类型类的文件顶部

use Brunops\Select24EntityBundle\Form\Type\Select24EntityType;

在将要使用字段的模板中,您必须像使用任何Select2字段一样激活它,例如使用以下代码

$('.select24entity').select24entity();

在括号内,您可以传递任何Select2可以接受的选项。

选项

如果没有设置,将使用默认值。

  • class 是您的实体类。必需的
  • primary_key 是用于唯一识别实体的属性的名称。默认为 'id'
  • text_property 这是用于检索现有数据的实体属性。如果省略text_property,则将实体转换为字符串。这要求它必须有 __toString() 方法。
  • multiple 对于多选(多对多)为真。对于单选(多对一)为假。
  • minimum_input_length 是在搜索发生之前需要按下的键的数量。默认为2。
  • page_limit 这作为查询参数传递给远程调用。它旨在用于限制返回列表的大小。默认为10。
  • allow_clear 如果为真,Select2将显示一个小的x以清除值。默认为false。
  • delay 键入后触发另一个AJAX请求的毫秒延迟。默认为250 ms。
  • placeholder 占位符文本。
  • language i18n语言代码。默认为en。
  • cache 启用AJAX缓存。对于每个查询的'term',结果将被缓存。
  • cache_timeout 缓存查询的毫秒数。设置为0将导致缓存从不超时 (60000 = 60 seconds)
  • transformer 如果需要以下描述的灵活性,则指定自定义转换器的完全限定类名。

远程查询的URL可以通过两种方式之一提供:remote_route 是Symfony路由。可以可选地指定 remote_params 以提供参数。或者,可以使用 remote_path 直接指定URL。

默认值可以在您的app/config.yml文件中更改,格式如下。

brunops_select24entity:
  minimum_input_length: 2
  page_limit: 8
  allow_clear: true
  delay: 500
  language: fr
  cache: false
  cache_timeout: 0

AJAX响应

控制器应返回以下格式的JSON数组。属性必须是idtext

[
  { id: 1, text: 'Displayed Text 1' },
  { id: 2, text: 'Displayed Text 2' }
]

Select2可标记字段

如果您想使用 Select2标签字段,您需要做两件事

  1. 将字段激活为带标签的属性设置为true
$(".select24entity").select24entity({
  tags: true
});
  1. 定义一个类似以下 数据转换器
// Transform should return the same thing as the argument, Select24Entity will do the job.
public function transform($entities) {
  return $entities;
}

// This data transformer will receive the entities already parsed through the Select24Entity data transformer, alongside a key 'toCreate' if there is something to create.
public function reverseTransform($entities) {
  if ($entities->containsKey('toCreate')) {
    $toCreate = $entities->get('toCreate');
    $entities->remove('toCreate'); // We need to remove the key so that the Symfony Form component won't try to read it as if it was of same type of all other $entities
    // Simple loop to create the entities. Don't forget to persist them!
    foreach ($toCreate as $value) {
      if ($this->is_valid($value)) { // Some validation
        $newEntity = $this->createAndPersistEntity($value); // Create the entity object and persist it
        $entities->add($newEntity); // Add the entity to the ArrayCollection
      }
    }
  }
  return $entities;
}

##自定义选项文本## 如果您需要更灵活地显示每个选项的文本,例如显示实体中的几个字段的值或在其中显示图片,您可以定义自己的自定义转换器。您的转换器必须实现DataTransformerInterface。最简单的方法可能是扩展EntityToPropertyTransformer或EntitiesToPropertyTransformer并重新定义transform()方法。这样,您可以返回任何内容作为text,而不仅仅是单个实体属性。

以下是一个示例,它返回国家名称和大陆(国家实体中的两个不同属性)

$builder
  ->add('country', Select24EntityType::class, [
    'multiple' => true,
    'remote_route' => 'brunops_test_default_countryquery',
    'class' => '\Brunops\TestBundle\Entity\Country',
    'transformer' => '\Brunops\TestBundle\Form\DataTransformer\CountryEntitiesToPropertyTransformer',
  ]);

在transform中设置数据数组如下

$data[] = array(
  'id' => $country->getId(),
  'text' => $country->getName().' ('.$country->getContinent()->getName().')',
);

您的自定义转换器和相应的Ajax控制器应该以以下格式返回数组

[
  { id: 1, text: 'United Kingdom (Europe)' },
  { id: 1, text: 'China (Asia)' }
]

###模板化###

如果您需要在Select2中使用模板化,可以考虑以下示例,它显示每个选项旁边的国家旗帜。

您的自定义转换器应该返回如下数据

[
  { id: 1, text: 'United Kingdom (Europe)', img: 'images/flags/en.png' },
  { id: 2, text: 'China (Asia)', img: 'images/flags/ch.png' }
]

您需要定义自己的JavaScript函数select24entityAjax,它扩展了原始的select24entity并显示带图片的自定义模板

$.fn.select24entityAjax = function(action) {
  var action = action || {};
  var template = function (item) {
    var img = item.img || null;
    if (!img) {
      if (item.element && item.element.dataset.img) {
        img = item.element.dataset.img;
      } else {
        return item.text;
      }
    }
    return $(
      '<span><img src="' + img + '" class="img-circle img-sm"> ' + item.text + '</span>'
    );
  };
  this.select24entity($.extend(action, {
    templateResult: template,
    templateSelection: template
  }));
  return this;
};
$('.select2entity').select24entityAjax();

此脚本将为所有具有类select24entity的元素添加功能,但如果未传递img,它将像原始的select24entity一样工作。

您还需要覆盖以下模板中的以下块

{% block brunops_select24entity_widget_select_option %}
  <option value="{{ label.id }}" selected="selected"
    {% for key, data in label %}
      {% if key not in ['id', 'text'] %} data-{{ key }}="{{ data }}"{% endif %}
    {% endfor %}>
    {{ label.text }}
  </option>
{% endblock %}

此块将所有所需的数据添加到JavaScript函数select24entityAjax中,如数据属性。在这种情况下,我们传递了data-img

##嵌入集合表单## 如果您使用嵌入式集合表单data-prototype在您的表单中添加新元素,您将需要以下JavaScript,它将监听添加元素.select24entity

$('body').on('click', '[data-prototype]', function(e) {
  $(this).prev().find('.select24entity').last().select24entity();
});