Laravel использует ту же форму для создания и редактирования
Я совсем новичок в Laravel, и мне нужно создать форму для создания и форму для редактирования. В моей форме у меня есть довольно много сообщений jquery ajax. Мне интересно, обеспечивает ли Laravel простой способ для меня использовать одну и ту же форму для редактирования и создания без необходимости добавлять тонны логики в мой код. Я не хочу проверять, нахожусь ли я в режиме редактирования или создания каждый раз при назначении значений полям при загрузке формы. Есть идеи о том, как я могу сделать это с минимальным кодированием?
9 answers
Мне нравится использовать форму model binding
, чтобы я мог легко заполнять поля формы соответствующим значением, поэтому я следую этому подходу (например, используя модель user
):
@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() }}
Так, например, с контроллера я в основном использую одну и ту же форму для создания и обновления, например:
// 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);
}
Довольно легко в вашем контроллере вы делаете:
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'));
}
И вам просто нужно использовать этот способ:
{{ Form::model($user, ['action' => $action]) }}
{{ Form::input('email') }}
{{ Form::input('first_name') }}
{{ Form::close() }}
Еще один чистый метод с небольшим контроллером, двумя представлениями и частичным представлением:
UsersController.php
public function create()
{
return View::('create');
}
public function edit($id)
{
$user = User::find($id);
return View::('edit')->with(compact('user'));
}
Create.blade.php
{{ Form::open( array( 'route' => ['users.index'], 'role' => 'form' ) ) }}
@include('_fields')
{{ Form::close() }}
Edit.blade.php
{{ Form::model( $user, ['route' => ['users.update', $user->id], 'method' => 'put', 'role' => 'form'] ) }}
@include('_fields')
{{ Form::close() }}
_fields.blade.php
{{ Form::text('fieldname1') }}
{{ Form::text('fieldname2') }}
{{ Form::button('Save', ['type' => 'submit']) }}
Простой и понятный:)
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'));
}
Edit.blade.php
{{ Form::model($user, ['url' => ['/user', $user->id]]) }}
{{ Form::text('name') }}
<button>save</button>
{{ Form::close() }}
Вместо создания двух методов - одного для создания новой строки и одного для обновления, вы должны использовать метод findOrNew()
. Итак:
public function edit(Request $request, $id = 0)
{
$user = User::findOrNew($id);
$user->fill($request->all());
$user->save();
}
В Rails у него есть помощник form_for, поэтому мы могли бы создать функцию, подобную form_for.
Мы можем создать макрос формы, например, в resource/macro/html.php :
(если вы не знаете, как настроить макрос, вы можете погуглить "Макрос laravel 5")
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;
});
Контроллер:
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'));
}
Затем в представлении _form.blade.php :
{!! Form::start($category, 'admin.categories', ['class' => 'definewidth m20']) !!}
// here the Form fields
{{!! Form::close() !!}}
Затем просмотрите create.blade.php :
@include '_form'
Затем просмотрите edit.blade.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');
}
Вы можете использовать привязку форм и 3 метода в вашем Controller
. Вот что я делаю
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();
}
}
И, по моему мнению, у меня есть
{{ 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'));
}
User.blade.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() }}