自动完成<选择>
编辑本页自动完成<选择>
改变你的EntityType
,ChoiceType
或任何<选择>
元素转换为ajax支持的自动补全智能UI控件(利用汤姆选择):
安装
在你开始之前,确保你有欧宝娱乐app下载地址在你的应用中配置Symfony UX.
然后使用Composer和Symfony Flex安装包:欧宝娱乐app下载地址
1 2 3 4 5 6 7 8 9
$作曲家需要symfony/ux-a欧宝娱乐app下载地址utocomplete不要忘记安装JavaScript依赖项并进行编译$NPM install——force$NPM运行监视#或用纱线$纱线安装力$纱看
在表单中使用(不使用Ajax)
任何ChoiceType
或EntityType
可以转换为Tom select支持的UI控件,只需添加自动完成
选择:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// src/Form/AnyForm.php //…类AnyForm扩展AbstractType{公共函数buildForm(FormBuilderInterface $builder,数组$options): void {$builder ->add('food', EntityType::class, ['class' => food::class, '占位符' => '我们应该吃什么?”,+ 'autocomplete' => true,) - >添加(portionSize, ChoiceType::类,['选择' = >['选择一个份量 ' => '', ' 小' = > ' s ', '中' = > ' m ', '大' = > ' l ', '超大' = > ' xl”,“所有你能吃”= >“∞”),+ 'autocomplete' => true,]);}}
这就是你所需要的!当你刷新时,自动补全刺激控制器将把你的选择元素转换成一个智能UI控件:
表单中的用法(使用Ajax)
在前面的例子中,自动完成发生在“本地”:所有的选项都被加载到页面上并用于搜索。
如果你用的是EntityType
与许多可能的选项,一个更好的选择是通过AJAX加载选项。这也允许您搜索更多的字段,而不仅仅是“显示”文本。
要将字段转换为ajax支持的自动补全,需要创建一个新的“表单类型”类来表示字段。如果你安装了MakerBundle,你可以运行:
1
$PHP bin/console make:自动完成字段
或者,手动创建字段:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / src /形式/ FoodAutocompleteField.php/ /……使用欧宝娱乐app下载地址\组件\安全\核心\安全;使用欧宝娱乐app下载地址\用户体验\自动完成\形式\AsEntityAutocompleteField;使用欧宝娱乐app下载地址\用户体验\自动完成\形式\ParentEntityAutocompleteType;# (AsEntityAutocompleteField)类FoodAutocompleteField扩展AbstractType{公共函数configureOptions(OptionsResolver$解析器){$解析器->setDefaults ([“类”= >食物::类,“占位符”= >“我们该吃什么?”,//选择在搜索中使用的字段//如果没有传递,则使用*all*字段//'searchable_fields' => ['name'],//如果需要保护自动完成端点//'security' => 'ROLE_FOOD_ADMIN',/ /……任何其他正常的EntityType选项//例如query_builder, choice_label]);}公共函数getParent():字符串{返回ParentEntityAutocompleteType::类;}}
有3件重要的事情:
- 这门课需要
# (AsEntityAutocompleteField)
属性,以便自动补全系统注意到它。 - 的
getParent ()
方法必须返回ParentEntityAutocompleteType
. - 内部
configureOptions ()
,您可以使用任何正常配置字段EntityType
你需要的选项加上一些额外的选项(见表格选项参考).
创建这个类后,在你的表单中使用它:
12 3 4 5 6 7 8 9 10 11 12
// src/Form/AnyForm.php //…类AnyForm扩展了AbstractType{公共函数buildForm(FormBuilderInterface $builder,数组$options): void {$builder+ ->add('food', FoodAutocompleteField::class);}}
谨慎
类的第3个参数避免传递任何选项- > add ()
方法,因为在Ajax调用期间不会使用这些方法来获取结果。相反,在自定义类中包含所有选项(FoodAutocompleteField
).
恭喜你!你的EntityType
现在是ajax支持的!
造型Tom Select
在你的资产/ controllers.json
文件,您应该看到一行自动包含CSS文件的Tom Select,它将为您提供基本样式。
如果您正在使用Bootstrap,请设置tom-select.default.css
虚假和tom-select.bootstrap5.css
正确的:
1 2 3 4
"autoimport": {"tom-select/dist/css/tom-select.default.css": false, "tom-select/dist/css/tom-select.bootstrap5.css": true}
为了进一步定制,您可以使用自己的自定义CSS覆盖这些类,甚至可以控制Tom Select的各个部分如何呈现。看到汤姆选择渲染模板.
表格选项参考
所有ChoiceType
,EntityType
而且TextType
字段有以下新选项(这些也可以在自定义Ajax自动补全类中使用,例如:FoodAutocompleteField
从上面):
-
自动完成
(默认值:假
) -
设置为
真正的
激活您的选择
元素。 -
tom_select_options
(默认值:[]
) - 使用此选项设置自定义Tom选择选项.如果需要使用JavaScript设置选项,请参见扩展Tom Select.
-
options_as_html
(默认值:假
) -
设置为
真正的
如果你的选择(例如:choice_label
)包含HTML。如果您的自动补全是ajax支持的,则不需要。 -
autocomplete_url
(默认值:零
) -
通常你不需要手动设置。但是,你可以手动创建一个自动完成的ajax端点(例如自定义
ChoiceType
),然后设置它以将该字段更改为ajax支持的选择。 -
no_results_found_text
(默认:'No results found') -
当没有找到匹配结果时呈现。属性自动转换此消息
AutocompleteBundle
域。 -
no_more_results_text
(默认值:'No more results') -
显示匹配结果后,在列表底部呈现。属性自动转换此消息
AutocompleteBundle
域。
对于ajax支持的自动补全字段类(即getParent ()
返回ParentEntityAutocompleteType
),除了上述选项外,你还可以传递:
-
searchable_fields
(默认值:零
) -
将此设置为实体上的字段数组,在搜索匹配选项时应该使用该数组。默认情况下(即
零
),所有将搜索实体上的字段。关系字段也可以使用-例如。category.name
如果您的实体有类别
关系属性。 -
安全
(默认值:假
) -
保护Ajax端点。缺省情况下,端点可以被任何用户访问。为了确保安全,通过
安全
到字符串角色(例如。ROLE_FOOD_ADMIN
),以访问端点。或者,传递一个回调函数并返回真正的
授予权限或假
拒绝访问:1 2 3 4 5
使用欧宝娱乐app下载地址\组件\安全\核心\安全;“安全”= >函数(安全$安全):保龄球{返回$安全->isGranted (“ROLE_FOO”);}
-
filter_query
(默认值:零
) -
如果您想完全控制对“搜索结果”的查询,请使用此选项。这与
searchable_fields
:1 2 3 4 5 6 7 8
“filter_query”= >函数(QueryBuilder$qb、字符串$查询, EntityRepository$存储库){如果(!$查询){返回;}$qb->引入('entity.name LIKE:过滤器或entity.description LIKE:过滤器')->setParameter (“过滤”,“%”.$查询.“%”);}
-
max_results
(默认值:10) - 允许您控制自动自动完成端点返回的最大结果数。
-
预加载
(默认值:焦点
) -
设置为
焦点
打电话给负载
当控制接收焦点时执行。设置为真正的
打电话给负载
在控件初始化时(使用空搜索)。
使用TextType字段
以上所有选项也可以与TextType
字段:
12 3 4 5 6 7 8 9 10 11 12
$构建器/ /……->add (“标签”, TextType::类,“自动完成”= >真正的,“tom_select_options”= > [“创建”= >真正的,“createOnBlur”= >真正的,“分隔符”= >','),// 'autocomplete_url' => '…可选:自定义端点,见下面',]);
这<输入>
字段不会有任何自动完成,但是它将允许用户输入新的选项,并将它们视为框中的漂亮“项目”。在提交时,所有的选项-由分隔符
-将作为字符串发送。
你可以方法添加自动补全功能autocomplete_url
选项-但您可能需要创建自己的自定义自动完成端点.
扩展Tom Select
最简单的自定义方法汤姆选择是通过tom_select_options
传递给字段的选项。这对于像Tom Select这样简单的事情非常有效loadingClass
选项,该选项被设置为字符串。但是其他的选择,比如onInitialize
,必须通过JavaScript设置。
要做到这一点,创建一个自定义的刺激控制器,并侦听核心刺激控制器分派的一个或两个事件:
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/ /资产/控制器/ custom-autocomplete_controller.js进口{控制器}从“@hotwired /刺激”;出口默认的类扩展控制器{初始化(){这._onPreConnect =这._onPreConnect.bind (这);这._onConnect =这._onConnect.bind (这);} connect() {这.element.addEventListener (“自动完成:pre-connect”,这._onPreConnect);这.element.addEventListener (“自动完成:连接”,这._onConnect);} disconnect() {//当控制器断开连接时,应该总是删除监听器以避免副作用这.element.removeEventListener (“自动完成:pre-connect”,这._onConnect);这.element.removeEventListener (“自动完成:连接”,这._onPreConnect);} _onPreConnect(事件){// TomSelect未初始化-选项可以更改控制台. log (event.detail.options);//用于初始化TomSelect的选项event.detail.options.onChange =(价值) = >{/ /……};} _onConnect(事件){// TomSelect刚刚被初始化,您可以从事件中访问详细信息控制台. log (event.detail.tomSelect);// TomSelect实例控制台. log (event.detail.options);//初始化TomSelect的选项}}
请注意
扩展控制器应该立即加载(删除)/*刺激性取回:'lazy' */
),因此它可以侦听由原控制器分派的事件。
然后,更新你的字段配置以使用你的新控制器(它将被用于核心自动补全控制器之外):
1 2 3 4 5 6 7 8
$builder ->add('food', EntityType::class, ['class' => food::class, 'autocomplete' => true,+ 'attr' => [+ 'data-controller' => 'custom-autocomplete',+),])
或者,如果使用自定义Ajax类,则添加attr
选择您的configureOptions ()
方法:
1 2 3 4 5 6 7 8 9
公共函数configureOptions(OptionsResolver $resolver) {$resolver->setDefaults(['class' => Food::class,+ 'attr' => [+ 'data-controller' => 'custom-autocomplete',+),]);}
高级:创建一个自动补全器(没有表单)
如果不使用表单系统,可以创建Ajax自动完成端点,然后手动初始化刺激控制器.这只适用于Doctrine实体:参见手动使用刺激控制器如果你在自动补全实体以外的东西。
要公开端点,请创建实现的类欧宝娱乐app下载地址Symfony \ \自动完成用户体验\ EntityAutocompleterInterface
并将此服务标记为ux.entity_autocompleter
,包括别名
选择:
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 46 47
名称空间应用程序\自动完成;使用应用程序\实体\食物;使用学说\ORM\EntityRepository;使用学说\ORM\QueryBuilder;使用欧宝娱乐app下载地址\组件\DependencyInjection\属性\AutoconfigureTag;使用欧宝娱乐app下载地址\组件\安全\核心\安全;使用欧宝娱乐app下载地址\用户体验\自动完成\EntityAutocompleterInterface;# (AutoconfigureTag(“用户体验。实体_autocompleter', ['alias' => 'food'])]类FoodAutocompleter实现了EntityAutocompleterInterface{公共函数getEntityClass():字符串{返回食物::类;}公共函数createFilteredQueryBuilder(EntityRepository$存储库、字符串$查询):QueryBuilder{返回$存储库//别名“food”可以是任何东西->createQueryBuilder (“食物”)->引入(' name LIKE:搜索或food.description LIKE:搜索')->setParameter (“搜索”,“%”.$查询.“%”)//可能在所有情况下做一些自定义过滤/ / - - - - - - >引入('食物。isHealthy =:isHealthy')/ / - - - - - - > setParameter(‘健康’,真的);}公共函数getLabel(对象$实体):字符串{返回$实体->getName ();}公共函数getValue(对象$实体):字符串{返回$实体->getId ();}公共函数isGranted(安全$安全):保龄球{//详细信息请参见"security"选项返回真正的;}}
多亏了这个,你现在可以自动完成你的食物
实体通过ux_entity_autocomplete
路线和别名
路线通配符:
1
{{path('ux_entity_autocomplete', {alias: 'food'})}}
通常,您将把这个URL传递给刺激控制器,这将在下一节中讨论。
手动使用刺激控制器
这个库附带了一个刺激控制器,可以在任何情况下激活Tom Select选择
或输入
元素。这可以在Form组件之外使用。例如:
1 2 3 4
<选择的名字=“食物”{{兴奋剂控制器('symfony/ux-aut欧宝娱乐app下载地址ocomplete/autocomplete')}}>
就是这样!如果您希望通过Ajax自动完成选项,则传递一个url
值,如果您创建一个自定义自动完成:
1 2 3 4 5 6
<选择的名字=“食物”{{stimulus us_controller欧宝娱乐app下载地址('symfony/ux-autocomplete/autocomplete', {url: path('ux_entity_autocomplete', {alias: 'food'})})}}>
请注意
如果你想创建一个AJAX自动完成端点不对于实体,您需要手动创建它。唯一的要求是响应返回如下格式的JSON:
1 2 3 4 5 6
{“结果”: [{“价值”:“1”,“文本”:“披萨”}, {“价值”:“2”,“文本”:“香蕉”}]}
生成指向控制器的URL并将其传递给url
的值stimulus_controller ()
树枝函数,还是要的autocomplete_url
表单字段的选项。用户输入的搜索项作为查询参数传递查询
.
除了url
时,刺激控制器具有各种其他值,包括tomSelectOptions
.看到controller.ts文件获取完整的列表。
单元测试
为窗体编写单元测试时,使用TypeTestCase
类时,您考虑注册所需的类型扩展AutocompleteChoiceTypeExtension
像这样:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ /测试/形式/类型/ TestedTypeTest.php名称空间应用程序\测试\形式\类型;使用欧宝娱乐app下载地址\组件\形式\测试\TypeTestCase;使用欧宝娱乐app下载地址\用户体验\自动完成\形式\AutocompleteChoiceTypeExtension;类TestedTypeTest扩展TypeTestCase{受保护的函数getTypeExtensions():数组{返回[新AutocompleteChoiceTypeExtension ()];}/ /……你的测试}
向后兼容承诺
这个包旨在遵循与Symfony框架相同的向后兼容性承诺:欧宝娱乐app下载地址https://欧宝娱乐app下载地址www.oldmanjams.com/doc/current/contributing/code/bc.html