iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
自我挑戰組

Laravel 讀碼源系列 第 22

鋼琴留言版的新增的 前端 程式碼

  • 分享至 

  • xImage
  •  

鋼琴留言版
https://laihao.vaserver.com/gbook

可以實際測試
也歡迎大家一起來學習喔
https://www.pressplay.cc/project/9D489B43D08BD198FDEB03ECDEFAC161/about

資料庫-這裡只有單一一個
MVC架構-
MODEL
前端
後端

前端-新增內容

程式碼

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新增許願</title>
    <style>
        body { font-family: 'Microsoft JhengHei', sans-serif; background: #f9f3ff; }
        h1 { text-align: center; color: #6a0dad; margin-top: 30px; }
        .form-box { width: 500px; margin: 30px auto; background: white;
                    padding: 30px; border-radius: 15px;
                    box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
        label { display: block; color: #6a0dad; font-weight: bold; margin-bottom: 5px; }
        input[type=text], select, textarea {
            width: 100%; padding: 10px; margin-bottom: 15px;
            border: 2px solid #e0c8ff; border-radius: 8px;
            font-size: 1em; box-sizing: border-box; }
        input:focus, select:focus, textarea:focus {
            outline: none; border-color: #6a0dad; }
        .btn-submit { width: 100%; padding: 12px; background: #6a0dad;
                      color: white; border: none; border-radius: 25px;
                      font-size: 1.1em; cursor: pointer; }
        .btn-submit:hover { background: #530a9e; }
        .back { display: block; text-align: center; margin-top: 15px;
                color: #6a0dad; text-decoration: none; }
        .error { color: red; font-size: 0.9em; margin-bottom: 10px; }
    </style>
</head>
<body>
    <h1>🎹 許願新課程</h1>

    <div class="form-box">
        @if(errors->any())<ulclass="error">@foreach(errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        @endif

        <form action="{{ route('gbook.store') }}" method="POST">
            @csrf

            <label>許願人</label>
            <input type="text" name="gbook_poser" value="{{ old('gbook_poser') }}" placeholder="請輸入你的名字">

            <label>課程類型</label>
            <select name="gbook_kind">
                <option value="初級">初級</option>
                <option value="中級">中級</option>
                <option value="高級">高級</option>
                <option value="樂理">樂理</option>
                <option value="即興">即興</option>
            </select>

            <label>課程標題</label>
            <input type="text" name="gbook_title" value="{{ old('gbook_title') }}" placeholder="你想學什麼課程?">

            <label>許願內容</label>
            <textarea name="gbook_msg" rows="5" placeholder="詳細描述你的願望...">{{ old('gbook_msg') }}</textarea>

            <button type="submit" class="btn-submit">🎵 送出許願</button>
        </form>

        <a href="{{ route('gbook.index') }}" class="back">← 回許願板</a>
    </div>
</body>
</html>


這是一個 Laravel Blade 的「新增許願」表單頁面,讓使用者輸入姓名、課程類型、課程標題和許願內容,再送到 GbookController@store 儲存到資料庫。

檔案通常是:

resources/views/gbook/create.blade.php

一、HTML 基本設定

<!DOCTYPE html>
<html lang="zh-Hant-TW">

表示這是一份 HTML5 文件,並指定頁面語言為台灣繁體中文。

<meta charset="UTF-8">

使用 UTF-8 編碼,支援中文、日文和 Emoji。

<meta name="viewport"
      content="width=device-width, initial-scale=1.0">

讓頁面能適應手機與平板螢幕。

<title>新增許願</title>

設定瀏覽器分頁標題。

二、CSS 樣式

頁面背景

body {
    font-family: 'Microsoft JhengHei', sans-serif;
    background: #f9f3ff;
}

設定:

  • 字體優先使用微軟正黑體。
  • 背景為淡紫色。

主標題

h1 {
    text-align: center;
    color: #6a0dad;
    margin-top: 30px;
}

讓標題置中、使用紫色,並與頁面上方保持 30px 間距。

表單外框

.form-box {
    width: 500px;
    margin: 30px auto;
    background: white;
    padding: 30px;
    border-radius: 15px;
    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}

這個區塊包住整個表單。

  • 寬度:500px。
  • margin: 30px auto:上下 30px,左右自動置中。
  • 白色背景。
  • 內容與邊界保持 30px 距離。
  • 圓角 15px。
  • 加上淡淡的陰影。

在手機上,固定 width: 500px 可能超出畫面,建議改成:

.form-box {
    width: 90%;
    max-width: 500px;
    box-sizing: border-box;
}

這樣在桌面上最大 500px,在手機上則會縮小至適合的寬度。

標籤

label {
    display: block;
    color: #6a0dad;
    font-weight: bold;
    margin-bottom: 5px;
}

每個表單標籤會:

  • 獨立佔一行。
  • 使用紫色。
  • 使用粗體。
  • 與輸入欄位保留 5px 距離。

輸入欄位

input[type=text], select, textarea {
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    border: 2px solid #e0c8ff;
    border-radius: 8px;
    font-size: 1em;
    box-sizing: border-box;
}

同時設定:

  • 文字輸入框。
  • 下拉選單。
  • 多行文字區域。

各項效果如下:

  • width: 100%:填滿表單寬度。
  • padding: 10px:增加輸入舒適度。
  • margin-bottom: 15px:欄位之間保留空間。
  • 淡紫色邊框。
  • 8px 圓角。
  • box-sizing: border-box:讓 padding 和邊框包含在設定的寬度內,避免欄位超出容器。

輸入時的焦點效果

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: #6a0dad;
}

當使用者正在輸入欄位時:

  • 移除瀏覽器預設外框。
  • 將邊框改成深紫色。

較重視無障礙時,不建議完全移除 outline,可以改成:

input:focus,
select:focus,
textarea:focus {
    outline: 3px solid rgba(106, 13, 173, 0.25);
    border-color: #6a0dad;
}

送出按鈕

.btn-submit {
    width: 100%;
    padding: 12px;
    background: #6a0dad;
    color: white;
    border: none;
    border-radius: 25px;
    font-size: 1.1em;
    cursor: pointer;
}

設定送出按鈕:

  • 寬度填滿表單。
  • 紫色背景。
  • 白色文字。
  • 移除預設邊框。
  • 圓角外觀。
  • 滑鼠移入時顯示手指游標。
.btn-submit:hover {
    background: #530a9e;
}

滑鼠移到按鈕時,背景變成深紫色。

返回連結

.back {
    display: block;
    text-align: center;
    margin-top: 15px;
    color: #6a0dad;
    text-decoration: none;
}

設定「回許願板」連結:

  • 顯示為區塊。
  • 文字置中。
  • 上方保留 15px。
  • 移除底線。

錯誤訊息

.error {
    color: red;
    font-size: 0.9em;
    margin-bottom: 10px;
}

驗證錯誤會以紅色、較小字體顯示。

三、標題與表單容器

<h1>🎹 許願新課程</h1>

<div class="form-box">

h1 是頁面標題。

.form-box 則是白色表單卡片,包住:

  • 錯誤訊息。
  • 表單欄位。
  • 送出按鈕。
  • 返回許願板連結。

四、顯示驗證錯誤

@if($errors->any())
    <ul class="error">
        @foreach($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

這段是 Laravel Blade 語法。

$errors->any()

判斷目前是否有任何驗證錯誤。

Controller 中的驗證是:

$request->validate([
    'gbook_poser' => 'required|max:20',
    'gbook_kind'  => 'required',
    'gbook_title' => 'required|max:30',
    'gbook_msg'   => 'required|max:200',
]);

如果使用者沒有填寫必填欄位,或者超過字數限制,就會產生錯誤。

$errors->all()

取得所有錯誤訊息。

@foreach

逐筆列出錯誤:

<li>{{ $error }}</li>

最後可能顯示:

The gbook poser field is required.
The gbook title may not be greater than 30 characters.

如果要顯示繁體中文錯誤訊息,可以在:

lang/zh_TW/validation.php

設定語言檔,或在驗證時自訂訊息。

Laravel 會將驗證錯誤與原始輸入資料暫存到 Session,讓重新導向回表單後可以顯示錯誤並保留使用者輸入。 laravel

五、表單送出設定

<form action="{{ route('gbook.store') }}" method="POST">

表示表單送出時:

  • 目的地是 gbook.store 路由。
  • 使用 HTTP POST 方法。

如果路由設定如下:

Route::post('/gbook', [GbookController::class, 'store'])
    ->name('gbook.store');

送出後會執行:

GbookController@store

也就是前面介紹的新增資料方法。

六、CSRF 防護

@csrf

Laravel 會將它轉換成隱藏欄位,類似:

<input type="hidden"
       name="_token"
       value="...">

這個 Token 用來確認表單是由自己網站產生,而不是惡意網站偽造的請求。

在 Laravel 的 POST、PUT、PATCH、DELETE 表單中,通常都必須加入:

@csrf

否則可能出現:

419 Page Expired

七、許願人欄位

<label>許願人</label>
<input
    type="text"
    name="gbook_poser"
    value="{{ old('gbook_poser') }}"
    placeholder="請輸入你的名字">

name="gbook_poser"

這個名稱必須與 Controller 驗證的欄位名稱相同:

'gbook_poser'

送出後,Laravel 才能透過:

$request->gbook_poser

取得資料。

old('gbook_poser')

如果驗證失敗,Laravel 會保留使用者上一次輸入的內容。

例如使用者填入:

王小明

但其他欄位驗證失敗,返回表單時:

value="{{ old('gbook_poser') }}"

會自動恢復:

王小明

這樣使用者不必重新輸入。

placeholder

placeholder="請輸入你的名字"

在欄位空白時顯示提示文字。

不過 placeholder 不能完全取代 <label>,目前同時使用 label 和 placeholder 是正確方向。表單控制項應該有清楚的標籤,這對可及性和螢幕閱讀器很重要。 developer.mozilla

八、課程類型下拉選單

<label>課程類型</label>

<select name="gbook_kind">
    <option value="初級">初級</option>
    <option value="中級">中級</option>
    <option value="高級">高級</option>
    <option value="樂理">樂理</option>
    <option value="即興">即興</option>
</select>

select 建立下拉式選單。

使用者看到的是:

初級
中級
高級
樂理
即興

送出後,Controller 可以取得:

$request->gbook_kind

例如選擇「即興」,送出的值為:

即興

目前第一個選項會預設被選取。如果希望使用者必須主動選擇,可以增加提示選項:

<select name="gbook_kind" required>
    <option value="">請選擇課程類型</option>
    <option value="初級" @selected(old('gbook_kind') === '初級')>初級</option>
    <option value="中級" @selected(old('gbook_kind') === '中級')>中級</option>
    <option value="高級" @selected(old('gbook_kind') === '高級')>高級</option>
    <option value="樂理" @selected(old('gbook_kind') === '樂理')>樂理</option>
    <option value="即興" @selected(old('gbook_kind') === '即興')>即興</option>
</select>

HTML 的 required 可以讓瀏覽器在送出前檢查文字框、下拉選單和文字區域是否有值。 developer.mozilla

九、課程標題欄位

<label>課程標題</label>
<input
    type="text"
    name="gbook_title"
    value="{{ old('gbook_title') }}"
    placeholder="你想學什麼課程?">

這個欄位對應資料庫:

gbook_title

Controller 驗證限制是:

'required|max:30'

也就是:

  • 必填。
  • 最多 30 個字元。

十、許願內容欄位

<label>許願內容</label>

<textarea
    name="gbook_msg"
    rows="5"
    placeholder="詳細描述你的願望..."
>{{ old('gbook_msg') }}</textarea>

textarea 用來輸入多行文字。

rows="5"

設定文字區域大約顯示 5 行高度。

old('gbook_msg')

如果驗證失敗,保留使用者原本輸入的內容。

input 不同,textarea 的值要放在開始標籤和結束標籤之間:

<textarea name="gbook_msg">{{ old('gbook_msg') }}</textarea>

十一、送出按鈕

<button type="submit" class="btn-submit">
    🎵 送出許願
</button>

type="submit" 表示按下後送出表單。

送出後的流程是:

POST gbook.store
        ↓
GbookController@store
        ↓
驗證資料
        ↓
Gbook::create()
        ↓
寫入 gbook 資料表
        ↓
返回 gbook.index

十二、返回許願板

<a href="{{ route('gbook.index') }}" class="back">
    ← 回許願板
</a>

利用 Laravel 的命名路由前往:

gbook.index

通常對應:

GbookController@index

最後回到留言清單頁面。

十三、建議加入 idfor

目前的寫法:

<label>許願人</label>
<input type="text" name="gbook_poser">

接來來是 美髮業的系統
這組資料適合先插入 users → customers → staff → services → products → appointments → appointment_services → invoices → invoice_items → inventory_logs,因為預約、發票、庫存異動都依賴前面的主資料表

不過有網址覺得有圖有真相

https://laihao.vaserver.com/hairdressing


上一篇
解釋 鋼琴留言版的前端 帶出內容程式碼
系列文
Laravel 讀碼源22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言