对称 / symfony-collection
一个jQuery插件,用于管理从Symfony集合中添加、删除和移动元素
This package is auto-updated.
Last update: 2024-09-20 22:53:27 UTC
README
一个jQuery插件,用于管理从Symfony集合中添加、删除和移动元素
使用Symfony提供的data-prototype
管理集合并不困难。但是,在使用了几次集合后,我觉得创建一个jQuery插件来做这项工作很有用。
特别是当你需要你的元素可以上下移动或添加到特定位置时:由于表单将通过字段名称进行操作,我们应该交换字段内容或字段名称,而不是移动字段本身来完成这项工作。这在JavaScript中并不友好,因此这个插件也旨在处理这种情况。
在线演示
此插件的演示可在以下地址实时查看:http://symfony-collection.fuz.org
演示源代码在此:https://github.com/ninsuo/symfony-collection-demo
安装
此插件包含2个文件
-
jQuery插件本身,应该位于您的资源文件中
-
一个用于简化使用的twig表单主题,应该位于您的视图文件中
使用Composer安装
要自动化插件下载和安装,编辑composer.json并添加
"require": { ... "ninsuo/symfony-collection": "dev-master" }, "scripts": { "post-install-cmd": [ ... "Fuz\\Symfony\\Collection\\ScriptHandler::postInstall" ], "post-update-cmd": [ ... "Fuz\\Symfony\\Collection\\ScriptHandler::postUpdate" ] }
文件将自动安装到以下位置
-
symfony-collection表单主题将安装在
app/Resources/views
-
symfony-collection jQuery插件将安装在
web/js
。
提示
-
将
dev-master
替换为当前稳定版本。 -
如果希望利用资源文件优化,请在Symfony的installAssets之前放置脚本处理器。
-
将
app/Resources/views/jquery.collection.html.twig
和web/js/jquery.collection.js
添加到您的.gitignore
如果您更喜欢手动安装插件,可以使用
composer require ninsuo/symfony-collection
您需要将以下文件移动到您的资源文件中
-
vendor/ninsuo/symfony-collection/jquery.collection.js
(例如,在web/js
中) -
vendor/ninsuo/symfony-collection/jquery.collection.html.twig
(例如,在app/Resources/views
中)
使用npm安装
npm install ninsuo/symfony-collection
您需要将以下文件移动到您的资源文件中
node_modules/symfony-collection/jquery.collection.js
(例如,在web/js
中)。node_modules/symfony-collection/jquery.collection.html.twig
(例如,在app/Resources/views
中)。
使用Bower安装
bower install ninsuo/symfony-collection
您需要将以下文件移动到您的资源文件中
bower_components/symfony-collection/jquery.collection.js
(例如,在web/js
中)。bower_components/symfony-collection/jquery.collection.html.twig
(例如,在app/Resources/views
中)。
基本用法
一个简单的集合
您的集合类型应该包含prototype
、allow_add
、allow_remove
选项(当然取决于您需要的按钮)。以及一个用作选择器的类,用于运行集合插件。
->add('myCollection', 'collection', array ( // ... 'allow_add' => true, 'allow_remove' => true, 'prototype' => true, 'attr' => array( 'class' => 'my-selector', ), ))
然后,应用给定自定义主题后渲染您的表单
{% form_theme myForm 'jquery.collection.html.twig' %} {{ form(myForm) }}
最后,将以下代码放置在页面底部。
<script src="{{ asset('js/jquery.js') }}"></script> <script src="{{ asset('js/jquery.collection.js') }}"></script> <script type="text/javascript"> $('.my-selector').collection(); </script>
使用表单主题
大多数情况下,您需要创建一个表单主题,这将帮助您以优雅的方式渲染集合及其子元素。
- 在您的表单类型中,覆盖
getBlockPrefix()
方法并返回一个好名字。
// Fuz/AppBundle/Form/AddressType.php <?php namespace Fuz\AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class AddressType extends AbstractType { // ... public function getBlockPrefix() { return 'AddressType'; } }
- 在你的表单主题中,你只需要使用相同的名称(
{% block AddressType_XXX %}
)。将XXX
替换为widget
、error
或row
,具体取决于你想做什么(更多信息请参阅Symfony文档)。
{# FuzAppBundle:Advanced:addresses-theme.html.twig #} {% block AddressType_row %} <div class="col-md-3"> {{ form_label(form) }} {{ form_errors(form) }} {{ form_widget(form) }} </div> {% endblock %} {% block AddressType_widget %} {{ form_widget(form) }} <br/> <p class="text-center"> <a href="#" class="collection-up btn btn-default"><</a> <a href="#" class="collection-remove btn btn-default">-</a> <a href="#" class="collection-add btn btn-default">+</a> <a href="#" class="collection-down btn btn-default">></a> </p> {% endblock %}
然后,使用以下方法使用两个表单主题:
{% form_theme myForm 'FuzAppBundle:Advanced:addresses-theme.html.twig' 'jquery.collection.html.twig' %}
在演示网站的高级菜单中有很多使用表单主题的示例,不要犹豫去查看它们。
始终将jquery.collection.html.twig
表单主题放在其他你使用的主题下方,以避免设置被覆盖。
使用Doctrine,并在字段中明确存储位置
集合不过是一系列对象,因此默认情况下,此插件会在这个数组中移动元素位置。例如,如果你在你的集合中有A、B和C,并且将B向上移动,它将包含B、A、C。
但是当Doctrine持久化你的集合时,它将保留现有的实体,并简单地更新它们的内容。例如,如果你有一个包含A、B、C的集合,ID分别为1、2和3,你最终会得到一个包含B、A、C的集合,但ID仍然是1、2和3。
在大多数情况下,这不是问题。但是,如果你在每个集合元素上都有其他关联,你永远不应该断开ID和值的链接。你将在数据库表上使用一个位置字段,并管理位置。
例如:
/** * @ORM\Column(name="position", type="integer") */ private $position;
此插件支持这种情况;你需要在你的表单中创建一个position
字段(类型为隐藏),并将其映射到你的实体上,并给它一个作为选择器的类。
$builder->add('position', HiddenType::class, [ 'attr' => [ 'class' => 'my-position', ], ]);
然后,使用position_field_selector
选项将其提供给插件。
$('.my-selector').collection({ position_field_selector: '.my-position' });
同一页面上有多个集合
如果你想在同一页面上创建多个集合,你需要更改集合前缀,以便插件能够触发正确的操作以针对正确的集合。
例如:
$('.collectionA').collection({ 'prefix': 'first-collection' }); $('.collectionB').collection({ 'prefix': 'second-collection' });
然后,如果你想编辑这些集合的表单主题,例如,你需要在添加按钮上将collection-add
替换为first-collection-add
。
<a href="#" class="first-collection-add btn btn-default"> <span class="glyphicon glyphicon-plus-sign"></span> </a>
请参阅此示例以获取一个工作示例。
选项
自定义渲染链接(演示)
你可以通过设置up
、down
、add
、remove
和duplicate
选项来自定义显示的链接。
默认值是:
$('.collection').collection({ up: '<a href="#">▲</a>', down: '<a href="#">▼</a>', add: '<a href="#">[ + ]</a>', remove: '<a href="#">[ - ]</a>', duplicate: '<a href="#">[ # ]</a>' });
你还可以使用以下类:
collection-add
用于添加按钮collection-remove
用于移除按钮collection-up
用于向上移动按钮collection-down
用于向下移动按钮collection-duplicate
用于复制按钮
以及
collection-action
用于上述任何操作collection-action-disabled
与上述相同,但按钮被禁用时(例如,顶部没有“向上”)
请注意,可以使用prefix
选项更改collection
前缀。
禁用链接(演示)
你可以通过使用allow_up
、allow_down
、allow_add
、allow_remove
和allow_duplicate
选项来禁用一些按钮。默认情况下,除了duplicate
之外的所有按钮都启用。
例如,如果你不希望你的元素可以上下移动,使用:
$('.collection').collection({ allow_up: false, allow_down: false });
如果你使用的是给定的表单主题,allow_add
、allow_remove
和allow_duplicate
会自动根据你的表单类型配置设置。
设置集合中元素的最小和最大值(演示)
你可以通过使用min
选项来设置集合中允许的最小元素数量。默认情况下,它被禁用(设置为0)。
$('.collection').collection({ min: 0 });
您可以通过使用 max
选项来设置集合中允许的最大元素数量。默认情况下,它设置为 100。
$('.collection').collection({ max: 100 });
您可以使用至少创建的元素数初始化集合(即使它们在数据对象中不存在) (演示)。
$('.collection').collection({ init_with_n_elements: 3 });
底部只有一个添加按钮 (演示)
如果您希望在集合底部只有一个 add
按钮而不是每个集合元素旁边都有一个添加按钮,请使用 add_at_the_end
选项
$('.collection').collection({ add_at_the_end: true });
自定义添加按钮位置 (演示)
如果您想为添加按钮设置一个特定的位置(不是靠近每个集合元素,也不是在集合底部),则可以使用 custom_add_location
选项。
JS
$('.collectionA').collection({ custom_add_location: true });
HTML
<button data-collection="collectionA" class="collection-action collection-add btn btn-success" >Add element to collection</button>
隐藏无用的按钮 (演示)
默认情况下,向上移动
按钮在第一个元素上隐藏,向下移动
按钮在最后一个元素上隐藏。您可以通过将 hide_useless_buttons
设置为 false
来使它们仍然出现。这可能在您想使用 CSS 美化它们时很有用。
$('.collection').collection({ hide_useless_buttons: true });
事件 (演示)
有 before_*
和 after_*
选项,允许您在集合中添加、删除或移动元素之前和之后放置回调函数。
-
before_up
、before_down
、before_add
和before_remove
在修改集合之前被调用。如果回调函数返回false
,则修改将被取消,如果返回true
或undefined
,则继续进行。 -
after_up
、after_down
、after_add
和after_remove
在修改集合后被调用。如果回调函数返回false
,则修改将被撤销。 -
before_init
和after_init
在初始化集合时被调用。不需要返回值。
回调函数接收两个参数
-
collection
引用包含您整个集合的 div(symfony2 字段) -
element
是已添加(或移动/删除)的集合中的元素
$('.collection').collection({ after_add: function(collection, element) { // automatic backup or whatever return true; } });
不使用表单主题使用插件 (演示)
表单主题旨在在激活插件时减少所需选项的数量。当您处理表单集合的集合时,这非常有用。但您也可以手动进行,使用以下等效项。
$('.my-selector').collection({ prototype_name: '{{ myForm.myCollection.vars.prototype.vars.name }}', allow_add: false, allow_remove: false, name_prefix: '{{ myForm.myCollection.vars.full_name }}' });
请注意,只有 name_prefix
选项是必需的,所有其他选项都有默认值。
淡入 & 淡出支持 (演示)
默认情况下,在添加或删除元素时,fade
动画会使元素移动更平滑。您仍然可以通过使用 fade_in
和 fade_out
选项来禁用此选项。
$('.my-selector').collection({ fade_in: true, fade_out: true });
拖 & 放支持 (演示)
如果您正在使用 Jquery UI 并在您的应用程序中有可用的 sortable
组件,则 drag_drop
选项将自动启用,并允许您使用拖 & 放来更改元素位置。您可以通过显式将 drag_drop
选项设置为 false 来禁用此行为。
如有需要,您可以通过使用drag_drop_options
选项,通过覆盖传递给jQuery.ui.sortable
的选项来自定义sortable
。
默认情况下,您的集合使用以下选项初始化
$('.collection').collection({ drag_drop: true, drag_drop_options: { placeholder: 'ui-state-highlight' } });
请注意,您不应覆盖start
和update
回调函数,因为它们由该插件使用,有关详细信息,请参阅下面的高级使用中的drag_drop_start
和drag_drop_update
选项。
更改子选择器
默认情况下,Symfony将集合的每个元素写入位于集合本身下面的div中。因此,此插件将> div
视为获取集合元素的默认值。但是,您可能需要将集合的每个元素显示在表中,因此您可以更改此值。
$('.collection').collection({ elements_selector: '> div' });
您可以使用> tr
、thead > tr
或更具体地使用tr.item
或仅使用.item
(如果您的项目表单主题的顶部设置了class="item"
)。目标是无论标记如何都能引用集合中的每个项目。
更改父选择器
为了能够将元素添加到集合中,此插件应该知道将包含它们的dom对象。
默认情况下,您的集合元素将位于您的集合下方,例如
<div id="collection"> <div id="child_0">(...)</div> <div id="child_1">(...)</div> <div id="child_2">(...)</div> </div>
但是,您可能需要将元素放置在DOM中更深的位置,例如当您在表中放置元素时
<table id="collection"> <tbody> <tr id="child_0">(...)</tr> <tr id="child_1">(...)</tr> <tr id="child_2">(...)</tr> </tbody> </table>
在此示例中,父选择器应为table.collection tbody
。
请注意,您可以在elements_parent_selector
中使用%id%
,它将被自动替换为集合的ID。这在处理嵌套集合时尤其有用。
示例
$('.collection').collection({ // ... children: [{ // ... elements_parent_selector: '%id% tbody' }] });
默认值
$('.collection').collection({ elements_parent_selector: '%id%' // will be the collection itself });
不要更改字段名称
Symfony使用字段名称对集合进行排序,而不是每个元素在DOM中的位置。因此,默认情况下,如果您在中间删除一个元素,所有后续元素将减少索引1(field[3]
将变为field[2]
,依此类推),如果您在中间添加一些元素,所有后续元素将看到它们的索引增加以为新元素腾出空间。
使用此实现,您在点击“向上移动”和“向下移动”等操作时可以确保保持正确的位置。但在某些情况下,您可能不希望覆盖索引,最可能是为了维护Doctrine关系。
将preserve_names
选项设置为true
以从不触摸字段名称。但请注意,此选项将禁用allow_up
、allow_down
、drag_drop
选项并将add_at_the_end
设置为true。
默认值
$('.collection').collection({ preserve_names: false });
更改操作容器标签
默认情况下,没有表单主题,所有操作都放在一个<div>
中。您可以通过设置action_container_tag
选项来覆盖此设置,例如,如果您想将操作放在一个<td>
中。
默认值
$('.collection').collection({ action_container_tag: 'div' });
高级使用
更改操作的顺序(演示)
默认情况下
add
、向上移动
、向下移动
和remove
按此顺序位于每个集合元素的下方- 使用
add_at_the_bottom
选项可以将add
按钮放在集合的底部
您可以通过在表单主题的任何位置手动创建按钮来更改这些按钮的位置。
只要具有一个操作类,您就可以使用任何自定义可点击元素
collection-add
用于add
按钮collection-remove
用于remove
按钮collection-up
用于move up
按钮collection-down
用于move down
按钮
警告:collection
来自prefix
选项:如果您更改插件的prefix,您也应该更改此类。
示例
如果我们有一组文本字段,并且想要在每个值右侧而不是下方显示操作,我们将使用类似以下的方法
{% block MyType_label %}{% endblock %} {% block MyType_errors %}{% endblock %} {% block MyType_widget %} <div class="row"> <div class="col-md-8"> {{ form_widget(form.value) }} </div> <div class="col-md-2"> <a href="#" class="collection-up btn btn-default">Move up</a> <a href="#" class="collection-down btn btn-default">Move Down</a> </div> <div class="col-md-2"> <a href="#" class="collection-remove btn btn-default">Remove</a> <a href="#" class="collection-add btn btn-default">Add</a> </div> </div> {% endblock %}
注意:在启用插件时,不要忘记设置 add
选项,因为如果您的集合被清空,插件将根据插件的配置生成一个 add
按钮。
提示:当 add
按钮被放入集合的元素中时,会在点击的元素旁边创建一个新的元素,而不是在集合的末尾。
高级拖放支持 (演示)
如果您需要在您的集合中监听来自 jQuery.ui.sortable
的 start
和/或 update
事件,您不应该在 drag_drop_options
中覆盖 start
和 update
选项,而应该使用内置的 drag_drop_start
和 drag_drop_update
选项。
$('.collection').collection({ drag_drop_start: function (event, ui, elements, element) { // ... }, drag_drop_update: function (event, ui, elements, element) { // ... } });
注意
event
和ui
来自jQuery.ui.sortable
的start
回调。elements
包含受影响的集合中所有的元素element
是集合中移动的元素- 如果您的回调返回 false,则位置更改将被取消/撤销。
集合的集合 (演示)
此插件具有管理表单集合集合的能力,但为了避免冲突,您应该
在您的表单类型中
- 为每个集合设置一个唯一的
prototype_name
选项和选择器类
->add('collections', 'collection', array ( 'type' => 'collection', 'label' => 'Add, move, remove collections', 'options' => array ( 'type' => 'text', 'label' => 'Add, move, remove values', 'options' => array ( 'label' => 'Value', ), 'allow_add' => true, 'allow_remove' => true, 'prototype' => true, 'prototype_name' => '__children_name__', 'attr' => array ( 'class' => "child-collection", ), ), 'allow_add' => true, 'allow_remove' => true, 'prototype' => true, 'prototype_name' => '__parent_name__', 'attr' => array ( 'class' => "parent-collection", ), ))
在插件选项中
-
使用一个唯一的集合前缀,因此点击集合的
add
按钮将向正确的集合添加一个项目 -
在
children
选项的selector
属性中定义子选择器(必须选择子集合的根节点)
$('.parent-collection').collection({ prefix: 'parent', children: [{ selector: '.child-collection', prefix: 'child' // ... }] });