symphonygf / laravel-form
此软件包将 Symfony 表单组件集成到 Laravel 中。
Requires
- php: ^7.2|^8
- illuminate/support: ^6|^7|^8|^9
- symfony/form: ^4|^5|^6
- symfony/twig-bridge: ^4|^5|^6
- symfony/validator: ^4|^5|^6
- twig/twig: ^2.13|^3.3.8
Requires (Dev)
- orchestra/testbench: ^3|^4|^5|^6|^7
- squizlabs/php_codesniffer: ^2.3
This package is auto-updated.
Last update: 2024-09-29 06:03:22 UTC
README
请参阅 https://symfony.com.cn/doc/current/forms.html
Laravel 集成
- 预置旧输入
- 添加验证错误
- 翻译字段名称
安装
composer require fadeevGosha/laravel_form
- 将
Yobidoyobi\Form\ServiceProvider::class,
添加到您的 ServiceProviders。 - (可选) 将
'FormFactory' => Yobidoyobi\Form\Facade\FormFactory::class,
添加到您的 Facades。 - (可选) 将
'FormRenderer' => Yobidoyobi\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.com.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 Yobidoyobi\Form\ValidatesForms; use Yobidoyobi\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.com.cn/doc/current/book/forms.html 了解更多信息。
多对多关系
多对多行为不同,因为它不是您模型上的实际属性。相反,我们可以将 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(); }
有关更多选项,请参阅 choice 类型文档。
注意:BelongsToManyType 已弃用,转而使用 Symfony 的 ChoiceType。
翻译标签
如果您想自动翻译您的标签,只需将翻译键作为 label
属性传递。它将通过 Twig 的 trans
过滤器运行。
->add('name', TextType::class, ['label' => 'fields.name'])
上传文件
您可以在 FormBuilder 中使用 file
类型,并在您的模型上使用神奇的 getFile()
和 setFile()
方法,或者将其标记为未映射,这样您就可以自行处理它。请参阅 https://symfony.com.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; });