本文目录导读:

- 使用原生 CheckboxType 配合 CSS
- 使用 ChoiceType 自定义渲染
- 使用 JavaScript 库(推荐方案)
- 使用第三方 Bundle
- 完整示例 - 使用 Stimulus(推荐现代方案)
- 推荐方案
- 注意事项
在 Symfony 表单中使用开关按钮(Toggle Switch)通常有几种方法,以下是完整的实现方案:
使用原生 CheckboxType 配合 CSS
最简单的方案是使用 Symfony 的 CheckboxType 并通过 CSS 美化:
// src/Form/YourFormType.php
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
$builder
->add('active', CheckboxType::class, [
'label' => '启用状态',
'required' => false,
'attr' => [
'class' => 'toggle-switch'
]
])
CSS 样式:
/* 开关按钮样式 */
.toggle-switch {
display: none;
}
.toggle-switch + label {
position: relative;
padding-left: 60px;
cursor: pointer;
line-height: 24px;
}
.toggle-switch + label:before {
content: '';
position: absolute;
left: 0;
width: 50px;
height: 24px;
background: #ccc;
border-radius: 12px;
transition: background 0.3s;
}
.toggle-switch + label:after {
content: '';
position: absolute;
left: 2px;
top: 2px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: transform 0.3s;
}
.toggle-switch:checked + label:before {
background: #4CAF50;
}
.toggle-switch:checked + label:after {
transform: translateX(26px);
}
使用 ChoiceType 自定义渲染
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder
->add('status', ChoiceType::class, [
'choices' => [
'关闭' => false,
'开启' => true,
],
'expanded' => true,
'multiple' => false,
'attr' => [
'class' => 'toggle-switch-group'
]
])
使用 JavaScript 库(推荐方案)
安装 Bootstrap Switch 或类似库:
npm install bootstrap-switch # 或 npm install @yaireo/toggle
创建自定义表单类型:
// src/Form/Type/ToggleSwitchType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ToggleSwitchType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'on_text' => '开启',
'off_text' => '关闭',
'on_color' => 'success',
'off_color' => 'danger',
]);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['on_text'] = $options['on_text'];
$view->vars['off_text'] = $options['off_text'];
$view->vars['on_color'] = $options['on_color'];
$view->vars['off_color'] = $options['off_color'];
}
public function getParent()
{
return CheckboxType::class;
}
}
模板渲染:
{# templates/form/toggle_switch.html.twig #}
{% block toggle_switch_widget %}
<div class="toggle-switch-container">
<input type="checkbox"
id="{{ form.vars.id }}"
name="{{ form.vars.full_name }}"
value="{{ form.vars.value }}"
{{ form.vars.checked ? 'checked' : '' }}
class="toggle-switch-input">
<label for="{{ form.vars.id }}" class="toggle-switch-label">
<span class="toggle-switch-slider"></span>
</label>
<span class="toggle-status">
{{ form.vars.checked ? form.vars.on_text : form.vars.off_text }}
</span>
</div>
{% endblock %}
注册自定义表单主题:
# config/packages/twig.yaml
twig:
form_themes:
- 'form/toggle_switch.html.twig'
使用第三方 Bundle
安装合适的 Symfony Bundle:
composer require fadco/symfony-toggle-switch # 或 composer require thomas-bros/switch-bundle
完整示例 - 使用 Stimulus(推荐现代方案)
创建 Stimulus 控制器:
// assets/controllers/toggle_switch_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ["checkbox", "status"];
connect() {
this.updateStatus();
}
toggle(event) {
this.updateStatus();
}
updateStatus() {
if (this.hasCheckboxTarget) {
this.statusTarget.textContent =
this.checkboxTarget.checked ? '已开启' : '已关闭';
}
}
}
表单类型:
$builder
->add('active', CheckboxType::class, [
'label' => false,
'required' => false,
'attr' => [
'data-controller' => 'toggle-switch',
'data-action' => 'change->toggle-switch#toggle',
'class' => 'toggle-checkbox'
]
])
HTML 结构:
<div class="toggle-wrapper" data-controller="toggle-switch">
<label class="toggle">
{{ form_widget(form.active) }}
<span class="toggle-track">
<span class="toggle-thumb"></span>
</span>
</label>
<span class="toggle-text" data-toggle-switch-target="status">
{{ form.active.vars.checked ? '已开启' : '已关闭' }}
</span>
</div>
推荐方案
- 简单项目:使用 CSS 美化 CheckboxType
- 中等复杂度:创建自定义表单类型 + Stimulus
- 复杂项目:使用成熟的 UI 库(Bootstrap Switch 等)
注意事项
- 确保正确配置 Symfony 的 CSRF 保护
- 开关状态的提交值是布尔型
- 考虑无障碍访问(Accessibility)