早速実装してみる
今回はjobsテーブル
という求人情報を入れるテーブルがある前提で進める
全部書くと大変などで所々端折ってます
プレビュー用のルーティング設定
- routes/web.php
// 登録フォーム
Route::get('/jobs/create', 'JobController@create')->name('jobs.create');
// プレビュー処理
Route::post('/jobs/preview', 'JobController@preview')->name('jobs.preview');
// 登録処理
Route::post('/jobs', 'JobController@store')->name('jobs.store');
Controller作成
ここではメインとなる「求人作成フォームの表示」と「プレビュー処理」のみ記載
(実際には登録処理などのメソッドも必要)
- JobController.php
<?php
namespace App\Http\Controllers;
use App\Models\Job;
use Illuminate\Http\Request;
class JobController extends Controller
{
/**
* 求人作成フォーム
*
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
return view('jobs.create');
}
/**
* 求人プレビュー
*
* @param Request $request
* @return \Illuminate\Contracts\View\View
*/
public function preview(Request $request)
{
// viewに渡すjobインスタンスを作成
$job = Job::make()->newInstance($request->input());
return view('jobs.show', ['job' => $job, 'is_preview' => true]);
}
}
実際に表示する求人詳細画面のViewと同じViewをプレビューでも使用しているのがポイント
共通化しているので区別するためにis_preview
を渡してあげてる
また、newInstance()
はNon-static methodなのでJob
がインスタンス化されていない場合はmake()
関数をつけてあげる
もしコンストラクタでインスタンス化されている場合は下記でOK
$this->job->newInstance()
View作成
デザインやLayoutは省略で表示する部分だけざっくり書いてみる
- jobs/create.blade.php
@section('content')
<form method="post" action="{{ route('jobs.store') }}">
@csrf
<h1>求人作成</h1>
<h2>タイトル</h2>
<input type="text" name="title" value="{{ old('title') }}">
<h2>求人内容</h2>
<textarea name="content">{{ old('content') }}</textarea>
<h2>会社</h2>
<select name="company_id">
<option value="1">会社1</option>
<option value="2">会社2</option>
<option value="3">会社3</option>
</select>
<button type="button" onclick="onClickPreview(this)">プレビューを見る</button>
<button type="button" onclick="onClickSave(this)">保存する</button>
</form>
<script type="text/javascript">
const onClickPreview = (button) => {
button.form.action = '/jobs/preview'
button.form.target = '_blank'
button.form.submit()
}
const onClickSave = (button) => {
button.form.action = '/jobs'
button.form.target = '_self'
button.form.submit()
}
</script>
@endsection
同じform内で「登録」か「プレビュー」かを切り分けるためJavaScriptを使用してる
- jobs/show.blade.php
@section('content')
@if (isset($is_preview))
<p>※これはプレビュー表示です</p>
@endif
<h1>{{ $job->title }}</h1>
<h2>求人内容</h2>
<div>{!! nl2br(e($job->content)) !!}</div>
<h2>求人を出している会社名</h2>
<div>{{ $job->company->name }}</div>
@endsection
newInstance
でリレーション (今回だとcompany_id
) も指定してあげると、$job->company->name
のように従来のリレーションの呼び出しができるようになって便利
例えば求人ポータルサイトなどで登録前に求人情報をプレビュー表示したい場合
・まだDBには入れてないけどリレーションをViewで使用したい
・実際の求人情報詳細画面と同じViewを使って共通化したい
そんな時に便利なのが
newInstance()