ปัญหาที่ตัวเลขเงิน (Premium) ในตารางไม่มี ตัวคั่นหลักพัน (Comma Separator) ทำให้ตัวเลขยาวๆ อ่านยาก
การแก้ไขปัญหานี้ทำได้ง่ายมากใน JavaScript โดยใช้เมธอด .toLocaleString() เมื่อเราทำการสร้าง Input ในตาราง และเมื่อเราแสดงผลรวมเบี้ยทั้งหมด
ผมจะแนะนำการแก้ไขใน 2 จุดหลัก คือ:
- ในตาราง (Input Premium): ต้องใส่ตัวคั่นให้ค่าที่โหลดเข้ามาแสดงผล
- ในส่วนสรุป (Total Premium): ต้องใส่ตัวคั่นให้ค่ารวมที่คำนวณได้
เนื่องจากคุณกำหนดให้คอลัมน์ Premium เป็น type: 'number' ใน createTableRow การใช้ toLocaleString() โดยตรงอาจมีปัญหาได้ หากผู้ใช้แก้ไขตัวเลข ดังนั้นเราจะเปลี่ยนเป็น type: 'text' แล้วจัดการการแสดงผลและการคำนวณใน JavaScript แทน
🛠️ โค้ดที่ต้องแก้ไข: JavaScript
1. แก้ไข createTableRow(d) (เพื่อให้ Input Premium มีตัวคั่น)
เราจะเปลี่ยน type: 'number' เป็น type: 'text' ใน cellData และใช้ toLocaleString() ในการกำหนด input.value
ตำแหน่ง: ในฟังก์ชัน createTableRow(d)
JavaScript
function createTableRow(d) {
const tr = document.createElement("tr");
// ข้อมูลเซลล์หลัก 9 ช่อง (Premium คือ index 4)
const cellData = [
{ type: 'date', value: d.date, className: 'date-cell-status' },
// ... (คอลัมน์ 1, 2, 3) ...
// ⭐️ FIX 1: เปลี่ยน Premium จาก 'number' เป็น 'text'
{ type: 'text', value: d.premium },
{ type: 'checkbox', value: d.paid === "true" || d.paid === true, ispaid: true },
// ... (คอลัมน์ 6, 7, 8, 9) ...
];
cellData.forEach((cell, index) => {
const td = document.createElement("td");
// ... (โค้ดการจัดการ td.style.width, className) ...
const input = document.createElement("input");
input.type = cell.type; // ตอนนี้ input.type คือ 'text'
// ⭐️ FIX 2: ใส่ตัวคั่นหลักพันให้ค่า Premium (เฉพาะ index 4) ⭐️
if (index === 4) { // Premium
// ตรวจสอบว่าเป็นตัวเลขหรือไม่ แล้วจัดรูปแบบ
const numValue = parseFloat(cell.value);
if (!isNaN(numValue)) {
// ใช้ 'en-US' locale เพื่อให้ได้ Comma (,) เป็นตัวคั่นหลักพัน
input.value = numValue.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
} else {
input.value = cell.value || '';
}
}
else if (cell.type !== 'checkbox') {
// โค้ดเดิมสำหรับ Input ทั่วไป
input.className = "form-control form-control-sm";
input.value = cell.value;
// ... (โค้ดจัดการ Input Date) ...
}
// ... (โค้ดส่วนอื่น ๆ) ...
});
// ... (โค้ดส่วนท้าย) ...
return tr;
}
2. แก้ไข saveDataToLocalStorage() (เพื่อให้ค่าที่ถูกบันทึกไม่มีตัวคั่น)
เนื่องจากตอนนี้ Input เป็น type: 'text' เมื่อผู้ใช้พิมพ์ตัวเลขพร้อมตัวคั่น (เช่น 10,000) เราต้อง ลบตัวคั่น ออกก่อนที่จะบันทึกลง Local Storage เพื่อให้เป็นตัวเลขที่ถูกต้องสำหรับการคำนวณในอนาคต
ตำแหน่ง: ในฟังก์ชัน saveDataToLocalStorage() (บริเวณที่คุณวนลูปเพื่อดึงค่าจากตาราง)
JavaScript
function saveDataToLocalStorage() {
// ... (โค้ดส่วนการเตรียม dataForSave) ...
const table = document.getElementById('mainTable') || document.getElementById(activeTableId);
if (!table) return;
// ... (โค้ดวนลูป tr.querySelectorAll('td')) ...
// ⭐️ FIX 3: จัดการค่า Premium ก่อนบันทึก ⭐️
let cellValue = input.value;
if (index === 4) { // Premium
// ลบตัวคั่นหลักพัน (,) ออก เพื่อให้เป็นตัวเลขที่ถูกต้อง
cellValue = cellValue.replace(/,/g, '');
}
// ... (โค้ดส่วนที่บันทึก cellValue เข้าไปใน dataForSave) ...
// dataForSave.push(cellValue);
// ...
}
3. แก้ไข updateSummary() (เพื่อให้ส่วนสรุปมีตัวคั่น)
หากคุณใช้ฟังก์ชัน updateSummary หรือส่วนที่แสดงผล “รวมเบี้ยทั้งหมด” กรุณาตรวจสอบให้แน่ใจว่าคุณได้ใช้ toLocaleString() กับผลรวม:
ตำแหน่ง: ในฟังก์ชันที่อัปเดตค่าสรุป (ตามที่แก้ไขในขั้นตอนที่แล้ว)
JavaScript
// ... ภายในฟังก์ชัน updateSummary()
// ... (โค้ดคำนวณ totalPremium) ...
const totalPremiumDisplay = document.getElementById('totalPremiumDisplay');
if (totalPremiumDisplay) {
// ⭐️ FIX 4: ใช้ toLocaleString() กับตัวแปร totalPremium ⭐️
totalPremiumDisplay.textContent = `รวมเบี้ยทั้งหมด: ${totalPremium.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}
// ...
การแก้ไขเหล่านี้จะช่วยให้ตัวเลขในช่อง Premium และส่วนสรุป มีตัวคั่นหลักพันที่ชัดเจนและอ่านง่ายขึ้นครับ!
ลงมือทำ
// 🟢 เพิ่มฟังก์ชันใหม่นี้ทั้งหมด
function createTableRow(d) {
const tr = document.createElement("tr");
// ข้อมูลเซลล์หลัก 9 ช่อง (รวมวันที่)
const cellData = [
{ type: 'date', value: d.date, className: 'date-cell-status' },
{ type: 'text', value: d.product, className: 'expandable-cell' },
{ type: 'text', value: d.company, className: 'expandable-cell' },
{ type: 'text', value: d.name, className: 'expandable-cell' },
{ type: 'text', value: d.premium },
{ type: 'text', value: d.receive },
{ type: 'text', value: d.pay },
{ type: 'text', value: d.note, className: 'expandable-cell' },
{ type: 'text', value: d.contact, className: 'expandable-cell' },
];
cellData.forEach((cell, index) => {
const td = document.createElement("td");
if (cell.className) td.className = cell.className;
const input = document.createElement("input");
input.type = cell.type;
input.className = "form-control";
// ⭐️ ความปลอดภัย: ใช้ .value เพื่อกำหนดค่าให้ Input
input.value = cell.value;
// ⭐️ จุดที่ต้องเพิ่ม: แนบ Event Listener ⭐️
// Index 4: Premium
// Index 5: Receive
// Index 6: Pay
if (index === 4 || index === 5 || index === 6) {
// ⚠️ สำคัญ: ต้องเป็น type='text' หรือไม่ระบุ type
// ถ้าเป็น type='number' การใส่ Comma จะไม่ทำงาน
input.type = 'text';
// แนบ Event Listener: เรียกใช้ formatNumberWithCommas ทุกครั้งที่พิมพ์
input.addEventListener('input', function() {
formatNumberWithCommas(this);
});
}
// ⭐️ สำคัญ: เพิ่ม class expandable-input สำหรับช่องที่ต้องขยาย
// (Product, Company, Name, Note, Contact)
if (index > 0 && index < 4 || index > 6 && index < 9) {
input.classList.add('expandable-input');
}/* ======================= HOVER EXPAND FUNCTION (ส่วนที่เพิ่มใหม่) ======================== */
// 1. Helper function สำหรับคำนวณความกว้างของข้อความ (ยังคงเดิม)
function getTextWidth(text, font) {
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = font;
// เพิ่ม 30px เพื่อ account for input's internal padding และ border
return context.measureText(text).width + 30;
}
/* ==================== NEW: Real-time Comma Formatter ======================= */
function formatNumberWithCommas(input) {
// 1. ลบตัวคั่นหลักพัน (,) และอักขระที่ไม่ใช่ตัวเลข/จุดทศนิยมออก
// ใช้วิธีที่อนุญาตให้มีจุดทศนิยมได้เพียงจุดเดียว
let value = input.value.replace(/,/g, '');
value = value.replace(/[^0-9.]/g, '');
// 2. แยกส่วนจำนวนเต็มและส่วนทศนิยม
let parts = value.split('.');
let integerPart = parts[0];
let decimalPart = parts.length > 1 ? '.' + parts[1] : '';
// 3. ใส่ตัวคั่นหลักพัน (,) ให้กับส่วนจำนวนเต็ม
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
// 4. อัปเดตค่าใน Input Field
input.value = integerPart + decimalPart;
// 5. เรียกอัปเดตยอดรวมทันทีที่ค่าเปลี่ยน
updateTotalsContextually();
}
// 2. Main handler function
// ฟังก์ชันช่วยในการคำนวณความกว้างของข้อความ (จำเป็นต้องคงไว้)