• Stars
    star
    143
  • Rank 247,958 (Top 6 %)
  • Language
    PHP
  • Created about 9 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Laravel Bridge for the Symfony Form Component

Laravel Form Bridge

See http://symfony.com/doc/current/forms.html

Laravel integration:

  • Pre-set old input
  • Add validation errors
  • Translate field names

Install

  • composer require barryvdh/laravel-form-bridge
  • Add Barryvdh\Form\ServiceProvider::class, to you ServiceProviders.
  • (optional) Add 'FormFactory' => Barryvdh\Form\Facade\FormFactory::class, to your Facades.
  • (optional) Add 'FormRenderer' => Barryvdh\Form\Facade\FormRenderer::class, to your Facades.

Basic example

You can use the FormFactory to create a form. You can supply a Model as data, so it will fill the values.

You can use $form->handleRequest($request); to update the values in the user, or you can just use $request object or Input facade like usual. However, by default, the form is grouped under a form key, so you have to use $request->get('form') to get the form values. Or you can create a Named form, with an empty name.

If you need to set more options, use the createBuilder function instead of create, to be able to use setAction() etc. You need to call ->getForm() to get the actual form instance again.

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

Use the following in your Blade templates:

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

Other directives are: @form, @formLabel, @formErrors, @formRest and @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)

Or use the following in your Twig templates to render the view:

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

See http://symfony.com/doc/current/book/forms.html#form-rendering-template for more options.

Traits

To make it easier to use in a Controller, you can use 2 traits:

ValidatesForms: Adds a validation method, similar to the ValidatesRequests trait: $this->validateForm($form, $request, $rules)

CreatesForms: Create a Form or FormBuilder:

  • createForm($type, $data, $options) -> Form for a type (form or a Type class)
  • createNamed($name, $type, $data, $options) -> Form with a given name
  • createFormBuilder($data, $options) -> FormBuilder with an empty name
  • createNamedFormBuilder($name, $data, $options) -> FormBuilder with a given name
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()]);
    }
}

Creating a named form:

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']);

See http://symfony.com/doc/current/book/forms.html for more information.

BelongsToMany relations

BelongsToMany behaves differently, because it isn't an actual attribute on your model. Instead, we can set the mapped option to false and sync it manually.

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

See for more options the choice type documentation.

Note: The BelongsToManyType is deprecated in favor of the ChoiceType from Symfony.

Translation labels

If you want to translate your labels automatically, just pass the translation key as the label attribute. It will run throught Twig's trans filter.

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

Uploading Files

You can use the file type in the FormBuilder, and use the magic getFile() and setFile() method on your Model or mark it as not mapped, so you can handle it yourself. See http://symfony.com/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();
}

Extending

You can extend some of the arrays in the ServiceProvider, eg. to add Types, add this to the register() method in your own ServiceProvider:

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

More Repositories

1

laravel-debugbar

Debugbar for Laravel (Integrates PHP Debug Bar)
PHP
15,498
star
2

laravel-ide-helper

IDE Helper for Laravel
PHP
13,496
star
3

laravel-dompdf

A DOMPDF Wrapper for Laravel
PHP
6,091
star
4

laravel-snappy

Laravel Snappy PDF
PHP
2,447
star
5

laravel-translation-manager

Manage Laravel translation files
PHP
1,564
star
6

laravel-elfinder

elFinder bundle for Laravel
PHP
730
star
7

laravel-httpcache

Laravel HTTP Cache
PHP
459
star
8

laravel-async-queue

Laravel Async Queue Driver
PHP
290
star
9

laravel-migration-generator

Generate migrations based on existing tables
PHP
246
star
10

elfinder-flysystem-driver

elFinder driver for Flysystem
PHP
182
star
11

laravel-omnipay

Omnipay ServiceProvider for Laravel
PHP
169
star
12

laravel-vendor-cleanup

L4 Vendor Cleanup Command (DEPRECATED!)
PHP
162
star
13

composer-cleanup-plugin

Composer plugin for cleaning up unused files from packages.
PHP
143
star
14

laravel-twigbridge

Laravel TwigBridge
PHP
59
star
15

laravel-security

Laravel Security
PHP
53
star
16

laravel-stack-middleware

Stack Middleware for Laravel
PHP
40
star
17

laravel-assetic

Assetic ServiceProvider for Laravel
PHP
37
star
18

barryvdh.github.io

Jekyll blog for barryvdh.nl
HTML
16
star
19

laravel-form-builder

Laravel Form builder for version 5!
PHP
8
star
20

OAuth

PSR2 compliant OAuth 1.0 library based on Andy Smith's OAuth library here: http://oauth.googlecode.com/svn/code/php/
PHP
6
star
21

picofeed

Picofeed fork
PHP
4
star
22

elfinder-builds

Mirror from the nightly builds from elFinder
JavaScript
3
star
23

assetic-filters

Additional CSSminFilter and UriPrependFilter, using the mrclay/minify libraries
PHP
3
star