Laravel utilise le même formulaire pour créer et modifier
Je suis assez nouveau pour Laravel et je dois créer un formulaire pour create et un formulaire pour edit. Dans ma forme, j'ai pas mal de messages jQuery ajax. Je me demande si Laravel me fournit un moyen facile d'utiliser le même formulaire pour mon édition et créer sans avoir à ajouter des tonnes de logique dans mon code. Je ne veux pas vérifier si je suis en mode édition ou création à chaque fois lors de l'attribution de valeurs aux champs lorsque le formulaire se charge. Des idées sur la façon dont je peux accomplir cela avec un codage minimum?
9 réponses
J'aime utiliser form model binding
donc je peux facilement remplir les champs d'un formulaire avec la valeur correspondante, donc je suis cette approche (en utilisant un modèle user
par exemple):
@if(isset($user))
{{ Form::model($user, ['route' => ['updateroute', $user->id], 'method' => 'patch']) }}
@else
{{ Form::open(['route' => 'createroute']) }}
@endif
{{ Form::text('fieldname1', Input::old('fieldname1')) }}
{{ Form::text('fieldname2', Input::old('fieldname2')) }}
{{-- More fields... --}}
{{ Form::submit('Save', ['name' => 'submit']) }}
{{ Form::close() }}
Ainsi, par exemple, à partir d'un contrôleur, j'utilise essentiellement le même formulaire pour créer et mettre à jour, comme:
// To create a new user
public function create()
{
// Load user/createOrUpdate.blade.php view
return View::make('user.createOrUpdate');
}
// To update an existing user (load to edit)
public function edit($id)
{
$user = User::find($id);
// Load user/createOrUpdate.blade.php view
return View::make('user.createOrUpdate')->with('user', $user);
}
Assez facile dans votre contrôleur que vous faites:
public function create()
{
$user = new User;
$action = URL::route('user.store');
return View::('viewname')->with(compact('user', 'action'));
}
public function edit($id)
{
$user = User::find($id);
$action = URL::route('user.update', ['id' => $id]);
return View::('viewname')->with(compact('user', 'action'));
}
Et vous avez juste à utiliser de cette façon:
{{ Form::model($user, ['action' => $action]) }}
{{ Form::input('email') }}
{{ Form::input('first_name') }}
{{ Form::close() }}
Une autre méthode propre avec un petit contrôleur, deux vues et une vue partielle:
UsersController.php
public function create()
{
return View::('create');
}
public function edit($id)
{
$user = User::find($id);
return View::('edit')->with(compact('user'));
}
Créer.lame.php
{{ Form::open( array( 'route' => ['users.index'], 'role' => 'form' ) ) }}
@include('_fields')
{{ Form::close() }}
Modifier.lame.php
{{ Form::model( $user, ['route' => ['users.update', $user->id], 'method' => 'put', 'role' => 'form'] ) }}
@include('_fields')
{{ Form::close() }}
_fields.lame.php
{{ Form::text('fieldname1') }}
{{ Form::text('fieldname2') }}
{{ Form::button('Save', ['type' => 'submit']) }}
Simple et propre :)
UserController.php
public function create() {
$user = new User();
return View::make('user.edit', compact('user'));
}
public function edit($id) {
$user = User::find($id);
return View::make('user.edit', compact('user'));
}
Modifier.lame.php
{{ Form::model($user, ['url' => ['/user', $user->id]]) }}
{{ Form::text('name') }}
<button>save</button>
{{ Form::close() }}
Au lieu de créer deux méthodes - une pour créer une nouvelle ligne et une pour la mise à jour, vous devez utiliser la méthode findOrNew()
. Donc:
public function edit(Request $request, $id = 0)
{
$user = User::findOrNew($id);
$user->fill($request->all());
$user->save();
}
Dans Rails, il a form_for helper, donc nous pourrions faire une fonction comme form_for.
On peut faire une macro de formulaire, par exemple dans resource / macro / html.php:
(si vous ne savez pas comment configurer une macro, vous pouvez google "laravel 5 Macro")
Form::macro('start', function($record, $resource, $options = array()){
if ((null === $record || !$record->exists()) ? 1 : 0) {
$options['route'] = $resource .'.store';
$options['method'] = 'POST';
$str = Form::open($options);
} else {
$options['route'] = [$resource .'.update', $record->id];
$options['method'] = 'PUT';
$str = Form::model($record, $options);
}
return $str;
});
Le Contrôleur:
public function create()
{
$category = null;
return view('admin.category.create', compact('category'));
}
public function edit($id)
{
$category = Category.find($id);
return view('admin.category.edit', compact('category'));
}
Puis dans la vue _form.lame.php:
{!! Form::start($category, 'admin.categories', ['class' => 'definewidth m20']) !!}
// here the Form fields
{{!! Form::close() !!}}
Puis voir Créer.lame.php:
@include '_form'
Puis voir modifier.lame.php:
@include '_form'
Article is a model containing two fields - title and content
Create a view as pages/add-update-article.blade.php
@if(!isset($article->id))
<form method = "post" action="add-new-article-record">
@else
<form method = "post" action="update-article-record">
@endif
{{ csrf_field() }}
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" placeholder="Enter title" name="title" value={{$article->title}}>
<span class="text-danger">{{ $errors->first('title') }}</span>
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea class="form-control" rows="5" id="content" name="content">
{{$article->content}}
</textarea>
<span class="text-danger">{{ $errors->first('content') }}</span>
</div>
<input type="hidden" name="id" value="{{{ $article->id }}}">
<button type="submit" class="btn btn-default">Submit</button>
</form>
Route(web.php): Create routes to controller
Route::get('/add-new-article', 'ArticlesController@new_article_form');
Route::post('/add-new-article-record', 'ArticlesController@add_new_article');
Route::get('/edit-article/{id}', 'ArticlesController@edit_article_form');
Route::post('/update-article-record', 'ArticlesController@update_article_record');
Create ArticleController.php
public function new_article_form(Request $request)
{
$article = new Articles();
return view('pages/add-update-article', $article)->with('article', $article);
}
public function add_new_article(Request $request)
{
$this->validate($request, ['title' => 'required', 'content' => 'required']);
Articles::create($request->all());
return redirect('articles');
}
public function edit_article_form($id)
{
$article = Articles::find($id);
return view('pages/add-update-article', $article)->with('article', $article);
}
public function update_article_record(Request $request)
{
$this->validate($request, ['title' => 'required', 'content' => 'required']);
$article = Articles::find($request->id);
$article->title = $request->title;
$article->content = $request->content;
$article->save();
return redirect('articles');
}
Vous pouvez utiliser la liaison de formulaire et 3 méthodes dans votre Controller
. Voici ce que je fais
class ActivitiesController extends BaseController {
public function getAdd() {
return $this->form();
}
public function getEdit($id) {
return $this->form($id);
}
protected function form($id = null) {
$activity = ! is_null($id) ? Activity::findOrFail($id) : new Activity;
//
// Your logic here
//
$form = View::make('path.to.form')
->with('activity', $activity);
return $form->render();
}
}
Et à mon avis j'ai
{{ Form::model($activity, array('url' => "/admin/activities/form/{$activity->id}", 'method' => 'post')) }}
{{ Form::close() }}
UserController.php
use View;
public function create()
{
return View::make('user.manage', compact('user'));
}
public function edit($id)
{
$user = User::find($id);
return View::make('user.manage', compact('user'));
}
Utilisateur.lame.php
@if(isset($user))
{{ Form::model($user, ['route' => ['user.update', $user->id], 'method' => 'PUT']) }}
@else
{{ Form::open(['route' => 'user.store', 'method' => 'POST']) }}
@endif
// fields
{{ Form::close() }}