barryvdh / laravel-form-bridge
此软件包将 Symfony 表单组件集成到 Laravel 中。
Requires
- php: ^8
- illuminate/support: ^9|^10|^11.0
- symfony/form: ^6|^7.0
- symfony/twig-bridge: ^6|^7.0
- symfony/validator: ^6|^7.0
- twig/twig: ^3.3.8
Requires (Dev)
- orchestra/testbench: ^7|^8|^9.0
- squizlabs/php_codesniffer: ^2.3|^3.9
This package is auto-updated.
Last update: 2024-09-15 14:57:55 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; });