自动完成<选择>

编辑本页

自动完成<选择>

改变你的EntityTypeChoiceType任何<选择>元素转换为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——forceNPM运行监视#或用纱线纱线安装力纱看

在表单中使用(不使用Ajax)

任何ChoiceTypeEntityType可以转换为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件重要的事情:

  1. 这门课需要# (AsEntityAutocompleteField)属性,以便自动补全系统注意到它。
  2. getParent ()方法必须返回ParentEntityAutocompleteType
  3. 内部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的各个部分如何呈现。看到汤姆选择渲染模板

表格选项参考

所有ChoiceTypeEntityType而且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”= >函数(QueryBuilderqb、字符串查询, 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
名称空间应用程序自动完成使用应用程序实体食物使用学说ORMEntityRepository使用学说ORMQueryBuilder使用欧宝娱乐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下载地址用户体验自动完成形式AutocompleteChoiceTypeExtensionTestedTypeTest扩展TypeTestCase受保护的函数getTypeExtensions()数组返回AutocompleteChoiceTypeExtension ()];}/ /……你的测试

向后兼容承诺

这个包旨在遵循与Symfony框架相同的向后兼容性承诺:欧宝娱乐app下载地址https://欧宝娱乐app下载地址www.oldmanjams.com/doc/current/contributing/code/bc.html

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。