金額格式化表單
by ph822720355
HTML
<div class="container">
<h1>💰 訂單表單範例</h1>
<p class="subtitle">輸入金額時會自動格式化(觸發 onchange 事件)</p>
<form id="orderForm">
<div class="form-group">
<label for="customerName">客戶姓名 *</label>
<input
type="text"
id="customerName"
name="customerName"
placeholder="請輸入姓名"
required
>
</div>
<div class="form-group">
<label for="email">電子郵件</label>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
>
</div>
<div class="form-group">
<label for="orderAmount">訂單金額 *</label>
<input
type="text"
id="orderAmount"
name="orderAmount"
placeholder="輸入後自動格式化"
onchange="doAmtFormat(this, 15)"
required
>
<div class="hint">💡 可輸入負數、包含文字,系統會自動過濾並格式化</div>
</div>
<div class="form-group">
<label for="depositAmount">訂金金額</label>
<input
type="text"
id="depositAmount"
name="depositAmount"
placeholder="輸入後自動格式化"
onchange="doAmtFormat(this, 15)"
>
<div class="hint">💡 試試輸入: -abc12345xyz 或 00001234</div>
</div>
<div class="form-group">
<label for="paymentMethod">付款方式</label>
<select id="paymentMethod" name="paymentMethod">
<option value="">請選擇</option>
...
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
color: #333;
margin-bottom: 10px;
font-size: 28px;
}
.subtitle {
color: #666;
margin-bottom: 30px;
font-size: 14px;
}
.form-group {
margin-bottom: 25px;
}
label {
display: block;
margin-bottom: 8px;
color: #555;
font-weight: 600;
font-size: 14px;
}
input[type="text"],
input[type="number"],
input[type="email"],
select {
width: 100%;
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: all 0.3s;
}
input[type="text"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
select:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.hint {
font-size: 12px;
color: #999;
margin-top: 5px;
}
.button-group {
...
JavaScript
/**
* 格式化金額輸入
* @param {HTMLInputElement} field - 輸入框元素
* @param {number} maxLen - 最大長度限制
* @returns {boolean}
*/
function doAmtFormat(field, maxLen) {
let value = field.value.trim();
// 處理負號
const isNegative = value.startsWith('-');
if (isNegative) {
value = value.slice(1);
}
// 移除所有非數字字元
let numericValue = value.replace(/\D/g, '');
// 套用長度限制
if (numericValue.length > maxLen) {
numericValue = numericValue.slice(0, maxLen);
}
// 移除前導零,但保留至少一個 "0"
numericValue = numericValue.replace(/^0+/, '') || '0';
// 套用千分位格式
const formatted = moneyFormat(numericValue);
// 加回負號(如果有)
field.value = isNegative ? `-${formatted}` : formatted;
// 更新預覽
updatePreview();
return true;
}
/**
* 加上千分位逗號
* @param {string} str - 數字字串
* @returns {string} 格式化後的字串
*/
function moneyFormat(str) {
return str.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
/**
* 更新表單預覽
*/
function updatePreview() {
const form = document.getElementById('orderForm');
const preview = document.getElementById('preview');
// 取得表單值
const name = form.customerName.value;
const email = form.email.value;
const amount = form.orderAmount.value;
const deposit = form.depositAmount.value;
const payment = form.paymentMethod.options[form.paymentMethod.selectedIndex].text;
// 更新預覽
...