krgm.so-manager-dev.com/resources/views/admin/news/list.blade.php
你的名字 5b6b4faa14
All checks were successful
Deploy main / deploy (push) Successful in 22s
【最新ニュース登録】ダイアログ重複表示修正
2025-10-27 22:55:07 +09:00

235 lines
9.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.app')
@section('title', '最新ニュース登録')
@section('content')
@php
$modeLabel = [0=>'非表示', 1=>'公開', 2=>'下書き', 3=>'自動公開'];
$curSort = request('sort');
$curDir = strtolower(request('dir', 'desc'));
// DataTables と同一のクラスを付与(未選択: sorting / 昇順: sorting_asc / 降順: sorting_desc
$thClass = function(string $key) use ($curSort, $curDir) {
if ($curSort !== $key) return 'sorting';
return $curDir === 'asc' ? 'sorting_asc' : 'sorting_desc';
};
// クリック時に昇降をトグル
$urlFor = function(string $key) use ($curSort, $curDir) {
$next = ($curSort === $key && $curDir === 'asc') ? 'desc' : 'asc';
return route('news', array_merge(request()->except('page'), ['sort'=>$key, 'dir'=>$next]));
};
@endphp
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">最新ニュース登録</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">最新ニュース登録</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- フラッシュメッセージ --}}
@if(session('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ session('success') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@endif
@if(session('error'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ session('error') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@endif
<div class="card">
{{-- ヘッダー:新規/削除 --}}
<div class="card-header d-flex align-items-center">
<a href="{{ route('news_add') }}" class="btn btn-default mr-2">新規</a>
<button type="button" class="btn btn-default" id="delete_edit">削除</button>
</div>
{{-- 一覧テーブル --}}
<div class="card-body p-0">
<form id="form_delete" method="POST" action="{{ route('news_delete') }}">
@csrf
<div class="table-responsive">
<table class="table table-bordered text-nowrap mb-0 table-news dataTable">
<thead class="thead-light">
<tr>
<th class="col-actions">
<div class="actions-wrap">
<input type="checkbox" id="check-all">
<span class="text-muted" style="font-weight:normal;"></span>
</div>
</th>
{{-- 並び替え可能カラムDataTables と同じクラスを使用) --}}
<th class="w-id {{ $thClass('id') }}">
<a href="{{ $urlFor('id') }}" class="header-link">ニュースID</a>
</th>
<th class="{{ $thClass('news') }}">
<a href="{{ $urlFor('news') }}" class="header-link">ニュース内容</a>
</th>
<th class="w-datetime {{ $thClass('open_datetime') }}">
<a href="{{ $urlFor('open_datetime') }}" class="header-link">公開日時</a>
</th>
<th class="w-url">リンクURL</th>
<th class="w-img">画像1URL</th>
<th class="w-img">画像2URL</th>
<th class="w-mode {{ $thClass('mode') }}">
<a href="{{ $urlFor('mode') }}" class="header-link">表示モード</a>
</th>
<th class="w-created">登録日時</th>
<th class="w-updated">更新日時</th>
</tr>
</thead>
<tbody>
@forelse($rows as $r)
<tr>
{{-- 統合セル--}}
<td style="background: #faebd7;">
<div class="actions-wrap">
<input type="checkbox" name="ids[]" value="{{ $r->id }}">
<a href="{{ route('news_edit', ['id' => $r->id]) }}"
class="btn btn-sm btn-default ml10">編集</a>
</div>
</td>
{{-- データ本体 --}}
<td class="w-id">{{ $r->id }}</td>
<td class="one-line" title="{{ $r->news }}">{{ \Illuminate\Support\Str::limit($r->news, 80) }}</td>
<td class="w-datetime">{{ $r->open_datetime }}</td>
<td class="w-url one-line" title="{{ $r->link_url }}">{{ $r->link_url }}</td>
<td class="w-img one-line" title="{{ $r->image1_filename }}">{{ $r->image1_filename }}</td>
<td class="w-img one-line" title="{{ $r->image2_filename }}">{{ $r->image2_filename }}</td>
<td class="w-mode">{{ $modeLabel[$r->mode] ?? $r->mode }}</td>
<td class="w-created">{{ $r->created_at }}</td>
<td class="w-updated">{{ $r->updated_at }}</td>
</tr>
@empty
<tr>
<td colspan="10" class="text-center text-muted">データがありません。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- フッター:ページネーション右寄せ --}}
<div class="d-flex align-items-center p-3">
<div class="ml-auto">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<!-- jQuery Confirm存在すれば使用。無ければ下のスクリプトで標準confirmへフォールバック -->
<link rel="stylesheet" href="{{ asset('plugins/jquery-confirm/jquery-confirm.min.css') }}">
<script src="{{ asset('plugins/jquery-confirm/jquery-confirm.min.js') }}"></script>
<style>
/* 見出しの文字色を黒(リンクも黒・下線なし) */
.table-news thead th .header-link { color:#212529!important;text-decoration:none!important;display:block;white-space:nowrap;padding-right:1.8rem; }
/* DataTables の矢印位置を統一 */
.table-news.dataTable thead th.sorting,
.table-news.dataTable thead th.sorting_asc,
.table-news.dataTable thead th.sorting_desc { background-repeat:no-repeat;background-position:right .6rem center!important;padding-right:1.8rem; }
</style>
<script>
(function(){
// ▼ 全選択チェックボックスの処理
document.getElementById('check-all')?.addEventListener('change', function(e){
document.querySelectorAll('input[name="ids[]"]').forEach(function(el){ el.checked = e.target.checked; });
});
// ▼ 共通:削除対象が未選択の場合のアラート表示
function showNoSelection(){
if (window.jQuery && window.$ && $.confirm) {
$.confirm({
title: '確認ダイアログ。',
content: '削除対象が選択されていません。',
buttons: {
ok: { text: 'はい', btnClass: 'btn-primary' },
いいえ: function () {}
}
});
} else {
alert('削除対象が選択されていません。');
}
}
// ▼ 共通:削除確認ダイアログ表示
function showDeleteConfirm(onYes){
if (window.jQuery && window.$ && $.confirm) {
$.confirm({
title: '削除確認',
content: '削除してよろしいですか?',
buttons: {
ok: { text: 'はい', btnClass: 'btn-primary', action: function(){ if (typeof onYes==='function') onYes(); } },
いいえ: function () {}
}
});
} else {
if (confirm('削除してよろしいですか?')) { if (typeof onYes==='function') onYes(); }
}
}
// ▼ 削除ボタン(#delete_editのクリックイベント処理
// ①選択チェック → ②確認ダイアログ → ③削除フォーム送信
const delBtn = document.getElementById('delete_edit');
if (delBtn && delBtn.dataset.bound !== '1') {
delBtn.dataset.bound = '1'; // 二重バインド防止
// 捕捉段階で処理を実行し、他のリスナーによる重複ダイアログを防止
delBtn.addEventListener('click', function(e){
e.preventDefault();
e.stopPropagation();
if (e.stopImmediatePropagation) e.stopImmediatePropagation();
const checked = document.querySelectorAll('input[name="ids[]"]:checked').length;
if (!checked) return showNoSelection();
const form = document.getElementById('form_delete');
if (!form) return;
showDeleteConfirm(function(){
// jQuery 側の submit イベントを回避して、ネイティブでフォーム送信
form.submit();
});
}, true);
}
// ▼ フラッシュメッセージ成功エラーを5秒後に自動で非表示化
setTimeout(function(){
document.querySelectorAll('.alert-dismissible')?.forEach(function(el){
el.classList.remove('show');
el.style.display='none';
});
}, 5000);
})();
</script>
@endsection