如何创建自定义表单字段类型
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 4.3,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
如何创建自定义表单字段类型
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娱乐下载\组件\OptionsResolver\OptionsResolver;类ShippingType扩展AbstractType{公共函数configureOptions(OptionsResolver$解析器){$解析器->setDefaults ([“选择”= > [“标准航运”= >“标准”,加快运输的= >“加速”,“优先航运”= >“优先”,],]);}公共函数getParent(){返回ChoiceType::类;}}
的configureOptions ()
方法(本文后面将解释)定义可为表单类型配置的选项,并设置这些选项的默认值。
的getParent ()
方法定义哪种表单类型用作此类型的基。在本例中,类型从ChoiceType
以重用该字段类型的所有逻辑和呈现。
请注意
PHP类扩展机制和Symfony表单字段扩展机制是不同的。ob娱乐下载返回的父类型getParent ()
是Symfonyob娱乐下载用来构建和管理字段类型的工具。使PHP类从AbstractType
仅仅是实现所需的一种方便的方式吗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娱乐下载\组件\OptionsResolver\OptionsResolver;类PostalAddressType扩展AbstractType{/ /……}
当一个表单类型没有从另一个特定类型扩展时,不需要实现getParent ()
方法(Symfoob娱乐下载ny将使类型从泛型扩展FormType,它是所有其他类型的父类型)。
这些是表单类型类可以定义的最重要的方法:
-
buildForm ()
- 它将其他类型添加并配置到该类型中。这是同样的方法创建Symfonyob娱乐下载表单类.
-
buildView ()
- 它设置在模板中呈现字段时需要的任何额外变量。
-
configureOptions ()
-
它定义了在使用表单类型时可配置的选项,这些选项也是在
buildForm ()
而且buildView ()
方法。 -
finishView ()
-
当创建包含许多字段的表单类型时,此方法允许修改任何这些字段的“视图”。对于任何其他用例,建议使用
buildView ()
方法。
定义表单类型
首先添加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娱乐下载\组件\形式\FormBuilderInterface;类PostalAddressType扩展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娱乐下载\组件\OptionsResolver\OptionsResolver;类PostalAddressType扩展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
/ / 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
/ / 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 %}{%为孩子在形式上。如果不是孩子,那就是孩子。呈现%}<div类=“形式的班级”>{{form_label(child)}}{{form_widget(child)}}{{form_help(child)}}{{form_errors(child)}}div>{%endfor%}{%endblock%}
请注意
ob娱乐下载Symfony 4.2不支持调用FormRenderer: searchAndRenderBlock
对于已经呈现的字段。这就是为什么前面的示例包含...如果不是child.render
声明。
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
/ / src /形式/类型/ PostalAddressType.php使用学说\ORM\EntityManagerInterface;/ /……类PostalAddressType扩展AbstractType{私人$entityManager;公共函数__construct(EntityManagerInterface$entityManager){$这->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%}