symphonygf/laravel-form

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

v1.0.2.x-dev 2022-08-30 05:05 UTC

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;
});