Symfony:如何将文件删除表单的提交按钮替换为图标?求代码排查
嘿,我来帮你搞定这个图标按钮的问题,顺便也指出代码里的小问题~
把提交按钮换成图标按钮的解决方案
我们可以通过两步实现用图标替换默认的提交按钮:
1. 调整表单类的配置
在DocumentRemoveType里,修改removeButton的定义,去掉默认文字标签,添加适配图标的HTML属性:
class DocumentRemoveType extends AbstractType { private $urlGenerator; public function __construct(UrlGeneratorInterface $urlGenerator) { $this->urlGenerator = $urlGenerator; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add("id", HiddenType::class) ->setAction($this->urlGenerator->generate("admin_files_deletion")) ->add("removeButton", SubmitType::class, [ 'label' => '', // 清空默认按钮文本 'attr' => [ 'class' => 'btn btn-link p-0 border-0', // 移除默认按钮样式 'title' => 'Supprimer ce document' // 鼠标悬停提示 ] ]); } }
2. 在Twig模板中自定义按钮渲染
默认的form_widget会渲染带标签的按钮,我们需要手动替换成图标,同时保留表单的安全属性(比如CSRF令牌):
{% for file in files %} {# @var file \App\Entity\Document #} <tr> <th scope="row">{{ file.name }}</th> <td>{{ file.createdAt|date("d/m/Y") }}</td> <td class="text-center"> <a href="{{ vich_uploader_asset(file, 'file') }}" target="_blank" title="Télécharger le document"> <i class="fa fa-download"></i> </a> {{ form_start(forms[file.id], {attr: {class: 'my-form-class d-inline'} }) }} {{ form_widget(forms[file.id].id) }} {# 渲染隐藏的ID字段 #} {# 自定义删除按钮,使用Font Awesome垃圾桶图标 #} <button type="submit" class="{{ forms[file.id].removeButton.vars.attr.class }}" title="{{ forms[file.id].removeButton.vars.attr.title }}"> <i class="fa fa-trash text-danger"></i> </button> {# 必须渲染CSRF令牌,保障表单安全 #} {{ form_widget(forms[file.id]._token) }} {{ form_end(forms[file.id], {render_rest: false}) }} {# 关闭自动渲染多余字段 #} </td> </tr> {% endfor %}
这里用d-inline类让表单和下载链接在同一行显示,text-danger给图标加上红色,更符合删除操作的视觉提示。
代码中的错误修正
我发现你的删除控制器里有一个明显的错误:
// 错误代码 $file = $manager->find(Document::class, $manager["id"]);
$manager是EntityManagerInterface实例,不能用数组访问的方式获取表单ID。正确的写法应该是从表单中提取ID:
/** * @Route("/files/delete", name="admin_files_deletion") * @param Request $request * @return \Symfony\Component\HttpFoundation\RedirectResponse */ public function filesDeletion(Request $request) { $form = $this->createForm(DocumentRemoveType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $manager = $this->getDoctrine()->getManager(); // 修正:从表单获取文件ID $fileId = $form->get('id')->getData(); $file = $manager->find(Document::class, $fileId); if ($file) { // 增加判断,避免删除不存在的文件 $manager->remove($file); $manager->flush(); } } return $this->redirectToRoute('admin_files'); }
另外还可以优化逻辑:因为列表页的表单绑定了Document对象,删除控制器也可以直接绑定对象来获取实例,更简洁:
public function filesDeletion(Request $request) { $form = $this->createForm(DocumentRemoveType::class, new Document()); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $manager = $this->getDoctrine()->getManager(); $file = $form->getData(); $existingFile = $manager->find(Document::class, $file->getId()); if ($existingFile) { $manager->remove($existingFile); $manager->flush(); } } return $this->redirectToRoute('admin_files'); }
内容的提问来源于stack exchange,提问作者Alexandre
相关产品推荐
相关产品推荐

