barryvdh/laravel-form-bridge

此软件包将 Symfony 表单组件集成到 Laravel 中。

v0.7.3 2024-04-15 13:50 UTC

README

https://symfony.ac.cn/doc/current/forms.html

Laravel 集成

  • 预置旧输入
  • 添加验证错误
  • 翻译字段名

安装

  • composer require barryvdh/laravel-form-bridge
  • Barryvdh\Form\ServiceProvider::class, 添加到你的 ServiceProviders。
  • (可选) 将 'FormFactory' => Barryvdh\Form\Facade\FormFactory::class, 添加到你的 Facades。
  • (可选) 将 'FormRenderer' => Barryvdh\Form\Facade\FormRenderer::class, 添加到你的 Facades。

基本示例

您可以使用 FormFactory 创建表单。您可以提供一个模型作为数据,以便填充值。

您可以使用 $form->handleRequest($request); 来更新用户的值,或者您可以使用 $request 对象或 Input Facade 如常。但是,默认情况下,表单在 form 键下分组,因此您必须使用 $request->get('form') 来获取表单值。或者,您可以创建一个带空名称的命名表单。

如果您需要设置更多选项,请使用 createBuilder 函数而不是 create,以便能够使用 setAction() 等。您需要调用 ->getForm() 来再次获取实际的表单实例。

use FormFactory;
use Illuminate\Http\Request;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

Route::any('create', function()
{
    $user = App\User::first();
    
    $form = FormFactory::create(FormType::class, $user)
        ->add('name', TextType::class)
        ->add('email', EmailType::class, [
            'rules' => 'unique:users,email',
        ])
        ->add('save', SubmitType::class, ['label' => 'Save user']);

    $form->handleRequest();

    if ($form->isSubmitted() && $form->isValid()) {
        // Save the user with the new mapped data
        $user->save();
        
        return redirect('home')->withStatus('User saved!');
    }

    return view('user.create', compact('form'));
});

在您的 Blade 模板中使用以下内容

@formStart($form)
@formWidget($form)
@formEnd($form)

其他指令是:@form, @formLabel, @formErrors, @formRest 和 @formRow

@form($form)
@formStart($form)

<h2>Name</h2>
@formLabel($form['name'], 'Your name')
@formWidget($form['name'], ['attr' => ['class' => 'name-input']])

<h2>Rest</h2>
@formRest($form)

@formEnd($form)

或者在您的 Twig 模板中使用以下内容来渲染视图

{{ formStart(form) }}
{{ formWidget(form) }}
{{ formEnd(form) }}

有关更多选项,请参阅 https://symfony.ac.cn/doc/current/book/forms.html#form-rendering-template

特质

为了便于在控制器中使用,您可以使用 2 个特质

ValidatesForms: 添加一个验证方法,类似于 ValidatesRequests 特质:$this->validateForm($form, $request, $rules)

CreatesForms: 创建一个表单或 FormBuilder

  • createForm($type, $data, $options) -> 类型(form 或类型类)的表单
  • createNamed($name, $type, $data, $options) -> 带有指定名称的表单
  • createFormBuilder($data, $options) -> 带空名称的 FormBuilder
  • createNamedFormBuilder($name, $data, $options) -> 带有指定名称的 FormBuilder
use Barryvdh\Form\ValidatesForms;
use Barryvdh\Form\CreatesForms;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class UserController extends Controller{

    use ValidatesForms, CreatesForms;
    
    public function anyIndex(Request $request)
    {
        $user = User::first();

        $form = $this->createFormBuilder($user)
            ->add('name', TextType::class)
            ->add('email', EmailType::class)
            ->add('save', SubmitType::class, ['label' => 'Save user'])
            ->getForm();

        $form->handleRequest($request);

        if ($form->isSubmitted()) {
            $this->validateForm($form, $request, [
                'name' => 'required',
                'email' => 'required|email',
            ]);

            $user->save();
        }

        return view('user', ['form' => $form->createView()]);
    }
}

创建命名表单

use Symfony\Component\Form\Extension\Core\Type\FormType;

$form = $this->createNamed('user', FormType::class, $user) 
    ->add('name', TextType::class)
    ->add('email', EmailType::class)
    ->add('save', SubmitType::class, ['label' => 'Save user']);

有关更多信息,请参阅 https://symfony.ac.cn/doc/current/book/forms.html

多对多关系

BelongsToMany 的行为不同,因为它不是您模型上的实际属性。相反,我们可以将 mapped 选项设置为 false 并手动同步。

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

$builder->add('users', ChoiceType::class, [
    'choices' => \App\User::pluck('name', 'id'),
    'multiple' => true,
    'mapped' => false,
    'expanded' => true, // true=checkboxes, false=multi select
]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
    $this->validate($request, $rules);

    $item->save();
    $item->users()->sync($form->get('users')->getData());

    return redirect()->back();
}

有关更多选项,请参阅 选择类型文档

注意:BelongsToManyType 已弃用,取而代之的是来自 Symfony 的 ChoiceType。

翻译标签

如果您想自动翻译您的标签,只需将翻译键作为 label 属性传递。它将通过 Twig 的 trans 过滤器运行。

->add('name', TextType::class, ['label' => 'fields.name'])

上传文件

您可以在 FormBuilder 中使用 file 类型,并使用模型上的 getFile()setFile() 魔法方法,或者将其标记为未映射,以便您可以自行处理。有关详细信息,请参阅 https://symfony.ac.cn/doc/current/cookbook/doctrine/file_uploads.html

Class User extends Model {

    /** @var UploadedFile  */
    private $file;

    public function getFile()
    {
        return $this->file;
    }

    public function setFile(UploadedFile $file = null)
    {
        $this->file = $file;
    }

    public function upload()
    {
        // the file property can be empty if the field is not required
        if (null === $this->getFile()) {
            return;
        }

        // use the original file name here but you should
        // sanitize it at least to avoid any security issues

        // move takes the target directory and then the
        // target filename to move to
        $this->getFile()->move(
            $this->getUploadRootDir(),
            $this->getFile()->getClientOriginalName()
        );

        // set the path property to the filename where you've saved the file
        $this->path = $this->getFile()->getClientOriginalName();

        // clean up the file property as you won't need it anymore
        $this->file = null;
    }
}
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

$user = User::first();

$form = $this->createFormBuilder($user)
    ->add('name', TextType::class)
    ->add('file', FileType::class)
    ->add('save', SubmitType::class, ['label' => 'Save user'])
    ->getForm();
    
$form->handleRequest($request);

if ($form->isValid()) {
    $user->upload();
    $user->save();
}

扩展

您可以在 ServiceProvider 中扩展一些数组,例如,要添加类型,请将以下内容添加到您自己的 ServiceProvider 中的 register() 方法

$this->app->extend('form.types', function($types, $app){
    $types[] = new CustomType();
    return $types;
});