【最新ニュース登録】不具合修正
All checks were successful
Deploy main / deploy (push) Successful in 21s

This commit is contained in:
你的名字 2025-12-23 23:51:15 +09:00
parent 01aa7ad404
commit e7d517edff
3 changed files with 257 additions and 203 deletions

View File

@ -146,7 +146,7 @@ class NewsController extends Controller
if ($request->isMethod('post')) { if ($request->isMethod('post')) {
$messages = [ $messages = [
'required' => ':attribute は、必ず入力してください。', 'required' => ':attribute は、必ず入力してください。',
'open_datetime.date_format' => '公開日時は :format 形式YYYY-MM-DD HH:MM:SS)で入力してください。', 'open_datetime.date_format' => '公開日時は :format 形式YYYY-MM-DD)で入力してください。',
]; ];
$attributes = [ $attributes = [
'news' => 'ニュース内容', 'news' => 'ニュース内容',
@ -155,7 +155,7 @@ class NewsController extends Controller
]; ];
$v = $request->validate([ $v = $request->validate([
'news' => 'required|string', 'news' => 'required|string',
'open_datetime' => 'required|date_format:Y-m-d H:i:s', 'open_datetime' => 'required|date_format:Y-m-d',
'link_url' => 'nullable|string|max:255', 'link_url' => 'nullable|string|max:255',
'image1_filename' => 'nullable|string|max:255', 'image1_filename' => 'nullable|string|max:255',
'image2_filename' => 'nullable|string|max:255', 'image2_filename' => 'nullable|string|max:255',
@ -165,7 +165,7 @@ class NewsController extends Controller
// 更新 // 更新
DB::table($this->table)->where($this->pk, $id)->update([ DB::table($this->table)->where($this->pk, $id)->update([
'news' => $v['news'], 'news' => $v['news'],
'open_datetime' => $v['open_datetime'], 'open_datetime' => $v['open_datetime'] . ' 00:00:00',
'link_url' => $v['link_url'] ?? null, 'link_url' => $v['link_url'] ?? null,
'image1_filename' => $v['image1_filename'] ?? null, 'image1_filename' => $v['image1_filename'] ?? null,
'image2_filename' => $v['image2_filename'] ?? null, 'image2_filename' => $v['image2_filename'] ?? null,

View File

@ -2,11 +2,13 @@
@section('title', 'ニュース新規作成') @section('title', 'ニュース新規作成')
@section('content') @section('content')
{{-- コンテンツヘッダー(パンくず) --}} {{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header"> <div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">新規</h1></div> <div class="col-lg-6">
<h1 class="m-0 text-dark">新規</h1>
</div>
<div class="col-lg-6"> <div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm"> <ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li> <li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
@ -16,14 +18,16 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
{{-- バリデーションエラー表示 --}} {{-- バリデーションエラー表示 --}}
@if ($errors->any()) @if ($errors->any())
<div class="alert alert-danger"><ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul></div> <div class="alert alert-danger">
<ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul>
</div>
@endif @endif
{{-- 成功メッセージ表示 --}} {{-- 成功メッセージ表示 --}}
@ -43,10 +47,14 @@
<textarea name="news" class="form-control" rows="8" required>{{ old('news') }}</textarea> <textarea name="news" class="form-control" rows="8" required>{{ old('news') }}</textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>公開日時 <span class="text-danger">*</span></label> <label>公開日時<span class="text-danger">*</span></label>
<input type="text" name="open_datetime" class="form-control" placeholder="YYYY-MM-DD HH:MM:SS" <input type="date"
value="{{ old('open_datetime') }}" required> name="open_date"
class="form-control"
value="{{ old('open_date') }}"
required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>リンクURL</label> <label>リンクURL</label>
<input type="text" name="link_url" class="form-control" value="{{ old('link_url') }}"> <input type="text" name="link_url" class="form-control" value="{{ old('link_url') }}">
@ -77,13 +85,16 @@
<div class="imgbox-title">画像1</div> <div class="imgbox-title">画像1</div>
<div class="mb-2"> <div class="mb-2">
<label class="small text-muted d-block mb-1">画像1URLスペース</label> <label class="small text-muted d-block mb-1">画像1URLスペース</label>
<input type="text" name="image1_filename" id="image1_url" class="form-control" placeholder="http(s)://..." value="{{ old('image1_filename') }}"> <input type="text" name="image1_filename" id="image1_url" class="form-control"
placeholder="https://..." value="{{ old('image1_filename') }}">
</div> </div>
<div> <div>
<label class="small text-muted d-block mb-1">画像1表示スペース</label> <label class="small text-muted d-block mb-1">画像1表示スペース</label>
<div class="imgbox-preview"> <div class="imgbox-preview">
<img id="image1_preview" src="{{ old('image1_filename') }}" alt="" style="display: {{ old('image1_filename') ? 'block' : 'none' }};"> <img id="image1_preview" src="{{ old('image1_filename') }}" alt=""
<span id="image1_placeholder" class="text-muted" style="display: {{ old('image1_filename') ? 'none' : 'block' }};">プレビューなし</span> style="display: {{ old('image1_filename') ? 'block' : 'none' }};">
<span id="image1_placeholder" class="text-muted"
style="display: {{ old('image1_filename') ? 'none' : 'block' }};">プレビューなし</span>
</div> </div>
</div> </div>
</div> </div>
@ -94,13 +105,16 @@
<div class="imgbox-title">画像2</div> <div class="imgbox-title">画像2</div>
<div class="mb-2"> <div class="mb-2">
<label class="small text-muted d-block mb-1">画像2URLスペース</label> <label class="small text-muted d-block mb-1">画像2URLスペース</label>
<input type="text" name="image2_filename" id="image2_url" class="form-control" placeholder="http(s)://..." value="{{ old('image2_filename') }}"> <input type="text" name="image2_filename" id="image2_url" class="form-control"
placeholder="https://..." value="{{ old('image2_filename') }}">
</div> </div>
<div> <div>
<label class="small text-muted d-block mb-1">画像2表示スペース</label> <label class="small text-muted d-block mb-1">画像2表示スペース</label>
<div class="imgbox-preview"> <div class="imgbox-preview">
<img id="image2_preview" src="{{ old('image2_filename') }}" alt="" style="display: {{ old('image2_filename') ? 'block' : 'none' }};"> <img id="image2_preview" src="{{ old('image2_filename') }}" alt=""
<span id="image2_placeholder" class="text-muted" style="display: {{ old('image2_filename') ? 'none' : 'block' }};">プレビューなし</span> style="display: {{ old('image2_filename') ? 'block' : 'none' }};">
<span id="image2_placeholder" class="text-muted"
style="display: {{ old('image2_filename') ? 'none' : 'block' }};">プレビューなし</span>
</div> </div>
</div> </div>
</div> </div>
@ -110,94 +124,120 @@
{{-- 表示モード(デフォルト:非表示) --}} {{-- 表示モード(デフォルト:非表示) --}}
<div class="form-group mt-3"> <div class="form-group mt-3">
<label class="d-block">表示モード <span class="text-danger">*</span></label> <label class="d-block">表示モード <span class="text-danger">*</span></label>
{{-- 下書き(非表示) --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_draft" value="2" required <input class="form-check-input" type="radio" name="mode" id="mode_draft" value="1" required
@checked(old('mode','0')=='2')> @checked(old('mode', $row->mode ?? '') == '1')>
<label class="form-check-label" for="mode_draft">下書き(非表示)</label> <label class="form-check-label" for="mode_draft">下書き(非表示)</label>
</div> </div>
{{-- 公開 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_public" value="1" <input class="form-check-input" type="radio" name="mode" id="mode_public" value="2" @checked(old('mode', $row->mode ?? '') == '2')>
@checked(old('mode','0')=='1')>
<label class="form-check-label" for="mode_public">公開</label> <label class="form-check-label" for="mode_public">公開</label>
</div> </div>
{{-- 自動公開 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_auto" value="3" <input class="form-check-input" type="radio" name="mode" id="mode_auto" value="3" @checked(old('mode', $row->mode ?? '') == '3')>
@checked(old('mode','0')=='3')>
<label class="form-check-label" for="mode_auto">自動公開</label> <label class="form-check-label" for="mode_auto">自動公開</label>
</div> </div>
{{-- 非表示 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_hidden" value="0" <input class="form-check-input" type="radio" name="mode" id="mode_hidden" value="4" @checked(old('mode', $row->mode ?? '') == '4')>
@checked(old('mode','0')=='0')>
<label class="form-check-label" for="mode_hidden">非表示</label> <label class="form-check-label" for="mode_hidden">非表示</label>
</div> </div>
</div> </div>
<div class="text-right"> <div class="text-left">
<a href="{{ route('news') }}" class="btn btn-default">戻る</a>
<!-- 変更点: class="register" を付与して app.js の汎用確認を使用 -->
<button type="button" class="btn btn-default register" id="register-btn">登録</button> <button type="button" class="btn btn-default register" id="register-btn">登録</button>
<!-- 変更点: class="register" を付与して app.js の汎用確認を使用 -->
<a href="{{ route('news') }}" class="btn btn-default">戻る</a>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
@endsection @endsection
@push('styles') @push('styles')
<style> <style>
/* 画像ボックスの体裁 */ /* 画像ボックスの体裁 */
.imgbox { border:1px solid #ced4da; border-radius:.25rem; } .imgbox {
.imgbox-title { background:#f4f6f9; border-bottom:1px solid #ced4da; padding:.5rem .75rem; font-weight:600; } border: 1px solid #ced4da;
.imgbox-preview { border-radius: .25rem;
border:1px solid #ced4da; border-radius:.25rem; background:#f8f9fa; }
height:200px; display:flex; align-items:center; justify-content:center; overflow:hidden;
} .imgbox-title {
.imgbox-preview img { max-width:100%; max-height:100%; display:block; } background: #f4f6f9;
</style> border-bottom: 1px solid #ced4da;
padding: .5rem .75rem;
font-weight: 600;
}
.imgbox-preview {
border: 1px solid #ced4da;
border-radius: .25rem;
background: #f8f9fa;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.imgbox-preview img {
max-width: 100%;
max-height: 100%;
display: block;
}
</style>
@endpush @endpush
@push('scripts') @push('scripts')
<script> <script>
// 画像プレビュー系のみ(確認ダイアログは app.js に委譲) // 画像プレビュー系のみ(確認ダイアログは app.js に委譲)
(function(){ (function () {
function bindUrlPreview(urlId, imgId, phId) { function bindUrlPreview(urlId, imgId, phId) {
const url = document.getElementById(urlId); const url = document.getElementById(urlId);
const img = document.getElementById(imgId); const img = document.getElementById(imgId);
const ph = document.getElementById(phId); const ph = document.getElementById(phId);
if (!url || !img || !ph) return; if (!url || !img || !ph) return;
function update(){ function update() {
const v = (url.value || '').trim(); const v = (url.value || '').trim();
if (v) { img.src = v; img.style.display='block'; ph.style.display='none'; } if (v) { img.src = v; img.style.display = 'block'; ph.style.display = 'none'; }
else { img.removeAttribute('src'); img.style.display='none'; ph.style.display='block'; } else { img.removeAttribute('src'); img.style.display = 'none'; ph.style.display = 'block'; }
} }
url.addEventListener('input', update); update(); url.addEventListener('input', update); update();
} }
function bindUpload(btnId, fileId, urlId, imgId, phId, clearBtnId){ function bindUpload(btnId, fileId, urlId, imgId, phId, clearBtnId) {
const btn = document.getElementById(btnId); const btn = document.getElementById(btnId);
const file= document.getElementById(fileId); const file = document.getElementById(fileId);
const url = document.getElementById(urlId); const url = document.getElementById(urlId);
const img = document.getElementById(imgId); const img = document.getElementById(imgId);
const ph = document.getElementById(phId); const ph = document.getElementById(phId);
const clr = document.getElementById(clearBtnId); const clr = document.getElementById(clearBtnId);
if (!btn || !file || !url || !img || !ph || !clr) return; if (!btn || !file || !url || !img || !ph || !clr) return;
btn.addEventListener('click', ()=> file.click()); btn.addEventListener('click', () => file.click());
file.addEventListener('change', ()=>{ file.addEventListener('change', () => {
const f = file.files && file.files[0]; if (!f) return; const f = file.files && file.files[0]; if (!f) return;
const reader = new FileReader(); const reader = new FileReader();
reader.onload = e => { img.src = e.target.result; img.style.display='block'; ph.style.display='none'; }; reader.onload = e => { img.src = e.target.result; img.style.display = 'block'; ph.style.display = 'none'; };
reader.readAsDataURL(f); reader.readAsDataURL(f);
}); });
clr.addEventListener('click', ()=>{ clr.addEventListener('click', () => {
file.value=''; url.value=''; file.value = ''; url.value = '';
img.removeAttribute('src'); img.style.display='none'; ph.style.display='block'; img.removeAttribute('src'); img.style.display = 'none'; ph.style.display = 'block';
}); });
} }
bindUrlPreview('image1_url','image1_preview','image1_placeholder'); bindUrlPreview('image1_url', 'image1_preview', 'image1_placeholder');
bindUrlPreview('image2_url','image2_preview','image2_placeholder'); bindUrlPreview('image2_url', 'image2_preview', 'image2_placeholder');
bindUpload('btn-image1-upload','file-image1','image1_url','image1_preview','image1_placeholder','btn-image1-clear'); bindUpload('btn-image1-upload', 'file-image1', 'image1_url', 'image1_preview', 'image1_placeholder', 'btn-image1-clear');
bindUpload('btn-image2-upload','file-image2','image2_url','image2_preview','image2_placeholder','btn-image2-clear'); bindUpload('btn-image2-upload', 'file-image2', 'image2_url', 'image2_preview', 'image2_placeholder', 'btn-image2-clear');
})(); })();
</script> </script>
@endpush @endpush

View File

@ -40,10 +40,15 @@
<textarea name="news" class="form-control" rows="8" required>{{ old('news', $news->news) }}</textarea> <textarea name="news" class="form-control" rows="8" required>{{ old('news', $news->news) }}</textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>公開日時 <span class="text-danger">*</span></label> <label>公開日時<span class="text-danger">*</span></label>
<input type="text" name="open_datetime" class="form-control" placeholder="YYYY-MM-DD HH:MM:SS" <input type="date"
value="{{ old('open_datetime', $news->open_datetime) }}" required> name="open_datetime"
class="form-control"
value="{{ old('open_datetime', !empty($news->open_datetime) ? \Carbon\Carbon::parse($news->open_datetime)->format('Y-m-d') : '') }}"
required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>リンクURL</label> <label>リンクURL</label>
<input type="text" name="link_url" class="form-control" value="{{ old('link_url', $news->link_url) }}"> <input type="text" name="link_url" class="form-control" value="{{ old('link_url', $news->link_url) }}">
@ -110,34 +115,43 @@
</div> </div>
</div> </div>
{{-- 表示モードラジオ・必須新規画面と同一UI --}} {{-- 表示モード(デフォルト:非表示 --}}
<div class="form-group mt-3"> <div class="form-group mt-3">
<label class="d-block">表示モード <span class="text-danger">*</span></label> <label class="d-block">表示モード <span class="text-danger">*</span></label>
{{-- 下書き(非表示) --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_draft" value="2" required <input class="form-check-input" type="radio" name="mode" id="mode_draft" value="1" required
@checked(old('mode', (string)$news->mode)=='2')> @checked(old('mode', $news->mode) == 1)>
<label class="form-check-label" for="mode_draft">下書き(非表示)</label> <label class="form-check-label" for="mode_draft">下書き(非表示)</label>
</div> </div>
{{-- 公開 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_public" value="1" <input class="form-check-input" type="radio" name="mode" id="mode_public" value="2"
@checked(old('mode', (string)$news->mode)=='1')> @checked(old('mode', $news->mode) == 2)>
<label class="form-check-label" for="mode_public">公開</label> <label class="form-check-label" for="mode_public">公開</label>
</div> </div>
{{-- 自動公開 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_auto" value="3" <input class="form-check-input" type="radio" name="mode" id="mode_auto" value="3"
@checked(old('mode', (string)$news->mode)=='3')> @checked(old('mode', $news->mode) == 3)>
<label class="form-check-label" for="mode_auto">自動公開</label> <label class="form-check-label" for="mode_auto">自動公開</label>
</div> </div>
{{-- 非表示 --}}
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_hidden" value="0" <input class="form-check-input" type="radio" name="mode" id="mode_hidden" value="4"
@checked(old('mode', (string)$news->mode)=='0')> @checked(old('mode', $news->mode) == 4)>
<label class="form-check-label" for="mode_hidden">非表示</label> <label class="form-check-label" for="mode_hidden">非表示</label>
</div> </div>
</div> </div>
<div class="text-right">
<div class="text-left">
<button type="button" class="btn btn-default" id="register_edit">登録</button>
<a href="{{ route('news') }}" class="btn btn-default">戻る</a> <a href="{{ route('news') }}" class="btn btn-default">戻る</a>
<button type="button" class="btn btn-default" id="register_edit">保存</button>
</div> </div>
</form> </form>
</div> </div>