PHP项目Symfony form与开关按钮

wen PHP项目 3

本文目录导读:

PHP项目Symfony form与开关按钮

  1. 使用原生 CheckboxType 配合 CSS
  2. 使用 ChoiceType 自定义渲染
  3. 使用 JavaScript 库(推荐方案)
  4. 使用第三方 Bundle
  5. 完整示例 - 使用 Stimulus(推荐现代方案)
  6. 推荐方案
  7. 注意事项

在 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>

推荐方案

  1. 简单项目:使用 CSS 美化 CheckboxType
  2. 中等复杂度:创建自定义表单类型 + Stimulus
  3. 复杂项目:使用成熟的 UI 库(Bootstrap Switch 等)

注意事项

  • 确保正确配置 Symfony 的 CSRF 保护
  • 开关状态的提交值是布尔型
  • 考虑无障碍访问(Accessibility)

抱歉,评论功能暂时关闭!