You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony:如何在Twig模板循环中为每个Ring实体添加复选框

问题

我是PHP和Symfony的初学者,尝试从数据库中展示Ring实体的每条数据,并在每个Ring条目末尾添加复选框,但当前Twig模板仅在第一个Ring条目显示复选框,请问如何实现所有Ring条目都显示复选框?

原控制器代码

public function testPage(Request $request) { 
  $ring = $this->ringRepository->customFindAll();
  $jewel = $this->ringJewelRepository->customFindAll();
  $custom = $this->customRingRepository->customFindAll();
      
  $form = $this->createFormBuilder($ring)
     ->add('active', CheckboxType::class, [
         'label'=>'Selection',
         'required'=>false
     ])
     ->getForm();
   $form->handleRequest($request);
      
   return [
     'rings'=>$ring,
     'jewels'=>$jewel,
     'custom' => $custom,
     'form'=>$form->createView()
   ];
}

原Twig模板代码

{% for ring in rings %}
<div>
  <div class="text-center">
             
    <p>Ring Name: {{ ring.ring_name }}</p>
            
    <p>Ring Type: {{ ring.ring_type }}</p>
            
    {{ form_start(form) }}
            
    {{ form_widget(form.active) }}
          
    {{ form_end(form) }}   
  </div>
  <div class="text-center">
    <a href="{{ url('update_ring', {'id': ring.id}) }}" class="btn-basic">Update Ring</a>
  </div>
</div>
{% endfor %}

问题原因

你把整个Ring集合直接传给表单构建器,表单只会生成一个active字段。在Twig循环中,每次渲染form.active都是同一个DOM元素(id重复),浏览器只会显示第一个,后续的会被忽略。

解决方案

提供两种可行的实现方式,按需选择:

方案一:使用集合类型(CollectionType)推荐

这种方式符合Symfony表单的设计规范,适合批量处理选中状态。

修改后的控制器代码

public function testPage(Request $request) { 
    $rings = $this->ringRepository->customFindAll();
    $jewel = $this->ringJewelRepository->customFindAll();
    $custom = $this->customRingRepository->customFindAll();

    // 初始化选中状态数组,键为Ring的ID,默认未选中
    $selectedRings = array_fill_keys(
        array_map(fn($ring) => $ring->getId(), $rings),
        false
    );

    $form = $this->createFormBuilder(['selected_rings' => $selectedRings])
        ->add('selected_rings', CollectionType::class, [
            'entry_type' => CheckboxType::class,
            'entry_options' => [
                'label' => 'Selection',
                'required' => false,
            ],
            'allow_add' => false,
            'allow_delete' => false,
        ])
        ->getForm();

    $form->handleRequest($request);

    // 处理表单提交,获取选中的Ring ID
    if ($form->isSubmitted() && $form->isValid()) {
        $data = $form->getData();
        $selectedIds = array_keys(array_filter($data['selected_rings']));
        // 这里可以添加批量操作逻辑,比如批量删除、更新等
    }

    return [
        'rings' => $rings,
        'jewels' => $jewel,
        'custom' => $custom,
        'form' => $form->createView()
    ];
}

修改后的Twig模板代码

{{ form_start(form) }}
{% for ring in rings %}
<div>
    <div class="text-center">
        <p>Ring Name: {{ ring.ring_name }}</p>
        <p>Ring Type: {{ ring.ring_type }}</p>
        {# 渲染对应Ring的复选框 #}
        {{ form_widget(form.selected_rings[ring.id]) }}
    </div>
    <div class="text-center">
        <a href="{{ url('update_ring', {'id': ring.id}) }}" class="btn-basic">Update Ring</a>
    </div>
</div>
{% endfor %}
{{ form_end(form) }}

方案二:为每个Ring创建独立字段

适合数据量较小的场景,直接为每个Ring生成单独的复选框字段。

修改后的控制器代码

public function testPage(Request $request) { 
    $rings = $this->ringRepository->customFindAll();
    $jewel = $this->ringJewelRepository->customFindAll();
    $custom = $this->customRingRepository->customFindAll();

    $formBuilder = $this->createFormBuilder();

    // 遍历每个Ring,添加独立的复选框字段
    foreach ($rings as $ring) {
        $formBuilder->add('ring_' . $ring->getId(), CheckboxType::class, [
            'label' => 'Selection',
            'required' => false,
            'data' => false, // 默认未选中
        ]);
    }

    $form = $formBuilder->getForm();
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $data = $form->getData();
        $selectedIds = [];
        foreach ($data as $key => $isSelected) {
            if ($isSelected) {
                // 提取Ring的ID
                $selectedIds[] = str_replace('ring_', '', $key);
            }
        }
        // 处理选中的Ring
    }

    return [
        'rings' => $rings,
        'jewels' => $jewel,
        'custom' => $custom,
        'form' => $form->createView()
    ];
}

修改后的Twig模板代码

{{ form_start(form) }}
{% for ring in rings %}
<div>
    <div class="text-center">
        <p>Ring Name: {{ ring.ring_name }}</p>
        <p>Ring Type: {{ ring.ring_type }}</p>
        {# 渲染对应Ring的独立复选框 #}
        {{ form_widget(form['ring_' ~ ring.id]) }}
    </div>
    <div class="text-center">
        <a href="{{ url('update_ring', {'id': ring.id}) }}" class="btn-basic">Update Ring</a>
    </div>
</div>
{% endfor %}
{{ form_end(form) }}

内容的提问来源于stack exchange,提问作者maz32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:01:12