https://github.com/barryvdh/laravel-form-bridge
Laravel Bridge for the Symfony Form Component
https://github.com/barryvdh/laravel-form-bridge
hacktoberfest
Last synced: 2 months ago
JSON representation
Laravel Bridge for the Symfony Form Component
- Host: GitHub
- URL: https://github.com/barryvdh/laravel-form-bridge
- Owner: barryvdh
- Created: 2015-04-20T14:55:40.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2024-04-15T13:55:22.000Z (about 1 year ago)
- Last Synced: 2024-05-01T12:21:33.133Z (about 1 year ago)
- Topics: hacktoberfest
- Language: PHP
- Homepage:
- Size: 165 KB
- Stars: 148
- Watchers: 13
- Forks: 29
- Open Issues: 9
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
## 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.
```php
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:
```php
@formStart($form)
@formWidget($form)
@formEnd($form)
```Other directives are: @form, @formLabel, @formErrors, @formRest and @formRow
```php
@form($form)
``````php
@formStart($form)Name
@formLabel($form['name'], 'Your name')
@formWidget($form['name'], ['attr' => ['class' => 'name-input']])Rest
@formRest($form)@formEnd($form)
```Or use the following in your Twig templates to render the view:
```twig
{{ 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
```php
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:
```php
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 relationsBelongsToMany 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.
```php
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
]);
``````php
$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](http://symfony.com/doc/current/reference/forms/types/choice.html).> 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.
```php
->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
```php
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;
}
}
``````php
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:
```php
$this->app->extend('form.types', function($types, $app){
$types[] = new CustomType();
return $types;
});
```