如何创建一个自定义表单字段类型
编辑该页面警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.0,不再维护。
读这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。
如何创建一个自定义表单字段类型
欧宝娱乐app下载地址Symfony提供了一群核心字段类型可供建筑形式。然而在有些情况下,您可能想要创建一个自定义表单字段类型为一个特定的目的。这道菜假设您需要一个字段定义包含一个人的性别,基于现有的选择。本节解释如何定义的字段,你可以定制它的布局和最后,如何注册它在应用程序中使用。
定义字段类型
为了创建自定义字段类型,首先您需要创建类的代表。在这种情况下都会调用类的字段类型GenderType
和文件将存储在表单字段的默认位置,这是< BundleName > \ \类型
。确保领域延伸AbstractType:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24
/ / src / AppBundle / /类型/ GenderType.php形式名称空间AppBundle\形式\类型;使用欧宝娱乐app下载地址\组件\形式\AbstractType;使用欧宝娱乐app下载地址\组件\OptionsResolver\OptionsResolver;使用欧宝娱乐app下载地址\组件\形式\扩展\核心\类型\ChoiceType;类GenderType扩展AbstractType{公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“选择”= >数组(“米”= >“男”,“f”= >“女”)));}公共函数getParent(){返回ChoiceType::类;}}
提示
这个文件的位置,并不重要形式\类型
目录是一个约定。
的返回值getParent
表明你扩展函数ChoiceType
字段。默认情况下,这意味着你承受所有的逻辑和呈现字段类型。看到的一些逻辑,检查ChoiceType类。有三个方法尤其重要:
-
buildForm ()
-
每个字段类型都有
buildForm
方法,就是您配置和构建任何领域(年代)。请注意,这是你使用同样的方法设置你的形式,它的运作是一样的。 -
buildView ()
-
该方法用于设置任何额外的变量需要渲染你的领域在一个模板。例如,在ChoiceType,一个
多个
变量设置和使用模板中设置(或没有)多个
属性选择
字段。看到创建一个模板为更多的细节。 -
configureOptions ()
-
这个定义的选项可用于表单类型
buildForm ()
和buildView ()
。有很多选择所有字段(参见FormType领域),但在这里你可以创建任何其他需要。
提示
如果你创建一个字段包含许多字段,然后一定要设置为“父”类型形式
或者一些延伸形式
。同样,如果您需要修改的“视图”你的孩子从你的父母类型,类型使用finishView ()
方法。
这一领域的目标是扩展类型的选择,使选择性别。这是通过修复选择
列表可能的性别。
创建一个模板
每种字段类型呈现模板片段,这部分取决于你的类型的类名。有关更多信息,请参见如何自定义形式呈现。
请注意
第一部分的前缀(例如。性别
)来自类名(GenderType
- >性别
)。这可以通过覆盖控制getBlockPrefix ()
在GenderType
。
谨慎
当表单类的名称匹配任何内置的字段类型,表单可能不会正确地呈现。一种类型命名AppBundle \ \ PasswordType形式
内置的名称有相同的块吗PasswordType
和不会正确地呈现。覆盖getBlockPrefix ()
方法返回一个独特的块前缀(例如。app_password
),以避免碰撞。
在这种情况下,自父字段ChoiceType
,你不需要做任何工作作为自定义字段类型将自动显示像一个ChoiceType
。但为了这个例子中,假设当你的字段是“扩大”(即单选按钮或复选框,而不是选择字段),你总是想要呈现它ul
元素。在表单的主题模板(有关详细信息,请参阅上面的链接),创建一个gender_widget
块来处理:
- 嫩枝
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
{# app /资源/视图/形式/ fields.html。树枝#}{%块gender_widget %}{%没有余地的%}{%如果扩大%}<ul{{块(“widget_container_attributes”)}}>{%为孩子在形式上%}<李>{{form_widget(孩子)}}{{了form_label(孩子)}}< /李>{%endfor%}< /ul>{%其他的%}{#让选择小部件呈现选择标签#}{{块(“choice_widget”)}}{%endif%}{%endspaceless%}{%endblock%}
1 2 3 4 5 6 7 8 9 10 11 12 13 14
< !- - - - - -- - - - - -app/Resources/views/form/gender_widget.html.php -->< /span>< ? php如果(美元扩大):? ><ul< ?php美元视图['形式']- - - - - ->块(美元形式,widget_container_attributes) ? > >< ? phpforeach(美元形式作为美元孩子):? ><李>< ? php回声美元视图(“形式”]- >小部件(美元孩子)? >< ? php回声美元视图(“形式”]- >标签(美元孩子)? >< /李>< ? phpendforeach? >< /ul>< ? php其他的:? >< !- - - - - -- - - - - -just let the choice widget render the select tag -->< /span>< ? php回声美元视图(“形式”]- >renderBlock (“choice_widget”)? >< ? phpendif? >
请注意
确保使用了正确的部件前缀。在本例中这个名字gender_widget
(见如何自定义形式呈现)。进一步,主要配置文件应该指向自定义表单模板时使用呈现各种形式。
当使用树枝,这是:
- YAML
- XML
- PHP
1 2 3 4
# app / config / config.yml枝:form_themes:- - - - - -“形式/ fields.html.twig”
1 2 3 4
< !- - - - - -- - - - - -app/config/config.xml -->< /span><枝:配置><枝:form-theme>形式/ fields.html.twig< /枝:form-theme>< /枝:配置>
1 2 3 4 5 6
/ / app / config / config . php美元容器- >loadFromExtension (“树枝”,数组(“form_themes”= >数组(“形式/ fields.html.twig”)));
对于PHP模板引擎,您的配置应该是这样的:
- YAML
- XML
- PHP
1 2 3 4 5 6
# app / config / config.yml框架:模板:形式:资源:- - - - - -”:形式:fields.html.php”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
< !- - - - - -- - - - - -app/config/config.xml -->< /span>< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><容器xmlns=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services”xmlns: xsi=“http://www.w3.org/2001/XMLSchema-instance”xmlns:框架=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/symfony”xsi: schemaLocation=“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services //www.oldmanjams.com/schema/dic/services/services-1.0.xsd //www.oldmanjams.com/schema/dic/symfony //www.oldmanjams.com/schema/dic/symfony/symfony-1.0.xsd”><框架:配置><框架:模板><框架:形式><框架:资源>形式:fields.html.php< /枝:资源>< /框架:形式>< /框架:模板>< /框架:配置>< /容器>
1 2 3 4 5 6 7 8 9 10
/ / app / config / config . php美元容器- >loadFromExtension (“框架”,数组(“模板”= >数组(“形式”= >数组(“资源”= >数组(”:形式:fields.html.php”)))));
使用字段类型
你现在可以立即使用您的自定义字段类型,只需创建一个新的实例类型的表单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / AppBundle / /类型/ AuthorType.php形式名称空间AppBundle\形式\类型;使用欧宝娱乐app下载地址\组件\形式\AbstractType;使用欧宝娱乐app下载地址\组件\形式\FormBuilderInterface;使用AppBundle\形式\类型\GenderType;类AuthorType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“gender_code”,GenderType::类,数组(“占位符”= >选择一个性别的));}}
但这只因为工作GenderType
是非常简单的。如果性别代码存储在数据库中的配置或?下一节解释了更复杂的字段类型解决这个问题。
作为服务创建字段类型
到目前为止,这个条目假设您有一个非常简单的自定义字段类型。但是如果你需要访问配置中,一个数据库连接,或其他服务,然后你要注册您的自定义类型作为服务。例如,假设你存储性别参数配置:
- YAML
- XML
- PHP
1 2 3 4 5
# app / config / config.yml参数:性别:m:男性f:女
1 2 3 4 5 6 7
< !- - - - - -- - - - - -app/config/config.xml -->< /span><参数><参数关键=“性别”类型=“收集”><参数关键=“m”>男性< /参数><参数关键=“f”>女< /参数>< /参数>< /参数>
1 2 3
/ / app / config / config . php美元容器- >setParameter (“genders.m”,“男”);美元容器- >setParameter (“genders.f”,“女”);
使用参数,定制字段类型定义为一种服务,注入性别
即将参数值作为第一个参数__construct
功能:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
# src / AppBundle /资源/ config / services.yml服务:app.form.type.gender:类:AppBundle \ \ \ GenderType型形式参数:- - - - - -“%性别%”标签:- - - - - -{名称:form.type}
1 2 3 4 5
< !- - - - - -- - - - - -src/AppBundle/Resources/config/services.xml -->< /span><服务id=“app.form.type.gender”类=“AppBundle \ \ \ GenderType型”><论点>%性别%< /论点><标签的名字=“form.type”/ >< /服务>
1 2 3 4 5 6 7 8 9 10
/ / src / AppBundle /资源/ config / services.php使用欧宝娱乐app下载地址\组件\DependencyInjection\定义;美元容器- >setDefinition (“app.form.type.gender”,新定义(“AppBundle \ \类型\ GenderType形式”,数组(“%性别%”)))- >addTag (“form.type”);
提示
确保服务文件被导入。看到如何导入配置文件/资源获取详细信息。
首先,添加一个__construct
方法GenderType
性别,接收配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24日25日26日
/ / src / AppBundle / /类型/ GenderType.php形式名称空间AppBundle\形式\类型;使用欧宝娱乐app下载地址\组件\OptionsResolver\OptionsResolver;/ /……/ /……类GenderType扩展AbstractType{私人美元genderChoices;公共函数__construct(数组美元genderChoices){美元这- >genderChoices =美元genderChoices;}公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“选择”= >美元这- >genderChoices));}/ /……}
太棒了!的GenderType
现在由于配置参数和注册为一个服务。因为你使用了form.type
别名在其配置中,将使用你的服务,而不是创建一个新GenderType
。换句话说,你的控制器不需要改变,它仍然看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / AppBundle / /类型/ AuthorType.php形式名称空间AppBundle\形式\类型;使用欧宝娱乐app下载地址\组件\形式\AbstractType;使用欧宝娱乐app下载地址\组件\形式\FormBuilderInterface;使用AppBundle\形式\类型\GenderType;类AuthorType扩展AbstractType{公共函数buildForm(FormBuilderInterface美元构建器数组,美元选项){美元构建器- >add (“gender_code”,GenderType::类,数组(“占位符”= >选择一个性别的));}}
玩得开心!