如何创建自定义表单字段类型

编辑本页

如何创建自定义表单字段类型

ob娱乐下载附赠Symfony数十种表单类型(在其他项目中称为“表单字段”)准备在应用程序中使用。但是,通常创建自定义表单类型来解决项目中的特定目的。

基于Symfony内置类型创建表单类型ob娱乐下载

创建表单类型的最简单方法是基于现有表单类型.假设您的项目显示了一个“运输选项”列表<选择>HTML元素。可以使用ChoiceType在哪里选择选项设置为可用传送选项的列表。

但是,如果在多个表单中使用相同的表单类型,则重复的列表选择每次使用它都会很快变得无聊。在本例中,更好的解决方案是基于ChoiceType.自定义类型的外观和行为类似ChoiceType但是选择列表已经填充了运输选项,所以您不需要定义它们。

表单类型是实现的PHP类FormTypeInterface,但你应该从AbstractType,它已经实现了该接口并提供了一些实用程序。按照惯例,它们存储在src /形式/类型/目录:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ / src /形式/类型/ ShippingType.php名称空间应用程序形式类型使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式扩展核心类型ChoiceType使用ob娱乐下载组件OptionsResolverOptionsResolverShippingType扩展AbstractType公共函数configureOptions(OptionsResolver解析器:无效解析器->setDefaults ([“选择”= > [“标准航运”= >“标准”加快运输的= >“加速”“优先航运”= >“优先”,],]);}公共函数getParent():字符串返回ChoiceType::类;}}

getParent ()告诉Symfob娱乐下载ony接受ChoiceType那么,作为一个起点configureOptions ()覆盖它的一些选项。的所有方法FormTypeInterface将在本文后面详细解释。)生成的表单类型是一个具有预定义选项的选择字段。

现在您可以在何时添加此表单类型创建Symfonyob娱乐下载形式:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src /形式/类型/ OrderType.php名称空间应用程序形式类型使用应用程序形式类型ShippingType使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式FormBuilderInterface订单类型扩展AbstractType公共函数buildForm(FormBuilderInterface构建器数组,选项:无效构建器/ /……->add (“运输”, ShippingType::类);}/ /……

这是所有。的航运表单字段将在任何模板中正确呈现,因为它重用了其父类型定义的模板逻辑ChoiceType.如果您愿意,还可以为您的自定义类型定义一个模板,本文后面将对此进行解释。

从头创建表单类型

有些表单类型是如此特定于您的项目,以至于它们不能基于任何类型现有表单类型因为他们太不一样了。考虑一个应用程序,希望以不同的形式重用以下字段集作为“邮政地址”:

如上所述,表单类型是实现的PHP类FormTypeInterface,尽管从扩展更方便AbstractType:

1 2 3 4 5 6 7 8 9 10 11
/ / src /形式/类型/ PostalAddressType.php名称空间应用程序形式类型使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式扩展核心类型FormType使用ob娱乐下载组件OptionsResolverOptionsResolverPostalAddressType扩展AbstractType/ /……

这些是表单类型类可以定义的最重要的方法:

buildForm ()
它将其他类型添加并配置到该类型中。这是同样的方法创建Symfonyob娱乐下载表单类
buildView ()
它设置在模板中呈现字段时需要的任何额外变量。
finishView ()
这个方法允许修改任何呈现的小部件的“视图”。如果您的表单类型包含许多字段,或者包含产生许多HTML元素的类型(例如。ChoiceType).对于任何其他用例,建议使用buildView ()代替。
configureOptions ()
它定义了在使用表单类型时可配置的选项,这些选项也是在buildForm ()而且buildView ()方法。选项继承自父类型和父类型扩展,但您可以创建任何您需要的自定义选项。
getParent ()

如果您的自定义类型是基于另一个类型(即它们共享一些功能),则添加此方法以返回原始类型的全限定类名。不要为此使用PHP继承。ob娱乐下载Symfony将调用所有表单类型方法(buildForm ()buildView ()等)和父类的类型扩展,然后再调用自定义类型中定义的扩展。

否则,如果您的自定义类型是从头构建的,则可以省略getParent ()

默认情况下,AbstractType类返回泛型FormTypetype,它是form组件中所有表单类型的根父元素。

定义表单类型

首先添加buildForm ()方法配置邮政地址中包含的所有类型。目前,所有字段都是类型TextType:

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
/ / src /形式/类型/ PostalAddressType.php名称空间应用程序形式类型使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式扩展核心类型TextType使用ob娱乐下载组件形式FormBuilderInterfacePostalAddressType扩展AbstractType/ /……公共函数buildForm(FormBuilderInterface构建器数组,选项:无效构建器->add (“addressLine1”, TextType::类,“帮助”= >“街道地址,邮政信箱,公司名称”,)->add (“addressLine2”, TextType::类,“帮助”= >“公寓,套房,单元,建筑物,楼层”,)->add (“城市”, TextType::类)->add (“状态”, TextType::类,“标签”= >“状态”,)->add (“zipCode”, TextType::类,“标签”= >“邮政编码”,]);}}

提示

运行以下命令验证表单类型是否成功注册到应用程序中:

1
PHP bin/控制台调试:表单

该表单类型可以在其他表单中使用,并且它的所有字段将在任何模板中正确呈现:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src /形式/类型/ OrderType.php名称空间应用程序形式类型使用应用程序形式类型PostalAddressType使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式FormBuilderInterface订单类型扩展AbstractType公共函数buildForm(FormBuilderInterface构建器数组,选项:无效构建器/ /……->add (“地址”, PostalAddressType::类);}/ /……

然而,自定义表单类型的真正威力是通过自定义表单选项(使它们更加灵活)和自定义模板(使它们看起来更好)实现的。

为表单类型添加配置选项

假设您的项目需要制作PostalAddressType有两种配置方式:

  • 除“地址行1”和“地址行2”外,某些地址应允许显示“地址行3”以存储扩展地址信息;
  • 有些地址应该能够将可能的状态限制在给定的列表中,而不是显示自由文本输入。

这是通过“表单类型选项”解决的,它允许配置表单类型的行为。选项定义在configureOptions ()方法,你可以使用所有的OptionsResolver组件特性定义、验证和处理它们的值:

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
/ / src /形式/类型/ PostalAddressType.php名称空间应用程序形式类型使用ob娱乐下载组件形式AbstractType使用ob娱乐下载组件形式扩展核心类型TextType使用ob娱乐下载组件OptionsResolver选项使用ob娱乐下载组件OptionsResolverOptionsResolverPostalAddressType扩展AbstractType/ /……公共函数configureOptions(OptionsResolver解析器:无效//当。时,定义可用选项及其默认值//当使用表单类型时没有显式配置解析器->setDefaults ([“allowed_states”= >“is_extended_address”= >]);//你也可以选择限制选项类型或类型(获取//为最终用户自动类型验证和有用的错误消息)解析器->setAllowedTypes (“allowed_states”, (“零”“字符串”“数组”]);解析器->setAllowedTypes (“is_extended_address”“bool”);//您可以选择将给定的值转换为//简化这些选项的进一步处理解析器->setNormalizer (“allowed_states”静态函数(选项选项如果= = =) {返回;}如果(is_string ()) {= (数组;}返回合二为一元素),元素));});}}

现在你可以在使用表单类型时配置这些选项:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
/ / src /形式/类型/ OrderType.php名称空间应用程序形式类型/ /……订单类型扩展AbstractType公共函数buildForm(FormBuilderInterface构建器数组,选项:无效构建器/ /……->add (“地址”, PostalAddressType::类,“is_extended_address”= >真正的“allowed_states”= > [“CA”“FL”“TX”),//在这个例子中,这个配置也是有效的:// 'allowed_states' => 'CA',]);}/ /……

最后一步是在构建表单时使用这些选项:

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
/ / src /形式/类型/ PostalAddressType.php名称空间应用程序形式类型/ /……PostalAddressType扩展AbstractType/ /……公共函数buildForm(FormBuilderInterface构建器数组,选项:无效/ /……如果真正的= = =选项“is_extended_address”) {构建器->add (“addressLine3”, TextType::类,“帮助”= >“扩展地址信息”]);}如果= = !选项“allowed_states”) {构建器->add (“状态”, ChoiceType::类,“选择”= >选项“allowed_states”)));}其他的构建器->add (“状态”, TextType::类,“标签”= >州/省/地区的]);}}}

创建表单类型模板

默认情况下,自定义表单类型将使用形式的主题在应用程序中配置。但是,对于某些类型,您可能更喜欢创建自定义模板,以便自定义它们的外观或HTML结构。

首先,在应用程序的任何地方创建一个新的Twig模板来存储用于呈现类型的片段:

1 2 3
{/形式/ custom_types.html #模板。树枝#}{#……在这里你将添加树枝代码…#}

然后,更新form_themes选项要在列表的开头添加这个新模板(第一个会覆盖其他文件):

  • YAML
  • XML
  • PHP
1 2 3 4 5
#配置/包/ twig.yaml枝:form_themes:-“形式/ custom_types.html.twig”-“……”

最后一步是创建将呈现类型的实际Twig模板。模板内容取决于应用程序中使用的HTML、CSS和JavaScript框架和库:

1 2 3 4 5 6 7 8 9 10 11
{/形式/ custom_types.html #模板。树枝#}{%postal_address_row %}{%孩子们,|过滤器(child => not child.render) %}<div“形式的班级”>{{form_label(child)}}{{form_widget(child)}}{{form_help(child)}}{{form_errors(child)}}div>{%endfor%}{%endblock%}

Twig块名的第一部分(例如。postal_address)来自类名(PostalAddressType->postal_address).控件可以控制这一点getBlockPrefix ()方法PostalAddressType.Twig块名的第二部分(例如。_row)定义要呈现的表单类型部分(行、小部件、帮助、错误等)。

关于表单主题的文章解释了表单片段命名规则在细节。下图显示了本例中定义的一些Twig块名称:

谨慎

当表单类的名称与任何内置字段类型匹配时,表单可能无法正确呈现。一个名为应用\ \ PasswordType形式将有相同的块名内置PasswordType并且不会被正确渲染。覆盖getBlockPrefix ()方法返回唯一的块前缀(例如:app_password)以避免碰撞。

将变量传递给表单类型模板

ob娱乐下载Symfony将一系列变量传递给用于呈现表单类型的模板。你也可以传递你自己的变量,这些变量可以基于表单定义的选项,也可以完全独立:

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
/ / src /形式/类型/ PostalAddressType.php名称空间应用程序形式类型使用学说ORMEntityManagerInterface使用ob娱乐下载组件形式FormInterface使用ob娱乐下载组件形式FormView/ /……PostalAddressType扩展AbstractType私人entityManager公共函数__construct(EntityManagerInterfaceentityManager->entityManager =entityManager;}/ /……公共函数buildView(FormView视图, FormInterface形式数组,选项:无效//直接将表单类型选项传递给模板视图->var (“isExtendedAddress”] =选项“is_extended_address”];//对数据库进行查询,以查找与邮政地址相关的可能通知(例如到//显示动态消息,例如“交付到XX和YY状态将在下周添加!”)视图->var (“通知”] =->entityManager->找到(“……”);}}

如果你在用默认的服务。yaml的配置,这个例子已经工作了!否则,创建服务对于此表单类和标记它form.type

添加的变量buildView ()在表单类型模板中可以作为任何其他常规的Twig变量:

12 3 4 5 6 7 8 9 10 11 12 13 14
{/形式/ custom_types.html #模板。树枝#}{%postal_address_row %}{#……#}{%如果isExtendedAddress %}{#……#}{%endif%}{%如果通知不是空%}<div“警报alert-primary”角色“警告”>{{notification}}div>{%endif%}{%endblock%}
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 6.0支持通过SensioLabs