[0014]検索/一覧/登録/編集/削除がある画面作成の流れ
■初期準備
この例のLalavelフレームワークのバージョンは5.5です。
初めて作成する場合、ViewでFormファザードを利用したいので、以下ページを参考に設定を行います。
[0005]Formファザードを利用してViewを作成 ページへ
共通関数はヘルパー関数を自作したいので、以下ページを参考に設定を行います。
[0012]自作ヘルパー関数作成 ページへ
コントローラ(Controller)で\Input::all()を利用したいので、/config/app.phpのaliasesにInputを追加します。
app.php
'Input' => Illuminate\Support\Facades\Input::class,
configファイルを修正したのでキャッシュのクリアを実行します。ssh接続し、Lalavelのプロジェクト配下でartisanコマンドを実行します。
この例ではプロジェクト名が[sample]でプロジェクトがあるディレクトリは/home/failibere/www/sampleです。
#Lalavelのプロジェクト配下に移動
% cd /home/failibere/www/sample
#キャッシュクリア
% php artisan config:cache
■ルーティングの設定
例としてチームマスタを作成したいと思います。routes/web.phpに追加します。
web.php
//■Adminログイン後 S
Route::group(['prefix' => 'admin', 'middleware' => 'auth:admin'], function() {
Route::resource('mst/team', 'Admin\Mst\TeamController', ['only' => ['index', 'create', 'edit','update', 'store', 'destroy']]);
});
//■Adminログイン後 E
https://ドメイン/admin/mst/teamのURLでAdmin\Mst\TeamControllerを呼び出します。Controllerの機能はindex、create、edit、update、store、destroyを利用します。
■テーブル用意とModel
チーム用のテーブルをデータベースに追加します。テーブル名は「mst_teams」でカラムは以下にしました。
id int(10) AUTO_INCREMENT
name varchar(100)
disp_no int(11)
updated_by int(11)
created_at timestamp
updated_at timestamp
次にapp配下にモデル(Model)を作成します。テーブル名が「mst_teams」なので、モデル名は「MstTeam」です。「s」と「_」を無くし、大文字始まりの接続部分も大文字です。
MstTeam.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class MstTeam extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
//複数代入をしてはいけないカラム(ブラックリスト)
protected $guarded = ['id'];
}
IDがAUTO_INCREMENTでテーブル名も規則通りなのでモデルはこれだけです。既存のモデルをコピペしてクラス名だけ書き換えました。
■Controller
ルーティングの設定の通り、/app/Http/Controllers/Admin/Mst/TeamController.phpを作成します。
TeamController.php
<?php
namespace App\Http\Controllers\Admin\Mst;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\MstTeam;
use Validator;
use DB;
class TeamController extends Controller
{
public function __construct(){
$this->PAGE_NAME = "チーム";
$this->PAGE_URL = 'admin/mst/team';
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//検索項目
$paraArrs = array();
foreach(\Input::all() as $k => $v){
$paraArrs[$k] = $v;
}
$query = MstTeam::query();
//もしキーワードがあったら
if(!empty($paraArrs))
{
if(!empty($paraArrs['srh_name'])){
$query->where('id',$paraArrs['srh_name']);
}
if(!empty($paraArrs['srh_name_txt'])){
$query->where('name','like',"%".$paraArrs['srh_name_txt']."%");
}
//更新系検索
$query = helper_updated_search($query,$paraArrs,"");
}
//ページネーションだとページャーが簡単にできる!
$posts = $query->orderBy('disp_no','desc')->paginate(30);
return view('admin.mst.team.index', compact('posts','paraArrs'))->with('PAGE_NAME',@$this->PAGE_NAME)->with('PAGE_URL',@$this->PAGE_URL);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('admin.mst.team.create')->with('PAGE_NAME',@$this->PAGE_NAME)->with('PAGE_URL',@$this->PAGE_URL);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$v = $this->_mValidation($request,null);
$message = "作成";
if ($v->fails())
{
return redirect('/admin/mst/team/create')->withErrors($v)->withInput();
}
try {
DB::transaction(function() use($request) {
if (!MstTeam::create($request->all())) {
throw new \Exception();
}
});
\Session::flash('flash_info', $request->name.'を作成しました。');
} catch (\Exception $e) {
\Session::flash('flash_danger','DBエラーのため更新できませんでした
'.$e);
}
return redirect()->to('/admin/mst/team');
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$paras = MstTeam::find($id);
return view('admin.mst.team.edit', compact('paras'))->with('PAGE_NAME',@$this->PAGE_NAME)->with('PAGE_URL',@$this->PAGE_URL);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$paras = MstTeam::find($id);
$message = "更新";
if($request->copy_flg == 1){
$v = $this->_mValidation($request,null);
$message = "作成";
if ($v->fails()){
return redirect('/admin/mst/team/create')->withErrors($v)->withInput();
}
}else{
$v = $this->_mValidation($request,$id);
if ($v->fails()){
return redirect('/admin/mst/team/'.$id.'/edit')->withErrors($v)->withInput();
}
}
//トランザクション ※型違いのDBエラーが出てこなくエラー箇所はなしで登録されてしまう
try {
DB::transaction(function() use($paras,$request) {
if($request->copy_flg == 1){
if (!MstTeam::create($request->all())) {
throw new \Exception();
}
}else{
if (!$paras->update($request->all())) {
throw new \Exception();
}
}
});
\Session::flash('flash_info', $request->name."を".$message."しました。");
} catch (\Exception $e) {
\Session::flash('flash_danger','DBエラーのため'.$message.'できませんでした
'.$e);
}
return redirect()->route('team.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$paras = MstTeam::find($id);
//削除
try {
DB::transaction(function() use($paras) {
if (!$paras->delete()) {
throw new \Exception();
}
});
\Session::flash('flash_info', $paras->name.'を削除しました。');
} catch (\Exception $e) {
\Session::flash('flash_danger','DBエラーのため更新できませんでした
'.$e);
}
//リダイレクト
return redirect()->route('team.index');
}
private function _mValidation($request,$id) {
if(empty($id)){
$v = Validator::make($request->all(), [
'name'=>'required|max:100|unique:mst_teams',
'disp_no'=>'required|max:11|han_number',
]);
}else{
$v = Validator::make($request->all(), [
'name'=>'required|max:100|unique:mst_teams,name,'.$id.',id',
'disp_no'=>'required|max:11|han_number',
]);
}
return $v;
}
}
use App\MstTeam;先ほど作成したモデルを利用するのでuseします。
use Validator;バリデーションを利用するのでuseします。
use DB;
DBを利用するのでuseします。ページ名とURLをindexとcreateとeditのビュー(views)側で利用したいので__constructを利用しました。
RouteServiceProviderとバリデーションのRequestは作成時に逆に手間になるので使わずに作成しました。
・index関数内↓
Input::all()で検索条件を取得し、検索条件があればqueryに条件を追加しています。更新系検索処理は色々なところで利用するので「helper_updated_search」の名前で自作ヘルパーに作成し、共通化しました。
app/Services/helpers.phpに「helper_updated_search」を追加します。
helpers.php
//更新系の検索
function helper_updated_search($query,$paraArrs,$tableName) {
if(empty($tableName)){
$prefix = '';
}else{
$prefix = $tableName.'.';
}
if(!empty($paraArrs['srh_updated_by'])){
$query->where($prefix.'updated_by',$paraArrs['srh_updated_by']);
}
if(!empty($paraArrs['srh_updated_at_from'])){
$query->where($prefix.'updated_at','>=',$paraArrs['srh_updated_at_from']);
}
if(!empty($paraArrs['srh_updated_at_to'])){
$query->where($prefix.'updated_at','<=',helper_day_edit(1,1,$paraArrs['srh_updated_at_to']));
}
return $query;
}
ページャーを利用したいので30件ずつ表示でpaginateし、ビューを表示します。
ビューはadmin.mst.team.indexにし、後で作成します。
・create関数内↓
ビューを表示するだけです。ビューはadmin.mst.team.createにし、後で作成します。
・store関数内↓
新規登録前にバリデーションで値をチェックします。新規登録時と更新時に利用するので_mValidation関数にまとめました。
新規登録後にindex画面へ遷移します。
・edit関数内↓
ビューを表示するだけです。ビューはadmin.mst.team.editにし、後で作成します。
・update関数内↓
更新前にバリデーションで値をチェックします。copy_flgがある場合は新規登録、ない場合は更新にしています。
新規登録もしくは更新後にindex画面へ遷移します。
・destroy関数内↓
削除後にindex画面へ遷移します。
■ビュー
あと少しです!最後にViewを作成します。コントローラでadmin.mst.team.XXXにしたので、/resources/views/admin/mstにteamフォルダを作成し、
4つViewを作成していきます。まずはindex画面です。
index.blade.php
{{-- extendsとincludeの入れ子だとincludeが先に読み込まれる --}}
{{-- extendsの入れ子だと下から上に読み込まれる --}}
@extends('layouts.admin.appIndex')
<?php
//更新者
$static_admin_emp_cd_arr = helper_db_admin_emp_cd_arr(0);
?>
@section('search')
{!! Form::open(['method' => 'get','autocomplete'=>'off']) !!}
{!! Form::label('srh_name', '名前') !!}
{!! Form::select('srh_name',helper_db_team_name_arr(),@$paraArrs['srh_name'],['id'=>'srh_name']) !!}
{!! Form::label('srh_name_txt', '名前') !!}
<div class="input-group input-group-sm marginDel">
{!! Form::text('srh_name_txt',@$paraArrs['srh_name_txt'], ['class' => 'form-control','id'=>'srh_name_txt']) !!}
<span class="input-group-addon" onClick="clearText('srh_name_txt')">×@/span>
</div>
@include('admin.common.search')
{!! Form::submit("検索", ['class' => 'btn btn-info form-control']) !!}
{!! Form::close() !!}
@endsection
@section('create')
<a href=//create>{!!Html::image('images/icon/newcreate.png','icon_error',array('class'=>'image-middle'))!!}新規登録
@endsection
@section('content')
{!! $posts->appends(Request::all())->render() !!}
<table class="table table-striped">
<tr>
<td class="bg_green" id="tablePaddding">名前
<td class="bg_hedder_nomal" id="tablePaddding">表示順
@include('admin.common.title')
<td class="bg_hedder_nomal" id="tablePaddding">削除
</tr>
@foreach($posts as $post)
<tr>
<td id="tablePaddding">{!! link_to(action('Admin\Mst\TeamController@edit', [$post->id]), $post->name) !!}@/td>
<td id="tablePaddding">{{@$post->disp_no}}@/td>
@include('admin.common.data')
<td id="tablePaddding">{!! delete_form([@$PAGE_URL, $post->id]) !!}@/td>
</tr>
@endforeach
</table>
{!! $posts->appends(Request::all())->render() !!}
@endsection
@section('hedder_title')
スタッフ - {{@$PAGE_NAME}}
@endsection
@section('h_title')
スタッフ{!!Html::image('images/icon/h_yazirusi.png','h_yazirusi',array('class'=>'image-middle'))!!}
{!! link_to(@$PAGE_URL, @$PAGE_NAME, $attributes = array(), $secure = null) !!}
@endsection
@section('script')
@include('admin.common.script_index')
$(window).on('load', function(){
$('#srh_name').select2({
placeholder: "選択してください",
allowClear: true,
width:"100%"
});
});
@endsection
layoutsを利用し、他の画面からも共通で利用したいものは/resources/views配下に作成し、includeしています。
layoutsの利用方法は、[0004]レイアウト(layouts)を利用してViewを作成<を参照してください。
次は登録画面と編集画面です。
create.blade.php
@extends('layouts.admin.appForm')
@section('content')
@if ($errors->any())
<ul class="alert alert-danger">
<p class="image-middle">ERROR!!</p>
@foreach ($errors->all() as $error)
<div class="li-list">・{{ $error }}</div>
@endforeach
</ul>
@endif
{!! Form::open(array('route' => 'team.store','method' => 'post','autocomplete'=>'off')) !!}
@include('admin.mst.team.form', ['submitButton' => '新規作成'])
{!! Form::close() !!}
@stop
@section('hedder_title')
スタッフ - {{@$PAGE_NAME}} - 新規作成
@endsection
@section('h_title')
スタッフ{!!Html::image('images/icon/h_yazirusi.png','h_yazirusi',array('class'=>'image-middle'))!!}
{!! link_to(@$PAGE_URL, @$PAGE_NAME, $attributes = array(), $secure = null) !!}
{!!Html::image('images/icon/h_yazirusi.png','h_yazirusi',array('class'=>'image-middle'))!!}新規作成
@endsection
edit.blade.php
@extends('layouts.admin.appForm')
@section('content')
@if ($errors->any())
<ul class="alert alert-danger">
<p class="image-middle">ERROR!!</p>
@foreach ($errors->all() as $error)
<div class="li-list">・{{ $error }}</div>
@endforeach
@endif
{!! Form::model($paras, ['method' => 'PATCH', 'route' => ['team.update', $paras->id],'autocomplete'=>'off']) !!}
@include('admin.mst.team.form', ['updated_at' => $paras->updated_at->format('Y-m-d'), 'submitButton' => '編集'])
{!! Form::close() !!}
@endsection
@section('hedder_title')
スタッフ - {{@$PAGE_NAME}} - 編集
@endsection
@section('h_title')
スタッフ{!!Html::image('images/icon/h_yazirusi.png','h_yazirusi',array('class'=>'image-middle'))!!}
{!! link_to(@$PAGE_URL,@$PAGE_NAME, $attributes = array(), $secure = null) !!}
{!!Html::image('images/icon/h_yazirusi.png','h_yazirusi',array('class'=>'image-middle'))!!}編集
@endsection
登録画面と編集画面でForm部分は共通なので/resources/views/admin/mst/team/form.blade.phpを作成してincludeしています。
form.blade.php
{!! Form::hidden('updated_by',Auth::guard('admin')->id()) !!}
{!! Form::hidden('update_flg','') !!}
<table class="table-form">
@include('admin.common.copyFlg', ['submitButton' => $submitButton])
<tr>
<td>
<div class="form-group">
{!!Html::image('images/icon/required_icon.svg','h_yazirusi',array('class'=>'image-middle','width'=>'16px'))!!}{!! Form::label('name', '名前') !!}
</div>
<div class="input-group input-group-sm w-r ">
{!! Form::text('name',null, ['class' => 'form-control']) !!}
<span class="input-group-addon" onClick="clearText('name')">×</span>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-group">
{!!Html::image('images/icon/required_icon.svg','h_yazirusi',array('class'=>'image-middle','width'=>'16px'))!!}{!! Form::label('disp_no', '表示順') !!}
</div>
<div class="input-group input-group-sm w-c ">
{!! Form::text('disp_no',null, ['class' => 'form-control']) !!}
<span class="input-group-addon" onClick="clearText('disp_no')">×</span>
</div>
</td>
</tr>
</table>
<table class="table-form">
<tr>
<td>
<div class="form-group">
{!! Form::submit($submitButton, ['class' => 'btn btn-success form-control','value'=>'post']) !!}
</div>
</td>
<td>
<div class="form-group">
{!! link_to(@$PAGE_URL, '一覧へ戻る', ['class' => 'btn btn-primary form-control','value'=>'back']) !!}
</div>
</td>
</tr>
</table>
@section('script')
@include('admin.common.script_editback_alert')
@include('admin.common.script_upper_em_half', ['name' => 'disp_no','editFlg' => 2])
@endsection
必要なincludeファイルや画像や自作ヘルパーなどを用意し完成です!!