【利用者分類マスタ】新規、編集画面、CSV出力ボダン修正
All checks were successful
Deploy main / deploy (push) Successful in 22s

This commit is contained in:
你的名字 2025-10-07 16:41:19 +09:00
parent 5b01165319
commit 870b944009
6 changed files with 570 additions and 245 deletions

View File

@ -15,20 +15,35 @@ class UsertypeController extends Controller
{
public function list(Request $request)
{
$sortable = ['user_categoryid', 'sort_order', 'usertype_subject1', 'usertype_subject2', 'usertype_subject3', 'print_name', 'usertype_remarks'];
$sort = $request->input('sort', 'user_categoryid');
if (!in_array($sort, $sortable, true)) {
$sort = 'user_categoryid';
}
$sortType = strtolower($request->input('sort_type', 'asc'));
if (!in_array($sortType, ['asc', 'desc'], true)) {
$sortType = 'asc';
}
$inputs = [
'isMethodPost' => 0,
'isMethodPost' => $request->isMethod('post') ? 1 : 0,
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
'sort' => $sort,
'sort_type' => $sortType,
'page' => (int) $request->get('page', 1),
];
$inputs['isMethodPost'] = $request->isMethod('post');
$inputs['list'] = Usertype::search($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
$filters = [
'filter_sort_order' => $request->input('filter_sort_order', ''),
'filter_category_name1' => $request->input('filter_category_name1', ''),
'filter_category_name2' => $request->input('filter_category_name2', ''),
'filter_category_name3' => $request->input('filter_category_name3', ''),
];
$searchParams = array_merge($inputs, $filters);
$viewData = $searchParams;
$viewData['list'] = Usertype::search($searchParams);
if ($viewData['list']->total() > 0 && $viewData['page'] > $viewData['list']->lastPage()) {
return redirect()->route('usertypes');
}
return view('admin.usertypes.list', $inputs);
return view('admin.usertypes.list', $viewData);
}
public function add(Request $request)
@ -36,9 +51,9 @@ class UsertypeController extends Controller
// 画面に戻すための初期値
$viewData = [
'sort_order' => old('sort_order', ''),
'category_name1' => old('category_name1', ''),
'category_name2' => old('category_name2', ''),
'category_name3' => old('category_name3', ''),
'usertype_subject1' => old('usertype_subject1', ''),
'usertype_subject2' => old('usertype_subject2', ''),
'usertype_subject3' => old('usertype_subject3', ''),
'print_name' => old('print_name', ''),
'usertype_money' => old('usertype_money', ''),
'usertype_remarks' => old('usertype_remarks', ''),
@ -50,9 +65,9 @@ class UsertypeController extends Controller
// 入力値をまとめる
$inputs = [
'sort_order' => $request->input('sort_order'),
'category_name1' => $request->input('category_name1'),
'category_name2' => $request->input('category_name2'),
'category_name3' => $request->input('category_name3'),
'usertype_subject1' => $request->input('usertype_subject1'),
'usertype_subject2' => $request->input('usertype_subject2'),
'usertype_subject3' => $request->input('usertype_subject3'),
'print_name' => $request->input('print_name'),
'usertype_money' => $request->input('usertype_money'),
'usertype_remarks' => $request->input('usertype_remarks'),
@ -61,9 +76,9 @@ class UsertypeController extends Controller
// バリデーションルール(最小限)
$rules = [
'sort_order' => 'nullable|integer',
'category_name1' => 'nullable|string|max:255',
'category_name2' => 'nullable|string|max:255',
'category_name3' => 'nullable|string|max:255',
'usertype_subject1' => 'nullable|string|max:255',
'usertype_subject2' => 'nullable|string|max:255',
'usertype_subject3' => 'nullable|string|max:255',
'print_name' => 'required|string|max:255',
'usertype_money' => 'nullable|string|max:255',
'usertype_remarks' => 'nullable|string|max:255',
@ -115,9 +130,9 @@ class UsertypeController extends Controller
// ▼ 内蔵バリデーションFormRequest を使わない)
$rules = [
'sort_order' => 'nullable|integer',
'category_name1' => 'nullable|string|max:255',
'category_name2' => 'nullable|string|max:255',
'category_name3' => 'nullable|string|max:255',
'usertype_subject1' => 'nullable|string|max:255',
'usertype_subject2' => 'nullable|string|max:255',
'usertype_subject3' => 'nullable|string|max:255',
'print_name' => 'required|string|max:255',
'usertype_money' => 'nullable|string|max:255',
'usertype_remarks' => 'nullable|string|max:255',
@ -141,9 +156,9 @@ class UsertypeController extends Controller
// fill するフィールドだけを明示したい場合は only(...) で絞ってもOK
$usertype->fill([
'sort_order' => $data['sort_order'] ?? null,
'category_name1' => $data['category_name1'] ?? null,
'category_name2' => $data['category_name2'] ?? null,
'category_name3' => $data['category_name3'] ?? null,
'usertype_subject1' => $data['usertype_subject1'] ?? null,
'usertype_subject2' => $data['usertype_subject2'] ?? null,
'usertype_subject3' => $data['usertype_subject3'] ?? null,
'print_name' => $data['print_name'] ?? null,
'usertype_money' => $data['usertype_money'] ?? null,
'usertype_remarks' => $data['usertype_remarks'] ?? null,
@ -197,15 +212,16 @@ class UsertypeController extends Controller
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$timestamp = now()->format('YmdHis');
$filename = "利用者分類マスタ{$timestamp}.csv";
$filePath = storage_path("app/{$filename}");
$headers = [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Encoding' => 'UTF-8',
'Pragma' => 'no-cache',
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Expires' => '0',
];
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
@ -221,8 +237,7 @@ class UsertypeController extends Controller
__('適用料率'),// 2
__('備考'),// 3
);
$filename = "利用者分類マスタ.csv";
$file = fopen($filename, 'w+');
$file = fopen($filePath, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv(
@ -236,7 +251,7 @@ class UsertypeController extends Controller
);
}
fclose($file);
return Response::download($filename, $filename, $headers);
return Response::download($filePath, $filename, $headers)->deleteFileAfterSend(true);
}
public function import(Request $request)

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Utils;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
@ -15,9 +16,14 @@ class Usertype extends Model
protected $primaryKey = 'user_categoryid';
protected $fillable = [
'sort_order',
'usertype_subject1',
'usertype_subject2',
'usertype_subject3',
'print_name',
'usertype_money',
'usertype_remarks'
'usertype_remarks',
'operator_id',
];
public static function boot()
@ -30,20 +36,37 @@ class Usertype extends Model
public static function search($inputs)
{
$list = self::query();
if ($inputs['isMethodPost']) {
$query = self::query();
if (!empty($inputs['filter_sort_order'])) {
$query->where('sort_order', $inputs['filter_sort_order']);
}
// Sort
if ($inputs['sort']) {
$list->orderBy($inputs['sort'], $inputs['sort_type']);
if (!empty($inputs['filter_category_name1'])) {
$query->where('usertype_subject1', 'like', '%' . $inputs['filter_category_name1'] . '%');
}
if ($inputs['isExport']){
$list = $list->get();
}else{
$list = $list->paginate(Utils::item_per_page);
if (!empty($inputs['filter_category_name2'])) {
$query->where('usertype_subject2', 'like', '%' . $inputs['filter_category_name2'] . '%');
}
return $list;
if (!empty($inputs['filter_category_name3'])) {
$query->where('usertype_subject3', 'like', '%' . $inputs['filter_category_name3'] . '%');
}
$sortable = ['user_categoryid', 'sort_order', 'usertype_subject1', 'usertype_subject2', 'usertype_subject3', 'print_name', 'usertype_remarks'];
$sortColumn = $inputs['sort'] ?? 'user_categoryid';
if (!in_array($sortColumn, $sortable, true)) {
$sortColumn = 'user_categoryid';
}
$direction = strtolower($inputs['sort_type'] ?? 'asc');
if (!in_array($direction, ['asc', 'desc'], true)) {
$direction = 'asc';
}
$query->orderBy($sortColumn, $direction);
return !empty($inputs['isExport'])
? $query->get()
: $query->paginate(Utils::item_per_page);
}
public static function getByPk($pk)

View File

@ -1,105 +1,179 @@
<div class="form col-lg-12">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ Session::get('success') }}
</div>
@elseif(Session::has('error'))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-ban"></i> {{__('誤差')}}:</h4>
{!! Session::get('error') !!}
</div>
@elseif(isset($errorMsg))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-ban"></i> {{__('誤差')}}:</h4>
{!! $errorMsg !!}
<div class="card-body rv-usertype-form">
<div class="col-12 px-0">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ Session::get('success') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@elseif(Session::has('error'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{!! Session::get('error') !!}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@elseif(isset($errorMsg))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{!! $errorMsg !!}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
</div>
@if($isInfo || $isEdit)
<div class="rv-usertype-form__actions-top">
@if($isInfo)
<a href="{{ route('usertype_add') }}" class="btn btn-default btn-sm px-4">{{ __('登録') }}</a>
<a href="{{ route('usertype_edit', ['id' => $user_categoryid]) }}" class="btn btn-danger btn-sm px-4">{{ __('編集') }}</a>
@else
<button type="button" class="btn btn-default btn-sm px-4 register">{{ __('更新') }}</button>
@endif
</div>
@endif
</div>
<div class="col-lg-12 row sample03-wrapper no_padding_right mb20">
<div class="col-lg-10 col-xl-10 col-md-10 col-sm-9 col-xs-9 table_right no_padding_right">
<div class="scroll">
<form method="post">
<div class="btn_action mt-3">
@if($isInfo)
<a href="{{route('usertype_add')}}" class="btn btn-sm btn-success">{{__('登録')}}</a>
<a href="{{route('usertype_edit', ['id' => $user_categoryid])}}"
class="btn btn-sm btn-danger">{{__('編集')}}</a>
@else
<button type="submit" class="btn btn-sm btn-success register">{{__(key: '登録')}}</button>
<button type="button" class="btn btn-sm btn-danger register">{{__(key: '削除')}}</button>
@endif
<div class="rv-usertype-form__container">
<div class="rv-usertype-form__panel">
@if($isInfo || $isEdit)
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">{{ __('validation.attributes.user_categoryid') }}</label>
<div class="col-sm-8">
<input type="text" value="{{ $user_categoryid }}" class="form-control-plaintext" readonly>
</div>
</div>
@csrf
<table class="table dataTable">
<tbody>
@if($isInfo || $isEdit)
<tr>
<th style="width:200px; background-color:#fff;">{{__('validation.attributes.user_categoryid')}}</th>
<td>
<input type="text" value="{{$user_categoryid}}" class="form-control bg-white" readonly />
</td>
</tr>
@endif
<tr>
<th style="width:200px; background-color:#fff;">{{__('分類名')}}</th>
<td>
<input type="text" name="print_name" value="{{ old('print_name', $print_name ?? '') }}" class="form-control bg-white" placeholder="分類名" />
</td>
</tr>
<tr>
<th style="width:200px; background-color:#fff;">{{__('適用料率')}}</th>
<td>
<input type="text" name="usertype_money" value="{{ old('usertype_money', $usertype_money ?? '') }}" class="form-control bg-white" placeholder="適用料率" />
</td>
</tr>
<tr>
<th style="width:200px; background-color:#fff;">{{__('備考')}}</th>
<td>
<input type="text" name="usertype_remarks" value="{{ old('usertype_remarks', $usertype_remarks ?? '') }}" class="form-control bg-white" placeholder="備考" />
</td>
</tr>
<!-- 必要なら下記も追加 -->
<tr>
<th style="width:200px; background-color:#fff;">{{__('ソートオーダー')}}</th>
<td>
<input type="text" name="sort_order" value="{{ old('sort_order', $sort_order ?? '') }}" class="form-control bg-white" placeholder="ソートオーダー" />
</td>
</tr>
<tr>
<th style="width:200px; background-color:#fff;">{{__('分類名1')}}</th>
<td>
<input type="text" name="category_name1" value="{{ old('category_name1', $category_name1 ?? '') }}" class="form-control bg-white" placeholder="分類名1" />
</td>
</tr>
<tr>
<th style="width:200px; background-color:#fff;">{{__('分類名2')}}</th>
<td>
<input type="text" name="category_name2" value="{{ old('category_name2', $category_name2 ?? '') }}" class="form-control bg-white" placeholder="分類名2" />
</td>
</tr>
<tr>
<th style="width:200px; background-color:#fff;">{{__('分類名3')}}</th>
<td>
<input type="text" name="category_name3" value="{{ old('category_name3', $category_name3 ?? '') }}" class="form-control bg-white" placeholder="分類名3" />
</td>
</tr>
</tbody>
</table>
<div class="btn_action mt-3">
@if($isInfo)
<a href="{{route('usertype_add')}}" class="btn btn-sm btn-success">{{__('登録')}}</a>
<a href="{{route('usertype_edit', ['id' => $user_categoryid])}}"
class="btn btn-sm btn-danger">{{__('編集')}}</a>
@else
<button type="submit" class="btn btn-sm btn-success register">{{__('登録')}}</button>
<button type="button" class="btn btn-sm btn-danger register">{{__('削除')}}</button>
@endif
@endif
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">
{{ __('ソートオーダー') }}<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input type="text" name="sort_order" value="{{ old('sort_order', $sort_order ?? '') }}" class="form-control" placeholder="{{ __('ソートオーダー') }}">
</div>
</form>
</div>
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">
{{ __('分類名1') }}<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input type="text" name="usertype_subject1" value="{{ old('usertype_subject1', $usertype_subject1 ?? '') }}" class="form-control" placeholder="{{ __('分類名1') }}">
</div>
</div>
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">
{{ __('分類名2') }}<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input type="text" name="usertype_subject2" value="{{ old('usertype_subject2', $usertype_subject2 ?? '') }}" class="form-control" placeholder="{{ __('分類名2') }}">
</div>
</div>
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">{{ __('分類名3') }}</label>
<div class="col-sm-8">
<input type="text" name="usertype_subject3" value="{{ old('usertype_subject3', $usertype_subject3 ?? '') }}" class="form-control" placeholder="{{ __('分類名3') }}">
</div>
</div>
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">{{ __('印字名') }}</label>
<div class="col-sm-8">
<input type="text" name="print_name" value="{{ old('print_name', $print_name ?? '') }}" class="form-control" placeholder="{{ __('印字名') }}">
</div>
</div>
<div class="form-group row align-items-center">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">{{ __('適用料率') }}</label>
<div class="col-sm-8">
<input type="text" name="usertype_money" value="{{ old('usertype_money', $usertype_money ?? '') }}" class="form-control" placeholder="{{ __('適用料率') }}">
</div>
</div>
<div class="form-group row align-items-center mb-0">
<label class="col-sm-4 col-form-label font-weight-semibold text-sm-left">{{ __('備考') }}</label>
<div class="col-sm-8">
<textarea name="usertype_remarks" rows="2" class="form-control" placeholder="{{ __('備考') }}">{{ old('usertype_remarks', $usertype_remarks ?? '') }}</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="rv-usertype-form__actions-bottom">
@if($isInfo)
<a href="{{ route('usertype_add') }}" class="btn btn-default btn-sm px-4">{{ __('登録') }}</a>
<a href="{{ route('usertype_edit', ['id' => $user_categoryid]) }}" class="btn btn-danger btn-sm px-4">{{ __('編集') }}</a>
@else
<button type="button" class="btn btn-default btn-sm px-4 register">
{{ $isEdit ? __('更新') : __('登録') }}
</button>
@if($isEdit)
<button type="button" class="btn btn-default btn-sm px-4" id="btnDeleteInline">{{ __('削除') }}</button>
@endif
@endif
</div>
</div>
@push('styles')
<style>
.rv-usertype-form .font-weight-semibold{font-weight:600;}
.rv-usertype-form .form-group{margin-bottom:1.25rem;}
.rv-usertype-form .form-control{border-radius:.4rem;}
.rv-usertype-form__actions-top,
.rv-usertype-form__actions-bottom{display:flex;align-items:center;gap:.75rem;margin-bottom:1.5rem;}
.rv-usertype-form__container{display:flex;justify-content:flex-end;}
.rv-usertype-form__panel{
width:100%;
max-width:520px;
background:#fff;
border:1px solid #dee2e6;
border-radius:.5rem;
padding:2rem 2.5rem;
}
.rv-usertype-form__panel .col-form-label{font-size:.95rem;color:#555;}
.rv-usertype-form__panel .col-form-label{text-align:left;}
.rv-usertype-form__panel .form-control{font-size:.95rem;}
.rv-usertype-form__actions-bottom{margin-top:2rem;}
.rv-usertype-form .btn{min-width:90px;}
</style>
@endpush
@push('scripts')
@once
<script>
(function ($) {
$(function () {
var $form = $('#usertype-form');
if (!$form.length) {
return;
}
$('.register').off('click.usertypeConfirm').on('click.usertypeConfirm', function (e) {
e.preventDefault();
var submit = function () { $form.trigger('submit'); };
if (typeof $.confirm === 'function') {
$.confirm({
title: '確認ダイアログ。',
content: '登録してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: submit
},
いいえ: function () {}
}
});
} else if (window.confirm('登録してよろしいですか?')) {
submit();
}
});
});
})(window.jQuery);
</script>
@endonce
@endpush

View File

@ -1,6 +1,5 @@
@extends('layouts.app')
@section('title', '[東京都|〇〇駐輪場] 利用者分類マスタ')
@section('title', '利用者分類マスタ')
@section('content')
<!-- Content Header (Page header) -->
@ -8,14 +7,13 @@
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">[東京都|〇〇駐輪場] 利用者分類マスタ</h1>
<h1 class="m-0 text-dark">新規</h1>
</div><!-- /.col -->
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="./index2.html">XX様info(ホーム)</a></li>
<li class="breadcrumb-item"><a href="./index3.html">[東京都|〇〇駐輪場]</a></li>
<li class="breadcrumb-item">利用者分類マスタ</li>
<li class="breadcrumb-item active">[東京都|〇〇駐輪場] 利用者分類マスタ</li>
<li class="breadcrumb-item"><a href="{{route('home')}}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('usertypes') }}">利用者分類マスタ</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
@ -30,14 +28,15 @@
<div class="row">
<div class="col-lg-12">
<div class="card">
<form method="post" action="{{ route('usertype_add')}}" enctype="multipart/form-data">
<!-- TOKEN FORM -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" >
<!-- / .TOKEN FORM -->
@include('admin.usertypes._form',['isEdit'=>0,'isInfo'=>0])
</form>
</div>
<form id="usertype-form" method="post" action="{{ route('usertype_add')}}" enctype="multipart/form-data">
@csrf
<div class="card">
<div class="card-header d-flex justify-content-between">
<button type="button" class="btn btn-default btn-sm px-4 register">{{ __('登録') }}</button>
</div>
@include('admin.usertypes._form',['isEdit'=>0,'isInfo'=>0])
</div>
</form>
</div>
</div>
</div>
@ -45,3 +44,38 @@
<!-- /.content -->
@endsection
@push('scripts')
<script>
(function ($) {
$(function () {
var $form = $('#usertype-form');
if (!$form.length) {
return;
}
$('.register').on('click', function (e) {
e.preventDefault();
if (typeof $.confirm === 'function') {
$.confirm({
title: '確認ダイアログ。',
content: '登録してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: function () {
$form.trigger('submit');
}
},
いいえ: function () {}
}
});
} else if (window.confirm('登録してよろしいですか?')) {
$form.trigger('submit');
}
});
});
})(window.jQuery);
</script>
@endpush

View File

@ -1,5 +1,5 @@
@extends('layouts.app')
@section('title', '[東京都|〇〇駐輪場] 利用者分類マスタ')
@section('title', '利用者分類マスタ')
@section('content')
<div class="content-header">
<div class="container-fluid">
@ -16,29 +16,110 @@
</div>
</div>
</div>
<!-- /.content-header -->
<style>
.rv-filter-card .form-label{font-weight:600;color:#555;font-size:.85rem;}
.rv-filter-card .form-control-sm{border-radius:.25rem;}
.rv-toolbar .btn{min-width:82px;}
.rv-table-wrapper{background:#fff;border:1px solid #dee2e6;border-radius:.25rem;}
.rv-table tbody tr td{vertical-align:middle;}
.rv-table .op-cell{background:#f8f1e4;min-width:140px;}
.rv-table thead th{
white-space:nowrap;
background:#eeeeee;
text-decoration:none;
}
.rv-table thead th span,
.rv-table thead th .rv-sort-arrows,
.rv-table thead th .rv-sort-arrows .rv-arrow{
text-decoration:none !important;
}
.rv-table thead th.sortable{cursor:pointer;}
.rv-sort-arrows{
display:inline-flex;
align-items:center;
margin-left:4px;
gap:0;
letter-spacing:-5px; /* ↑↓を詰める */
font-size:16px;
}
.rv-sort-arrows .rv-arrow{
color:#b5b5b5;
font-size:16px;
line-height:1;
display:inline-block;
}
.rv-sort-arrows .rv-arrow.is-active{color:#000;}
@media (max-width: 767.98px){
.rv-toolbar{flex-direction:column;align-items:flex-start;gap:.5rem;}
}
</style>
<section class="content">
<div class="container-fluid">
<div class="row">
<form action="{{route('usertypes')}}" method="post" id="list-form">
<form action="{{ route('usertypes') }}" method="post" id="list-form" class="w-100">
@csrf
<input type="hidden" value="{{$sort}}" name="sort" id="sort">
<input type="hidden" value="{{$sort_type}}" name="sort_type" id="sort_type">
<input type="hidden" name="sort" id="sort" value="{{ $sort }}">
<input type="hidden" name="sort_type" id="sort_type" value="{{ $sort_type }}">
<div class="card rv-filter-card mb-3">
<div class="card-header bg-white font-weight-bold text-muted">
{{ __('絞り込み') }}
</div>
<div class="card-body pt-3 pb-2">
<div class="form-row">
<div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('ソートオーダー') }}</label>
<input type="text" name="filter_sort_order" class="form-control form-control-sm"
value="{{ $filter_sort_order ?? '' }}" placeholder="123456">
</div>
<div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名1') }}</label>
<input type="text" name="filter_category_name1" class="form-control form-control-sm"
value="{{ $filter_category_name1 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div>
<div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名2') }}</label>
<input type="text" name="filter_category_name2" class="form-control form-control-sm"
value="{{ $filter_category_name2 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div>
</div>
<div class="form-row">
<div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名3') }}</label>
<input type="text" name="filter_category_name3" class="form-control form-control-sm"
value="{{ $filter_category_name3 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div>
</div>
<div class="d-flex justify-content-start">
<button type="submit" class="btn btn-default btn-sm mr-2" id="btnFilterSubmit">{{ __('絞り込み') }}</button>
<button type="button" class="btn btn-default btn-sm" id="btnFilterReset">{{ __('解除') }}</button>
</div>
</div>
</div>
</form>
<div class="container-fluid mb20">
<div class="d-flex justify-content-between align-items-center">
<div>
<a href="{{route('usertype_add')}}" class="btn btn-sm btn-default mr10">{{__('新規')}}</a>
<button type="submit" class="btn btn-sm btn-default mr10" form="form_delete" name="delete"
id="delete">{{__('削除')}}</button>
<button type="submit" class="btn btn-sm btn-default mr10" name="export_csv" id="export_csv"
action="{{route('usertypes_export')}}">{{__('CSV出力')}}</button>
</div>
<div>
{{ $list->appends(['sort' => $sort, 'sort_type' => $sort_type])->links('pagination') }}
</div>
<form action="{{ route('usertypes_export') }}" method="post" id="form_export" class="d-none">
@csrf
<input type="hidden" name="sort" value="{{ $sort }}">
<input type="hidden" name="sort_type" value="{{ $sort_type }}">
<input type="hidden" name="filter_sort_order" value="{{ $filter_sort_order ?? '' }}">
<input type="hidden" name="filter_category_name1" value="{{ $filter_category_name1 ?? '' }}">
<input type="hidden" name="filter_category_name2" value="{{ $filter_category_name2 ?? '' }}">
<input type="hidden" name="filter_category_name3" value="{{ $filter_category_name3 ?? '' }}">
</form>
<div class="w-100 rv-toolbar mb-3 d-flex justify-content-between align-items-center">
<div class="btn-group" role="group" aria-label="toolbar-actions">
<a href="{{ route('usertype_add') }}" class="btn btn-default mr-2">{{ __('新規') }}</a>
<button type="button" class="btn btn-default mr-2" id="btnDeleteSelected">{{ __('削除') }}</button>
<button type="button" class="btn btn-default" id="btnExportCsv">{{ __('CSV出力') }}</button>
</div>
<div class="pagination-wrapper">
{{ $list->appends([
'sort' => $sort,
'sort_type' => $sort_type,
'filter_sort_order' => $filter_sort_order ?? '',
'filter_category_name1' => $filter_category_name1 ?? '',
'filter_category_name2' => $filter_category_name2 ?? '',
'filter_category_name3' => $filter_category_name3 ?? '',
])->links('pagination') }}
</div>
</div>
<div class="form col-lg-12">
@ -64,34 +145,75 @@
<div class="col-lg-12 sample03-wrapper no_padding_right mb20">
<form action="{{route('usertypes_delete')}}" method="post" id="form_delete">
@csrf
<div class="scroll">
<table class="table table-bordered table-hover rv-table mb-0 text-nowrap">
<div class="table-responsive rv-table-wrapper">
@php
$currentSort = $sort ?? '';
$currentDir = strtolower($sort_type ?? 'asc');
if (!in_array($currentDir, ['asc', 'desc'], true)) {
$currentDir = 'asc';
}
$sortClass = static function (string $key) use ($currentSort, $currentDir): string {
return $currentSort === $key
? 'sortable sorting_' . $currentDir
: 'sortable sorting';
};
$arrowState = static function (string $key) use ($currentSort, $currentDir): array {
$state = ['up' => '', 'down' => ''];
if ($currentSort === $key) {
if ($currentDir === 'asc') {
$state['up'] = 'is-active';
} elseif ($currentDir === 'desc') {
$state['down'] = 'is-active';
}
}
return $state;
};
$renderSortIcon = static function (array $state): string {
$up = $state['up'] ?? '';
$down = $state['down'] ?? '';
return '<span class="rv-sort-arrows"><span class="rv-arrow ' . $up . '">↑</span><span class="rv-arrow ' . $down . '">↓</span></span>';
};
@endphp
<table class="table table-striped table-hover rv-table mb-0 text-nowrap">
<thead>
<tr>
<th style="width:80px;">
<input type="checkbox" id="chkAll">
<span class="ml-1"></span>
</th>
<th class="sorting @if($sort == 'user_categoryid'){{$sort_type == 'asc' ? 'sorting_asc' : 'sorting_desc'}}@endif"
sort="user_categoryid">
<span>{{__('利用者分類ID')}}</span>
</th>
<th>
<span>{{__('ソート順')}}</span>
</th>
<th>
<span>{{__('分類名1')}}</span>
</th>
<th>
<span>{{__('分類名2')}}</span>
</th>
<th>
<span>{{__('分類名3')}}</span>
</th>
<th class="sorting @if($sort == 'print_name'){{$sort_type == 'asc' ? 'sorting_asc' : 'sorting_desc'}}@endif"
sort="print_name">
<span>{{__('分類名')}}</span>
</th>
@php $state = $arrowState('user_categoryid'); @endphp
<th class="{{ $sortClass('user_categoryid') }}" data-sort="user_categoryid">
<span>{{__('利用者分類ID')}}</span>
{!! $renderSortIcon($state) !!}
</th>
@php $state = $arrowState('sort_order'); @endphp
<th class="{{ $sortClass('sort_order') }}" data-sort="sort_order">
<span>{{__('ソートオーダー')}}</span>
{!! $renderSortIcon($state) !!}
</th>
@php $state = $arrowState('usertype_subject1'); @endphp
<th class="{{ $sortClass('usertype_subject1') }}" data-sort="usertype_subject1">
<span>{{__('分類名1')}}</span>
{!! $renderSortIcon($state) !!}
</th>
@php $state = $arrowState('usertype_subject2'); @endphp
<th class="{{ $sortClass('usertype_subject2') }}" data-sort="usertype_subject2">
<span>{{__('分類名2')}}</span>
{!! $renderSortIcon($state) !!}
</th>
@php $state = $arrowState('usertype_subject3'); @endphp
<th class="{{ $sortClass('usertype_subject3') }}" data-sort="usertype_subject3">
<span>{{__('分類名3')}}</span>
{!! $renderSortIcon($state) !!}
</th>
@php $state = $arrowState('print_name'); @endphp
<th class="{{ $sortClass('print_name') }}" data-sort="print_name">
<span>{{__('印字名')}}</span>
{!! $renderSortIcon($state) !!}
</th>
<th>
<span>{{__('適用料率')}}</span>
</th>
@ -101,42 +223,28 @@
</tr>
</thead>
<tbody>
@foreach($list as $item)
@forelse($list as $item)
<tr>
<td style="background-color:#faebd7;" class="op-cell">
<td class="op-cell">
<div class="d-flex align-items-center">
<input type="checkbox" class="mr-2 chkRow" name="pk[]"
value="{{ $item->user_categoryid }}">
<a href="{{ route('usertype_edit', ['id' => $item->user_categoryid]) }}"
class="btn btn-sm btn-default">編集</a>
<input type="checkbox" class="mr-2 chkRow" name="pk[]" value="{{ $item->user_categoryid }}">
<a href="{{ route('usertype_edit', ['id' => $item->user_categoryid]) }}" class="btn btn-xs btn-default">{{ __('編集') }}</a>
</div>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->user_categoryid, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->sort_order, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->category_name1, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->category_name2, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->category_name3, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->print_name, 0, 10) }}</span>
</td>
<td class='sm-item text-right'>
<span>{{ mb_substr($item->usertype_money, 0, 10) }}</span>
</td>
<td class='sm-item text-left'>
<span>{{ mb_substr($item->usertype_remarks, 0, 20) }}</span>
</td>
<td class="text-left">{{ $item->user_categoryid }}</td>
<td class="text-left">{{ $item->sort_order }}</td>
<td class="text-left">{{ $item->usertype_subject1 }}</td>
<td class="text-left">{{ $item->usertype_subject2 }}</td>
<td class="text-left">{{ $item->usertype_subject3 }}</td>
<td class="text-left">{{ $item->print_name }}</td>
<td class="text-right">{{ $item->usertype_money }}</td>
<td class="text-left">{{ $item->usertype_remarks }}</td>
</tr>
@endforeach
@empty
<tr>
<td colspan="9" class="text-center text-muted py-4">{{ __('データが存在しません。') }}</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@ -148,7 +256,6 @@
<script>
(function () {
// 全選択チェック
var chkAll = document.getElementById('chkAll');
var chks = document.getElementsByClassName('chkRow');
if (chkAll) {
@ -157,17 +264,89 @@
});
}
// 一括削除ボタン
var btn = document.getElementById('btnBulkDel');
var form = document.getElementById('bulkDeleteForm');
if (btn && form) {
btn.addEventListener('click', function () {
var any = false;
Array.prototype.forEach.call(chks, function (c) { if (c.checked) any = true; });
if (!any) { alert('削除対象の行を選択してください。'); return; }
if (confirm('選択した予約を削除します。よろしいですか?')) {
form.submit();
var filterReset = document.getElementById('btnFilterReset');
if (filterReset) {
filterReset.addEventListener('click', function () {
var form = document.getElementById('list-form');
if (!form) { return; }
Array.prototype.forEach.call(form.querySelectorAll('input[type="text"]'), function (input) {
input.value = '';
});
form.submit();
});
}
var sortHeaders = document.querySelectorAll('th[data-sort]');
if (sortHeaders.length) {
var sortInput = document.getElementById('sort');
var sortTypeInput = document.getElementById('sort_type');
var listForm = document.getElementById('list-form');
if (sortInput && sortTypeInput && listForm) {
Array.prototype.forEach.call(sortHeaders, function (th) {
th.addEventListener('click', function () {
var key = th.getAttribute('data-sort');
if (!key) { return; }
var nextDirection = 'asc';
if (sortInput.value === key) {
nextDirection = sortTypeInput.value === 'asc' ? 'desc' : 'asc';
}
sortInput.value = key;
sortTypeInput.value = nextDirection;
if (typeof listForm.requestSubmit === 'function') {
listForm.requestSubmit();
} else {
listForm.submit();
}
});
});
}
}
var deleteBtn = document.getElementById('btnDeleteSelected');
if (deleteBtn) {
deleteBtn.addEventListener('click', function () {
var anyChecked = false;
Array.prototype.forEach.call(chks, function (c) { if (c.checked) { anyChecked = true; } });
if (!anyChecked) {
alert('削除対象の行を選択してください。');
return;
}
if (window.jQuery && typeof window.jQuery.confirm === 'function') {
window.jQuery.confirm({
title: '確認ダイアログ。',
content: '削除してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: function () {
document.getElementById('form_delete').submit();
}
},
いいえ: function () {}
}
});
} else if (window.confirm('削除してよろしいですか?')) {
document.getElementById('form_delete').submit();
}
});
}
var exportBtn = document.getElementById('btnExportCsv');
if (exportBtn) {
exportBtn.addEventListener('click', function () {
var exportForm = document.getElementById('form_export');
var filterForm = document.getElementById('list-form');
if (!exportForm || !filterForm) { return; }
['filter_sort_order', 'filter_category_name1', 'filter_category_name2', 'filter_category_name3', 'sort', 'sort_type'].forEach(function (name) {
var source = filterForm.querySelector('[name="' + name + '"]');
var target = exportForm.querySelector('[name="' + name + '"]');
if (source && target) {
target.value = source.value;
}
});
exportForm.submit();
});
}
})();

View File

@ -245,7 +245,7 @@ Route::middleware('auth')->group(function () {
Route::match(['get', 'post'], '/usertypes/info/{id}', [UsertypeController::class, 'info'])->name('usertype_info')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/usertypes/delete', [UsertypeController::class, 'delete'])->name('usertypes_delete');
Route::match(['get', 'post'], '/usertypes/import', [UsertypeController::class, 'import'])->name('usertypes_import');
Route::get('/usertypes/export', [UsertypeController::class, 'export'])->name('usertypes_export');
Route::match(['get', 'post'], '/usertypes/export', [UsertypeController::class, 'export'])->name('usertypes_export');