【利用者分類マスタ】並び替え修正
All checks were successful
Deploy main / deploy (push) Successful in 23s

This commit is contained in:
你的名字 2025-10-07 18:15:32 +09:00
parent 870b944009
commit 30871b22ae
5 changed files with 212 additions and 100 deletions

View File

@ -15,9 +15,16 @@ class UsertypeController extends Controller
{ {
public function list(Request $request) 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'); $sort = $request->input('sort', 'user_categoryid');
if (!in_array($sort, $sortable, true)) { $allowSort = [
'user_categoryid',
'sort_order',
'usertype_subject1',
'usertype_subject2',
'usertype_subject3',
'print_name',
];
if (!in_array($sort, $allowSort, true)) {
$sort = 'user_categoryid'; $sort = 'user_categoryid';
} }
$sortType = strtolower($request->input('sort_type', 'asc')); $sortType = strtolower($request->input('sort_type', 'asc'));
@ -33,9 +40,9 @@ class UsertypeController extends Controller
]; ];
$filters = [ $filters = [
'filter_sort_order' => $request->input('filter_sort_order', ''), 'filter_sort_order' => $request->input('filter_sort_order', ''),
'filter_category_name1' => $request->input('filter_category_name1', ''), 'filter_usertype_subject1' => $request->input('filter_usertype_subject1', ''),
'filter_category_name2' => $request->input('filter_category_name2', ''), 'filter_usertype_subject2' => $request->input('filter_usertype_subject2', ''),
'filter_category_name3' => $request->input('filter_category_name3', ''), 'filter_usertype_subject3' => $request->input('filter_usertype_subject3', ''),
]; ];
$searchParams = array_merge($inputs, $filters); $searchParams = array_merge($inputs, $filters);
$viewData = $searchParams; $viewData = $searchParams;
@ -227,7 +234,10 @@ class UsertypeController extends Controller
'isExport' => 1, 'isExport' => 1,
'sort' => $request->input('sort', ''), 'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''), 'sort_type' => $request->input('sort_type', ''),
'filter_sort_order' => $request->input('filter_sort_order', ''),
'filter_usertype_subject1' => $request->input('filter_usertype_subject1', ''),
'filter_usertype_subject2' => $request->input('filter_usertype_subject2', ''),
'filter_usertype_subject3' => $request->input('filter_usertype_subject3', ''),
]; ];
$dataExport = Usertype::search($inputs); $dataExport = Usertype::search($inputs);

View File

@ -34,28 +34,36 @@ class Usertype extends Model
}); });
} }
public static function search($inputs) public static function search(array $inputs)
{ {
$query = self::query(); $query = self::query();
$table = (new self())->getTable();
if (!empty($inputs['filter_sort_order'])) { if (!empty($inputs['filter_sort_order'])) {
$query->where('sort_order', $inputs['filter_sort_order']); $query->where('sort_order', $inputs['filter_sort_order']);
} }
if (!empty($inputs['filter_category_name1'])) { if (!empty($inputs['filter_usertype_subject1'])) {
$query->where('usertype_subject1', 'like', '%' . $inputs['filter_category_name1'] . '%'); $query->where('usertype_subject1', 'like', '%' . $inputs['filter_usertype_subject1'] . '%');
} }
if (!empty($inputs['filter_category_name2'])) { if (!empty($inputs['filter_usertype_subject2'])) {
$query->where('usertype_subject2', 'like', '%' . $inputs['filter_category_name2'] . '%'); $query->where('usertype_subject2', 'like', '%' . $inputs['filter_usertype_subject2'] . '%');
} }
if (!empty($inputs['filter_category_name3'])) { if (!empty($inputs['filter_usertype_subject3'])) {
$query->where('usertype_subject3', 'like', '%' . $inputs['filter_category_name3'] . '%'); $query->where('usertype_subject3', 'like', '%' . $inputs['filter_usertype_subject3'] . '%');
} }
$sortable = ['user_categoryid', 'sort_order', 'usertype_subject1', 'usertype_subject2', 'usertype_subject3', 'print_name', 'usertype_remarks']; $sortable = [
$sortColumn = $inputs['sort'] ?? 'user_categoryid'; 'user_categoryid' => "{$table}.user_categoryid",
if (!in_array($sortColumn, $sortable, true)) { 'sort_order' => "{$table}.sort_order",
$sortColumn = 'user_categoryid'; 'usertype_subject1' => "{$table}.usertype_subject1",
} 'usertype_subject2' => "{$table}.usertype_subject2",
'usertype_subject3' => "{$table}.usertype_subject3",
'print_name' => "{$table}.print_name",
'usertype_remarks' => "{$table}.usertype_remarks",
];
$sortKey = $inputs['sort'] ?? 'user_categoryid';
$sortColumn = $sortable[$sortKey] ?? "{$table}.user_categoryid";
$direction = strtolower($inputs['sort_type'] ?? 'asc'); $direction = strtolower($inputs['sort_type'] ?? 'asc');
if (!in_array($direction, ['asc', 'desc'], true)) { if (!in_array($direction, ['asc', 'desc'], true)) {

View File

@ -28,9 +28,10 @@
<div class="rv-usertype-form__actions-top"> <div class="rv-usertype-form__actions-top">
@if($isInfo) @if($isInfo)
<a href="{{ route('usertype_add') }}" class="btn btn-default btn-sm px-4">{{ __('登録') }}</a> <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> <a href="{{ route('usertype_edit', ['id' => $user_categoryid]) }}" class="btn btn-default btn-sm px-4">{{ __('編集') }}</a>
@else @else
<button type="button" class="btn btn-default btn-sm px-4 register">{{ __('更新') }}</button> <button type="button" class="btn btn-default btn-sm px-4 register">{{ __('登録') }}</button>
@if($isEdit)<button type="button" class="btn btn-default btn-sm px-4 js-inline-delete">{{ __('削除') }}</button>@endif
@endif @endif
</div> </div>
@endif @endif
@ -106,13 +107,13 @@
<div class="rv-usertype-form__actions-bottom"> <div class="rv-usertype-form__actions-bottom">
@if($isInfo) @if($isInfo)
<a href="{{ route('usertype_add') }}" class="btn btn-default btn-sm px-4">{{ __('登録') }}</a> <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> <a href="{{ route('usertype_edit', ['id' => $user_categoryid]) }}" class="btn btn-default btn-sm px-4">{{ __('編集') }}</a>
@else @else
<button type="button" class="btn btn-default btn-sm px-4 register"> <button type="button" class="btn btn-default btn-sm px-4 register">
{{ $isEdit ? __('更新') : __('登録') }} {{ $isEdit ? __('登録') : __('登録') }}
</button> </button>
@if($isEdit) @if($isEdit)
<button type="button" class="btn btn-default btn-sm px-4" id="btnDeleteInline">{{ __('削除') }}</button> <button type="button" class="btn btn-default btn-sm px-4 js-inline-delete">{{ __('削除') }}</button>
@endif @endif
@endif @endif
</div> </div>
@ -151,9 +152,10 @@
if (!$form.length) { if (!$form.length) {
return; return;
} }
$('.register').off('click.usertypeConfirm').on('click.usertypeConfirm', function (e) { $('.register').off('click.usertypeConfirm').on('click.usertypeConfirm', function (e) {
e.preventDefault(); e.preventDefault();
var submit = function () { $form.trigger('submit'); }; var submitForm = function () { $form.trigger('submit'); };
if (typeof $.confirm === 'function') { if (typeof $.confirm === 'function') {
$.confirm({ $.confirm({
title: '確認ダイアログ。', title: '確認ダイアログ。',
@ -163,15 +165,41 @@
text: 'はい', text: 'はい',
btnClass: 'btn-primary', btnClass: 'btn-primary',
keys: ['enter'], keys: ['enter'],
action: submit action: submitForm
}, },
いいえ: function () {} いいえ: function () {}
} }
}); });
} else if (window.confirm('登録してよろしいですか?')) { } else if (window.confirm('登録してよろしいですか?')) {
submit(); submitForm();
} }
}); });
var $deleteBtn = $('#btnDeleteInline');
var $deleteForm = $('#usertype-delete-form');
if ($deleteBtn.length && $deleteForm.length) {
$deleteBtn.off('click.usertypeDelete').on('click.usertypeDelete', function (e) {
e.preventDefault();
var submitDelete = function () { $deleteForm.trigger('submit'); };
if (typeof $.confirm === 'function') {
$.confirm({
title: '確認ダイアログ。',
content: '削除してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: submitDelete
},
いいえ: function () {}
}
});
} else if (window.confirm('削除してよろしいですか?')) {
submitDelete();
}
});
}
}); });
})(window.jQuery); })(window.jQuery);
</script> </script>

View File

@ -24,17 +24,79 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
{{-- 上部の操作ボタン(登録/削除) --}}
{{-- カード本体 --}} {{-- カード本体 --}}
<div class="card"> <div class="card">
{{-- 既存の共通フォームをそのまま利用 --}} <form id="usertype-form" method="post" action="{{ route('usertype_edit', ['id' => $user_categoryid]) }}">
@csrf
@include('admin.usertypes._form', ['isEdit' => 1, 'isInfo' => 0]) @include('admin.usertypes._form', ['isEdit' => 1, 'isInfo' => 0])
</form> </form>
<form id="usertype-delete-form" method="post" action="{{ route('usertypes_delete', ['id' => $user_categoryid]) }}" class="d-none">
@csrf
<input type="hidden" name="pk[]" value="{{ $user_categoryid }}">
</form>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
@endsection @endsection
@push('scripts')
<script>
(function ($) {
$(function () {
var $registerBtn = $('.register');
var $editForm = $('#usertype-form');
if ($registerBtn.length && $editForm.length) {
$registerBtn.off('click.usertypeConfirm').on('click.usertypeConfirm', function (e) {
e.preventDefault();
var submitEdit = function () { $editForm.trigger('submit'); };
if (typeof $.confirm === 'function') {
$.confirm({
title: '確認ダイアログ。',
content: '登録してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: submitEdit
},
いいえ: function () {}
}
});
} else if (window.confirm('登録してよろしいですか?')) {
submitEdit();
}
});
}
var $deleteBtn = $('.js-inline-delete');;
var $deleteForm = $('#usertype-delete-form');
if ($deleteBtn.length && $deleteForm.length) {
$deleteBtn.off('click.usertypeDelete').on('click.usertypeDelete', function (e) {
e.preventDefault();
var submitDelete = function () { $deleteForm.trigger('submit'); };
if (typeof $.confirm === 'function') {
$.confirm({
title: '確認ダイアログ。',
content: '削除してよろしいですか?はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: submitDelete
},
いいえ: function () {}
}
});
} else if (window.confirm('削除してよろしいですか?')) {
submitDelete();
}
});
}
});
})(window.jQuery);
</script>
@endpush

View File

@ -39,7 +39,7 @@
align-items:center; align-items:center;
margin-left:4px; margin-left:4px;
gap:0; gap:0;
letter-spacing:-5px; /* ↑↓を詰める */ letter-spacing:-3px; /* ↑↓を詰める */
font-size:16px; font-size:16px;
} }
.rv-sort-arrows .rv-arrow{ .rv-sort-arrows .rv-arrow{
@ -49,6 +49,7 @@
display:inline-block; display:inline-block;
} }
.rv-sort-arrows .rv-arrow.is-active{color:#000;} .rv-sort-arrows .rv-arrow.is-active{color:#000;}
.rv-table thead th a{color:#000 !important;}
@media (max-width: 767.98px){ @media (max-width: 767.98px){
.rv-toolbar{flex-direction:column;align-items:flex-start;gap:.5rem;} .rv-toolbar{flex-direction:column;align-items:flex-start;gap:.5rem;}
} }
@ -73,20 +74,20 @@
</div> </div>
<div class="form-group col-xl-4 col-lg-4 col-md-6"> <div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名1') }}</label> <label class="form-label">{{ __('分類名1') }}</label>
<input type="text" name="filter_category_name1" class="form-control form-control-sm" <input type="text" name="filter_usertype_subject1" class="form-control form-control-sm"
value="{{ $filter_category_name1 ?? '' }}" placeholder="{{ __('キーワード...') }}"> value="{{ $filter_usertype_subject1 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div> </div>
<div class="form-group col-xl-4 col-lg-4 col-md-6"> <div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名2') }}</label> <label class="form-label">{{ __('分類名2') }}</label>
<input type="text" name="filter_category_name2" class="form-control form-control-sm" <input type="text" name="filter_usertype_subject2" class="form-control form-control-sm"
value="{{ $filter_category_name2 ?? '' }}" placeholder="{{ __('キーワード...') }}"> value="{{ $filter_usertype_subject2 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-xl-4 col-lg-4 col-md-6"> <div class="form-group col-xl-4 col-lg-4 col-md-6">
<label class="form-label">{{ __('分類名3') }}</label> <label class="form-label">{{ __('分類名3') }}</label>
<input type="text" name="filter_category_name3" class="form-control form-control-sm" <input type="text" name="filter_usertype_subject3" class="form-control form-control-sm"
value="{{ $filter_category_name3 ?? '' }}" placeholder="{{ __('キーワード...') }}"> value="{{ $filter_usertype_subject3 ?? '' }}" placeholder="{{ __('キーワード...') }}">
</div> </div>
</div> </div>
<div class="d-flex justify-content-start"> <div class="d-flex justify-content-start">
@ -101,9 +102,9 @@
<input type="hidden" name="sort" value="{{ $sort }}"> <input type="hidden" name="sort" value="{{ $sort }}">
<input type="hidden" name="sort_type" value="{{ $sort_type }}"> <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_sort_order" value="{{ $filter_sort_order ?? '' }}">
<input type="hidden" name="filter_category_name1" value="{{ $filter_category_name1 ?? '' }}"> <input type="hidden" name="filter_usertype_subject1" value="{{ $filter_usertype_subject1 ?? '' }}">
<input type="hidden" name="filter_category_name2" value="{{ $filter_category_name2 ?? '' }}"> <input type="hidden" name="filter_usertype_subject2" value="{{ $filter_usertype_subject2 ?? '' }}">
<input type="hidden" name="filter_category_name3" value="{{ $filter_category_name3 ?? '' }}"> <input type="hidden" name="filter_usertype_subject3" value="{{ $filter_usertype_subject3 ?? '' }}">
</form> </form>
<div class="w-100 rv-toolbar mb-3 d-flex justify-content-between align-items-center"> <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"> <div class="btn-group" role="group" aria-label="toolbar-actions">
@ -116,9 +117,9 @@
'sort' => $sort, 'sort' => $sort,
'sort_type' => $sort_type, 'sort_type' => $sort_type,
'filter_sort_order' => $filter_sort_order ?? '', 'filter_sort_order' => $filter_sort_order ?? '',
'filter_category_name1' => $filter_category_name1 ?? '', 'filter_usertype_subject1' => $filter_usertype_subject1 ?? '',
'filter_category_name2' => $filter_category_name2 ?? '', 'filter_usertype_subject2' => $filter_usertype_subject2 ?? '',
'filter_category_name3' => $filter_category_name3 ?? '', 'filter_usertype_subject3' => $filter_usertype_subject3 ?? '',
])->links('pagination') }} ])->links('pagination') }}
</div> </div>
</div> </div>
@ -176,6 +177,23 @@
$down = $state['down'] ?? ''; $down = $state['down'] ?? '';
return '<span class="rv-sort-arrows"><span class="rv-arrow ' . $up . '">↑</span><span class="rv-arrow ' . $down . '">↓</span></span>'; return '<span class="rv-sort-arrows"><span class="rv-arrow ' . $up . '">↑</span><span class="rv-arrow ' . $down . '">↓</span></span>';
}; };
$queryParams = [
'filter_sort_order' => $filter_sort_order ?? null,
'filter_usertype_subject1' => $filter_usertype_subject1 ?? null,
'filter_usertype_subject2' => $filter_usertype_subject2 ?? null,
'filter_usertype_subject3' => $filter_usertype_subject3 ?? null,
];
$queryParams = array_filter($queryParams, static function ($value) {
return !is_null($value) && $value !== '';
});
$buildSortUrl = static function (string $column, string $currentSort, string $currentDir, array $baseParams): string {
$nextDir = ($currentSort === $column && $currentDir === 'asc') ? 'desc' : 'asc';
return route('usertypes', array_merge($baseParams, [
'sort' => $column,
'sort_type' => $nextDir,
'page' => 1,
]));
};
@endphp @endphp
<table class="table table-striped table-hover rv-table mb-0 text-nowrap"> <table class="table table-striped table-hover rv-table mb-0 text-nowrap">
<thead> <thead>
@ -185,34 +203,46 @@
<span class="ml-1"></span> <span class="ml-1"></span>
</th> </th>
@php $state = $arrowState('user_categoryid'); @endphp @php $state = $arrowState('user_categoryid'); @endphp
<th class="{{ $sortClass('user_categoryid') }}" data-sort="user_categoryid"> <th class="{{ $sortClass('user_categoryid') }}">
<a href="{{ $buildSortUrl('user_categoryid', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('利用者分類ID') }}</span> <span>{{ __('利用者分類ID') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
@php $state = $arrowState('sort_order'); @endphp @php $state = $arrowState('sort_order'); @endphp
<th class="{{ $sortClass('sort_order') }}" data-sort="sort_order"> <th class="{{ $sortClass('sort_order') }}">
<a href="{{ $buildSortUrl('sort_order', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('ソートオーダー') }}</span> <span>{{ __('ソートオーダー') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
@php $state = $arrowState('usertype_subject1'); @endphp @php $state = $arrowState('usertype_subject1'); @endphp
<th class="{{ $sortClass('usertype_subject1') }}" data-sort="usertype_subject1"> <th class="{{ $sortClass('usertype_subject1') }}">
<a href="{{ $buildSortUrl('usertype_subject1', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('分類名1') }}</span> <span>{{ __('分類名1') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
@php $state = $arrowState('usertype_subject2'); @endphp @php $state = $arrowState('usertype_subject2'); @endphp
<th class="{{ $sortClass('usertype_subject2') }}" data-sort="usertype_subject2"> <th class="{{ $sortClass('usertype_subject2') }}">
<a href="{{ $buildSortUrl('usertype_subject2', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('分類名2') }}</span> <span>{{ __('分類名2') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
@php $state = $arrowState('usertype_subject3'); @endphp @php $state = $arrowState('usertype_subject3'); @endphp
<th class="{{ $sortClass('usertype_subject3') }}" data-sort="usertype_subject3"> <th class="{{ $sortClass('usertype_subject3') }}">
<a href="{{ $buildSortUrl('usertype_subject3', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('分類名3') }}</span> <span>{{ __('分類名3') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
@php $state = $arrowState('print_name'); @endphp @php $state = $arrowState('print_name'); @endphp
<th class="{{ $sortClass('print_name') }}" data-sort="print_name"> <th class="{{ $sortClass('print_name') }}">
<a href="{{ $buildSortUrl('print_name', $currentSort, $currentDir, $queryParams) }}" class="d-inline-flex align-items-center text-reset">
<span>{{ __('印字名') }}</span> <span>{{ __('印字名') }}</span>
{!! $renderSortIcon($state) !!} {!! $renderSortIcon($state) !!}
</a>
</th> </th>
<th> <th>
<span>{{__('適用料率')}}</span> <span>{{__('適用料率')}}</span>
@ -276,32 +306,6 @@
}); });
} }
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'); var deleteBtn = document.getElementById('btnDeleteSelected');
if (deleteBtn) { if (deleteBtn) {
deleteBtn.addEventListener('click', function () { deleteBtn.addEventListener('click', function () {
@ -339,7 +343,7 @@
var exportForm = document.getElementById('form_export'); var exportForm = document.getElementById('form_export');
var filterForm = document.getElementById('list-form'); var filterForm = document.getElementById('list-form');
if (!exportForm || !filterForm) { return; } if (!exportForm || !filterForm) { return; }
['filter_sort_order', 'filter_category_name1', 'filter_category_name2', 'filter_category_name3', 'sort', 'sort_type'].forEach(function (name) { ['filter_sort_order', 'filter_usertype_subject1', 'filter_usertype_subject2', 'filter_usertype_subject3', 'sort', 'sort_type'].forEach(function (name) {
var source = filterForm.querySelector('[name="' + name + '"]'); var source = filterForm.querySelector('[name="' + name + '"]');
var target = exportForm.querySelector('[name="' + name + '"]'); var target = exportForm.querySelector('[name="' + name + '"]');
if (source && target) { if (source && target) {