如何嵌入一个集合的形式
编辑本页任务类,并且在同一个表单中,您将能够编辑、创建和删除许多标签
与该任务相关的对象。
让我们从创建一个任务
实体:
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
/ / src /实体/ Task.php名称空间应用程序\实体;使用学说\常见的\集合\ArrayCollection;使用学说\常见的\集合\集合;类任务{受保护的$描述;受保护的$标签;公共函数__construct(){$这->标签=新ArrayCollection ();}公共函数getDescription():字符串{返回$这->描述;}公共函数setDescription(字符串$描述):无效{$这->描述=$描述;}公共函数getTags():集合{返回$这->标签;}}
请注意
的ArrayCollection是Doctrine特有的,类似于PHP数组,但提供了许多实用程序方法。
现在,创建一个标签
类。正如你在上面看到的,a任务
可以有很多标签
对象:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /实体/ Tag.php名称空间应用程序\实体;类标签{私人$的名字;公共函数getName():字符串{返回$这->名称;}公共函数setName(字符串$的名字):无效{$这->name =$的名字;}}
然后,创建一个表单类,以便a标签
对象可以被用户修改:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
/ / src /形式/ TagType.php名称空间应用程序\形式;使用应用程序\实体\标签;使用ob娱乐下载\组件\形式\AbstractType;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类TagType扩展AbstractType{公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{$构建器->add (“名字”);}公共函数configureOptions(OptionsResolver$解析器):无效{$解析器->setDefaults ([“data_class”= >标签::类,]);}}
下面,让我们为任务
实体,使用CollectionType领域的TagType
形式。这将允许我们修改所有的标签
a的要素任务
就在任务表单本身中:
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 /形式/ TaskType.php名称空间应用程序\形式;使用应用程序\实体\任务;使用ob娱乐下载\组件\形式\AbstractType;使用ob娱乐下载\组件\形式\扩展\核心\类型\CollectionType;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{$构建器->add (“描述”);$构建器->add (“标签”, CollectionType::类,“entry_type”= > TagType::类,“entry_options”= > [“标签”= >假)));}公共函数configureOptions(OptionsResolver$解析器):无效{$解析器->setDefaults ([“data_class”= >任务::类,]);}}
控件中创建一个新表单TaskType
:
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
/ / src /控制器/ TaskController.php名称空间应用程序\控制器;使用应用程序\实体\标签;使用应用程序\实体\任务;使用应用程序\形式\TaskType;使用ob娱乐下载\包\FrameworkBundle\控制器\AbstractController;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;类TaskController扩展AbstractController{公共函数新(请求$请求):响应{$任务=新任务();// dummy code -添加一些示例标签的任务//(否则,模板将呈现一个空的标签列表)$标签1=新标签();$标签1->setName (“标签1”);$任务->getTags ()->add ($标签1);$标签2=新标签();$标签2->setName (标签2的);$任务->getTags ()->add ($标签2);//结束虚拟代码$形式=$这->createForm (TaskType::类,$任务);$形式->handleRequest ($请求);如果($形式->isSubmitted () & &$形式->isValid ()) {/ /……做你的表单处理,如保存任务和标签实体}返回$这->renderForm (“任务/ new.html.twig”, (“形式”= >$形式]);}}
在模板中,现在可以遍历现有的模板TagType
呈现它们的表单:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
{/任务/ new.html #模板。树枝#}{#……#}{{form_start(form)}}{{form_row(form.description)}}<h3>标签h3><ul类=“标签”>{%为形式上的标签。标签%}<李>{{form_row(tag.name)}}李>{%endfor%}ul>{{form_end(form)}}{#……#}
当用户提交表单时,提交的数据为标签
字段用于构造ArrayCollection
的标签
对象。对象上设置集合标签
字段任务
并且可以通过任务- > getTags ()
.
到目前为止,这工作得很好,但只是编辑现有的标签。它还不允许我们添加新标签或删除现有标签。
谨慎
您可以将嵌套集合嵌入到您喜欢的任何级别。但是,如果使用Xdebug,则可能会收到一个已达到'100'的最大函数嵌套级别,中止!
错误。要解决此问题,请增加xdebug.max_nesting_level
PHP设置,或手动渲染每个表单字段使用form_row ()
而不是一次呈现整个表单(例如form_widget(形式)
).
错误。这是用allow_add
选择:
12 3 4 5 6 7 8 9 10 11 12 13 14
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,“entry_type”= > TagType::类,“entry_options”= > [“标签”= >假),“allow_add”= >真正的]);}
的allow_add
选项还会产生原型
变量可供您选择。这个“原型”是一个小“模板”,它包含了用JavaScript动态创建任何新“标签”表单所需的所有HTML。
让我们从纯JavaScript (Vanilla JS)开始-如果你正在使用刺激,请参见下面。
要渲染原型,添加以下内容data-prototype
属性为现有的< ul >
在模板中:
1 2 3 4 5
{# data-index属性对于下面的JavaScript代码是必需的<ul类=“标签”材料指数="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-prototype="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}">ul>
在渲染的页面上,结果看起来像这样:
1 2 3 4
<ul类=“标签”材料指数=“0”data-prototype="& lt;div比;& lt;标签类=“;要求“;比;__name__& lt;/标签比;& lt;div id =“;task_tags___name__“;比;& lt;div比;& lt;标签=“;task_tags___name___name“;类=“;要求“;比;的名字& lt;/标签比;& lt;输入类型=“;文本“;id =“;task_tags___name___name“;name =“;任务[标记][__name__][名称]“;要求=“;要求“;最大长度=“;255“;/比;& lt;/ div比;& lt;/ div比;& lt;/ div比;">ul>
现在添加一个按钮来动态添加一个新标签:
1
<按钮类型=“按钮”类=“add_item_link”data-collection-holder-class=“标签”>添加标签按钮>
另请参阅
如果要自定义原型中的HTML代码,请参见如何处理表单主题.
提示
的form.tags.vars.prototype
表单元素看起来和感觉起来就像个体吗form_widget(标签。*)
您的为
循环。这意味着你可以打电话form_widget ()
,form_row ()
或了form_label ()
在上面。你甚至可以选择只呈现它的一个字段(例如的名字
字段):
1
{{form_widget(form.tags.vars.prototype.name)|e}}
请注意
如果你渲染你的整个“标签”子表单一次(例如。form_row (form.tags)
),data-prototype
属性自动添加到包含div
,您需要相应地调整下面的JavaScript。
现在添加一些JavaScript来读取这个属性,并在用户单击“添加标签”链接时动态添加新的标签表单。添加一个< >脚本
标记在页面的某个地方,用JavaScript包含所需的功能:
1 2 3 4 5
文档.querySelectorAll (“.add_item_link”) .forEach (btn= >{btn.addEventListener (“点击”, addFormToCollection)});
的addFormToCollection ()
函数的工作是使用data-prototype
属性在单击此链接时动态添加新表单。的data-prototype
HTML包含标签的文本
输入名称为的元素任务[标记][__name__][名称]
的idtask_tags___name___name
.的__name__
是一个占位符,您将用一个惟一的递增数字替换它(例如。任务[标记][3][名称]
):
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
常量addFormToCollection =(e) = >{常量collectionHolder =文档.querySelector (“。”+ e.currentTarget.dataset.collectionHolderClass);常量项=文档.createElement (“李”);项。innerHTML = collectionHolder .dataset .prototype .replace(/ __name__ / g, collectionHolder.dataset.index);collectionHolder.appendChild(项);collectionHolder.dataset.index + +;};
现在,每当用户单击添加标签
链接,一个新的子表单将出现在页面上。当表单提交时,任何新的标签表单都将转换为新的标签
对象,并添加到标签
的属性任务
对象。
另请参阅
您可以在这里找到一个工作示例JSFiddle.
刺激,把一切都包在一个< div >
:
1 2 3 4 5 6 7
<div{{stimulus us_controller('form-collection')data-form-collection-index-value="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-form-collection-prototype-value="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}"><ul{{stimulus us_target('form-collection', 'collectionContainer')}}>ul><按钮类型=“按钮”{{stimulus - action('form-collection', 'addCollectionElement')}}>添加标签按钮>div>
然后创建控制器:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ /资产/控制器/ form-collection_controller.js进口{控制器}从“@hotwired /刺激”;出口默认的类扩展控制器{静态目标= [“collectionContainer”]静态值= {指数:数量,原型:字符串,} addCollectionElement(事件){常量项=文档.createElement (“李”);项。innerHTML =这.prototypeValue.replace (/ __name__ / g,这.indexValue);这.collectionContainerTarget.appendChild(项);这.indexValue + +;}}
allow_delete类型:
12 3 4 5 6 7 8 9 10 11 12
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,/ /……“allow_delete”= >真正的]);}
现在,需要将一些代码放入removeTag ()
的方法任务
:
12 3 4 5 6 7 8 9 10 11 12
/ / src /实体/ Task.php/ /……类任务{/ /……公共函数removeTag(标签$标签):无效{$这->标签->removeElement ($标签);}}
的allow_delete
选项意味着如果集合的项在提交时没有发送,则相关数据将从服务器上的集合中删除。为了在HTML表单中工作,必须在提交表单之前删除要删除的集合项的DOM元素。
首先,在每个标签表单中添加一个“delete this tag”链接:
12 3 4 5 6 7 8 9 10 11 12 13 14
文档.querySelectorAll (ul。标签s li') .forEach ((标签) = >{addTagFormDeleteLink(tag)})/ /……从上面看剩下的街区常量addFormToCollection =(e) = >{/ /……//添加一个删除链接到新表单addTagFormDeleteLink(项);}
的addTagFormDeleteLink ()
函数看起来是这样的:
12 3 4 5 6 7 8 9 10 11 12
常量addTagFormDeleteLink =(项) = >{常量removeFormButton =文档.createElement (“按钮”);removeFormButton。innerText =实现“删除此标签”;item.append (removeFormButton);removeFormButton.addEventListener (“点击”, (e) => {e.b preventdefault ();//删除标签表单的liitem.remove ();});}
当一个标签表单从DOM中删除并提交时,被删除的标签
对象将不包含在传递给的集合中setTags ()
.根据您的持久性层,这可能不足以实际删除被删除对象之间的关系标签
而且任务
对象。
另请参阅
Symfob娱乐下载ony社区创建了欧宝体育平台怎么样一些JavaScript包,提供了添加、编辑和删除集合元素所需的功能。请查看@a2lix ob娱乐下载/ symfony-collection包用于现代浏览器和ob娱乐下载symfony-collection包基于jQuery为其余的浏览器。
任务
实体: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
/ / src /实体/ Task.php名称空间应用程序\实体;使用学说\常见的\集合\ArrayCollection;使用学说\常见的\集合\集合;类任务{受保护的$描述;受保护的$标签;公共函数__construct(){$这->标签=新ArrayCollection ();}公共函数getDescription():字符串{返回$这->描述;}公共函数setDescription(字符串$描述):无效{$这->描述=$描述;}公共函数getTags():集合{返回$这->标签;}}
请注意
的ArrayCollection是Doctrine特有的,类似于PHP数组,但提供了许多实用程序方法。
标签
类。正如你在上面看到的,a任务
可以有很多标签
对象:12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /实体/ Tag.php名称空间应用程序\实体;类标签{私人$的名字;公共函数getName():字符串{返回$这->名称;}公共函数setName(字符串$的名字):无效{$这->name =$的名字;}}
标签
对象可以被用户修改:12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
/ / src /形式/ TagType.php名称空间应用程序\形式;使用应用程序\实体\标签;使用ob娱乐下载\组件\形式\AbstractType;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类TagType扩展AbstractType{公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{$构建器->add (“名字”);}公共函数configureOptions(OptionsResolver$解析器):无效{$解析器->setDefaults ([“data_class”= >标签::类,]);}}
任务
实体,使用CollectionType领域的TagType
形式。这将允许我们修改所有的标签
a的要素任务
就在任务表单本身中: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 /形式/ TaskType.php名称空间应用程序\形式;使用应用程序\实体\任务;使用ob娱乐下载\组件\形式\AbstractType;使用ob娱乐下载\组件\形式\扩展\核心\类型\CollectionType;使用ob娱乐下载\组件\形式\FormBuilderInterface;使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类TaskType扩展AbstractType{公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{$构建器->add (“描述”);$构建器->add (“标签”, CollectionType::类,“entry_type”= > TagType::类,“entry_options”= > [“标签”= >假)));}公共函数configureOptions(OptionsResolver$解析器):无效{$解析器->setDefaults ([“data_class”= >任务::类,]);}}
TaskType
: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
/ / src /控制器/ TaskController.php名称空间应用程序\控制器;使用应用程序\实体\标签;使用应用程序\实体\任务;使用应用程序\形式\TaskType;使用ob娱乐下载\包\FrameworkBundle\控制器\AbstractController;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;类TaskController扩展AbstractController{公共函数新(请求$请求):响应{$任务=新任务();// dummy code -添加一些示例标签的任务//(否则,模板将呈现一个空的标签列表)$标签1=新标签();$标签1->setName (“标签1”);$任务->getTags ()->add ($标签1);$标签2=新标签();$标签2->setName (标签2的);$任务->getTags ()->add ($标签2);//结束虚拟代码$形式=$这->createForm (TaskType::类,$任务);$形式->handleRequest ($请求);如果($形式->isSubmitted () & &$形式->isValid ()) {/ /……做你的表单处理,如保存任务和标签实体}返回$这->renderForm (“任务/ new.html.twig”, (“形式”= >$形式]);}}
TagType
呈现它们的表单:12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
{/任务/ new.html #模板。树枝#}{#……#}{{form_start(form)}}{{form_row(form.description)}}<h3>标签h3><ul类=“标签”>{%为形式上的标签。标签%}<李>{{form_row(tag.name)}}李>{%endfor%}ul>{{form_end(form)}}{#……#}
标签
字段用于构造ArrayCollection
的标签
对象。对象上设置集合标签
字段任务
并且可以通过任务- > getTags ()
.谨慎
您可以将嵌套集合嵌入到您喜欢的任何级别。但是,如果使用Xdebug,则可能会收到一个已达到'100'的最大函数嵌套级别,中止!
错误。要解决此问题,请增加xdebug.max_nesting_level
PHP设置,或手动渲染每个表单字段使用form_row ()
而不是一次呈现整个表单(例如form_widget(形式)
).
错误。这是用allow_add
选择:
12 3 4 5 6 7 8 9 10 11 12 13 14
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,“entry_type”= > TagType::类,“entry_options”= > [“标签”= >假),“allow_add”= >真正的]);}
的allow_add
选项还会产生原型
变量可供您选择。这个“原型”是一个小“模板”,它包含了用JavaScript动态创建任何新“标签”表单所需的所有HTML。
让我们从纯JavaScript (Vanilla JS)开始-如果你正在使用刺激,请参见下面。
要渲染原型,添加以下内容data-prototype
属性为现有的< ul >
在模板中:
1 2 3 4 5
{# data-index属性对于下面的JavaScript代码是必需的<ul类=“标签”材料指数="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-prototype="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}">ul>
在渲染的页面上,结果看起来像这样:
1 2 3 4
<ul类=“标签”材料指数=“0”data-prototype="& lt;div比;& lt;标签类=“;要求“;比;__name__& lt;/标签比;& lt;div id =“;task_tags___name__“;比;& lt;div比;& lt;标签=“;task_tags___name___name“;类=“;要求“;比;的名字& lt;/标签比;& lt;输入类型=“;文本“;id =“;task_tags___name___name“;name =“;任务[标记][__name__][名称]“;要求=“;要求“;最大长度=“;255“;/比;& lt;/ div比;& lt;/ div比;& lt;/ div比;">ul>
现在添加一个按钮来动态添加一个新标签:
1
<按钮类型=“按钮”类=“add_item_link”data-collection-holder-class=“标签”>添加标签按钮>
另请参阅
如果要自定义原型中的HTML代码,请参见如何处理表单主题.
提示
的form.tags.vars.prototype
表单元素看起来和感觉起来就像个体吗form_widget(标签。*)
您的为
循环。这意味着你可以打电话form_widget ()
,form_row ()
或了form_label ()
在上面。你甚至可以选择只呈现它的一个字段(例如的名字
字段):
1
{{form_widget(form.tags.vars.prototype.name)|e}}
请注意
如果你渲染你的整个“标签”子表单一次(例如。form_row (form.tags)
),data-prototype
属性自动添加到包含div
,您需要相应地调整下面的JavaScript。
现在添加一些JavaScript来读取这个属性,并在用户单击“添加标签”链接时动态添加新的标签表单。添加一个< >脚本
标记在页面的某个地方,用JavaScript包含所需的功能:
1 2 3 4 5
文档.querySelectorAll (“.add_item_link”) .forEach (btn= >{btn.addEventListener (“点击”, addFormToCollection)});
的addFormToCollection ()
函数的工作是使用data-prototype
属性在单击此链接时动态添加新表单。的data-prototype
HTML包含标签的文本
输入名称为的元素任务[标记][__name__][名称]
的idtask_tags___name___name
.的__name__
是一个占位符,您将用一个惟一的递增数字替换它(例如。任务[标记][3][名称]
):
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
常量addFormToCollection =(e) = >{常量collectionHolder =文档.querySelector (“。”+ e.currentTarget.dataset.collectionHolderClass);常量项=文档.createElement (“李”);项。innerHTML = collectionHolder .dataset .prototype .replace(/ __name__ / g, collectionHolder.dataset.index);collectionHolder.appendChild(项);collectionHolder.dataset.index + +;};
现在,每当用户单击添加标签
链接,一个新的子表单将出现在页面上。当表单提交时,任何新的标签表单都将转换为新的标签
对象,并添加到标签
的属性任务
对象。
另请参阅
您可以在这里找到一个工作示例JSFiddle.
刺激,把一切都包在一个< div >
:
1 2 3 4 5 6 7
<div{{stimulus us_controller('form-collection')data-form-collection-index-value="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-form-collection-prototype-value="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}"><ul{{stimulus us_target('form-collection', 'collectionContainer')}}>ul><按钮类型=“按钮”{{stimulus - action('form-collection', 'addCollectionElement')}}>添加标签按钮>div>
然后创建控制器:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ /资产/控制器/ form-collection_controller.js进口{控制器}从“@hotwired /刺激”;出口默认的类扩展控制器{静态目标= [“collectionContainer”]静态值= {指数:数量,原型:字符串,} addCollectionElement(事件){常量项=文档.createElement (“李”);项。innerHTML =这.prototypeValue.replace (/ __name__ / g,这.indexValue);这.collectionContainerTarget.appendChild(项);这.indexValue + +;}}
12 3 4 5 6 7 8 9 10 11 12 13 14
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,“entry_type”= > TagType::类,“entry_options”= > [“标签”= >假),“allow_add”= >真正的]);}
allow_add
选项还会产生原型
变量可供您选择。这个“原型”是一个小“模板”,它包含了用JavaScript动态创建任何新“标签”表单所需的所有HTML。data-prototype
属性为现有的< ul >
在模板中:1 2 3 4 5
{# data-index属性对于下面的JavaScript代码是必需的<ul类=“标签”材料指数="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-prototype="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}">ul>
1 2 3 4
<ul类=“标签”材料指数=“0”data-prototype="& lt;div比;& lt;标签类=“;要求“;比;__name__& lt;/标签比;& lt;div id =“;task_tags___name__“;比;& lt;div比;& lt;标签=“;task_tags___name___name“;类=“;要求“;比;的名字& lt;/标签比;& lt;输入类型=“;文本“;id =“;task_tags___name___name“;name =“;任务[标记][__name__][名称]“;要求=“;要求“;最大长度=“;255“;/比;& lt;/ div比;& lt;/ div比;& lt;/ div比;">ul>
1
<按钮类型=“按钮”类=“add_item_link”data-collection-holder-class=“标签”>添加标签按钮>
另请参阅
如果要自定义原型中的HTML代码,请参见如何处理表单主题.
提示
的form.tags.vars.prototype
表单元素看起来和感觉起来就像个体吗form_widget(标签。*)
您的为
循环。这意味着你可以打电话form_widget ()
,form_row ()
或了form_label ()
在上面。你甚至可以选择只呈现它的一个字段(例如的名字
字段):
1
{{form_widget(form.tags.vars.prototype.name)|e}}
请注意
如果你渲染你的整个“标签”子表单一次(例如。form_row (form.tags)
),data-prototype
属性自动添加到包含div
,您需要相应地调整下面的JavaScript。
< >脚本
标记在页面的某个地方,用JavaScript包含所需的功能:1 2 3 4 5
文档.querySelectorAll (“.add_item_link”) .forEach (btn= >{btn.addEventListener (“点击”, addFormToCollection)});
addFormToCollection ()
函数的工作是使用data-prototype
属性在单击此链接时动态添加新表单。的data-prototype
HTML包含标签的文本
输入名称为的元素任务[标记][__name__][名称]
的idtask_tags___name___name
.的__name__
是一个占位符,您将用一个惟一的递增数字替换它(例如。任务[标记][3][名称]
):12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
常量addFormToCollection =(e) = >{常量collectionHolder =文档.querySelector (“。”+ e.currentTarget.dataset.collectionHolderClass);常量项=文档.createElement (“李”);项。innerHTML = collectionHolder .dataset .prototype .replace(/ __name__ / g, collectionHolder.dataset.index);collectionHolder.appendChild(项);collectionHolder.dataset.index + +;};
添加标签
链接,一个新的子表单将出现在页面上。当表单提交时,任何新的标签表单都将转换为新的标签
对象,并添加到标签
的属性任务
对象。另请参阅
您可以在这里找到一个工作示例JSFiddle.
刺激,把一切都包在一个< div >
:
1 2 3 4 5 6 7
<div{{stimulus us_controller('form-collection')data-form-collection-index-value="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-form-collection-prototype-value="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}"><ul{{stimulus us_target('form-collection', 'collectionContainer')}}>ul><按钮类型=“按钮”{{stimulus - action('form-collection', 'addCollectionElement')}}>添加标签按钮>div>
1 2 3 4 5 6 7
<div{{stimulus us_controller('form-collection')data-form-collection-index-value="{{form.tags |长度> 0 ?form.tags |最后的.vars.name + 1: 0}}"data-form-collection-prototype-value="{{form_widget(form.tags.vars.prototype)|e('html_attr')}}"><ul{{stimulus us_target('form-collection', 'collectionContainer')}}>ul><按钮类型=“按钮”{{stimulus - action('form-collection', 'addCollectionElement')}}>添加标签按钮>div>
然后创建控制器:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ /资产/控制器/ form-collection_controller.js进口{控制器}从“@hotwired /刺激”;出口默认的类扩展控制器{静态目标= [“collectionContainer”]静态值= {指数:数量,原型:字符串,} addCollectionElement(事件){常量项=文档.createElement (“李”);项。innerHTML =这.prototypeValue.replace (/ __name__ / g,这.indexValue);这.collectionContainerTarget.appendChild(项);这.indexValue + +;}}
allow_delete类型:
12 3 4 5 6 7 8 9 10 11 12
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,/ /……“allow_delete”= >真正的]);}
现在,需要将一些代码放入removeTag ()
的方法任务
:
12 3 4 5 6 7 8 9 10 11 12
/ / src /实体/ Task.php/ /……类任务{/ /……公共函数removeTag(标签$标签):无效{$这->标签->removeElement ($标签);}}
的allow_delete
选项意味着如果集合的项在提交时没有发送,则相关数据将从服务器上的集合中删除。为了在HTML表单中工作,必须在提交表单之前删除要删除的集合项的DOM元素。
首先,在每个标签表单中添加一个“delete this tag”链接:
12 3 4 5 6 7 8 9 10 11 12 13 14
文档.querySelectorAll (ul。标签s li') .forEach ((标签) = >{addTagFormDeleteLink(tag)})/ /……从上面看剩下的街区常量addFormToCollection =(e) = >{/ /……//添加一个删除链接到新表单addTagFormDeleteLink(项);}
的addTagFormDeleteLink ()
函数看起来是这样的:
12 3 4 5 6 7 8 9 10 11 12
常量addTagFormDeleteLink =(项) = >{常量removeFormButton =文档.createElement (“按钮”);removeFormButton。innerText =实现“删除此标签”;item.append (removeFormButton);removeFormButton.addEventListener (“点击”, (e) => {e.b preventdefault ();//删除标签表单的liitem.remove ();});}
当一个标签表单从DOM中删除并提交时,被删除的标签
对象将不包含在传递给的集合中setTags ()
.根据您的持久性层,这可能不足以实际删除被删除对象之间的关系标签
而且任务
对象。
另请参阅
Symfob娱乐下载ony社区创建了欧宝体育平台怎么样一些JavaScript包,提供了添加、编辑和删除集合元素所需的功能。请查看@a2lix ob娱乐下载/ symfony-collection包用于现代浏览器和ob娱乐下载symfony-collection包基于jQuery为其余的浏览器。
12 3 4 5 6 7 8 9 10 11 12
/ / src /形式/ TaskType.php/ /……公共函数buildForm(FormBuilderInterface$构建器数组,$选项):无效{/ /……$构建器->add (“标签”, CollectionType::类,/ /……“allow_delete”= >真正的]);}
removeTag ()
的方法任务
:12 3 4 5 6 7 8 9 10 11 12
/ / src /实体/ Task.php/ /……类任务{/ /……公共函数removeTag(标签$标签):无效{$这->标签->removeElement ($标签);}}
allow_delete
选项意味着如果集合的项在提交时没有发送,则相关数据将从服务器上的集合中删除。为了在HTML表单中工作,必须在提交表单之前删除要删除的集合项的DOM元素。12 3 4 5 6 7 8 9 10 11 12 13 14
文档.querySelectorAll (ul。标签s li') .forEach ((标签) = >{addTagFormDeleteLink(tag)})/ /……从上面看剩下的街区常量addFormToCollection =(e) = >{/ /……//添加一个删除链接到新表单addTagFormDeleteLink(项);}
addTagFormDeleteLink ()
函数看起来是这样的:12 3 4 5 6 7 8 9 10 11 12
常量addTagFormDeleteLink =(项) = >{常量removeFormButton =文档.createElement (“按钮”);removeFormButton。innerText =实现“删除此标签”;item.append (removeFormButton);removeFormButton.addEventListener (“点击”, (e) => {e.b preventdefault ();//删除标签表单的liitem.remove ();});}
标签
对象将不包含在传递给的集合中setTags ()
.根据您的持久性层,这可能不足以实际删除被删除对象之间的关系标签
而且任务
对象。另请参阅
Symfob娱乐下载ony社区创建了欧宝体育平台怎么样一些JavaScript包,提供了添加、编辑和删除集合元素所需的功能。请查看@a2lix ob娱乐下载/ symfony-collection包用于现代浏览器和ob娱乐下载symfony-collection包基于jQuery为其余的浏览器。