// code V66
// 🟢 เพิ่มฟังก์ชันใหม่นี้ทั้งหมด
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: 'number', value: d.premium },
{ type: 'checkbox', value: d.paid === "true" || d.paid === true, ispaid: true },
{ type: 'checkbox', value: d.pay === "true" || d.pay === true, isPay: true },
{ 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;
// ⭐️ สำคัญ: เพิ่ม class expandable-input สำหรับช่องที่ต้องขยาย
// (Product, Company, Name, Note, Contact)
if (index > 0 && index < 4 || index > 6 && index < 9) {
input.classList.add('expandable-input');
}
// ⬇️ ⭐️ แทรก 3 บรรทัดนี้ตรงนี้ ⭐️ ⬇️
// --- Added: handle paid/Pay as checkboxes with flashing backgrounds ---
if (cell.ispaid) {
input.checked = !!cell.value;
input.classList.add('form-check-input');
// ensure input type is checkbox (in case)
input.type = 'checkbox';
// style the parent TD for flashing when unchecked
if (!input.checked) td.classList.add('flash-paid');
input.addEventListener('change', () => {
if (!input.checked) td.classList.add('flash-paid'); else td.classList.remove('flash-paid');
try { saveDataToLocalStorage(); } catch(e){}
});
}
if (cell.isPay) {
input.checked = !!cell.value;
input.classList.add('form-check-input');
input.type = 'checkbox';
if (!input.checked) td.classList.add('flash-pay');
input.addEventListener('change', () => {
if (!input.checked) td.classList.add('flash-pay'); else td.classList.remove('flash-pay');
try { saveDataToLocalStorage(); } catch(e){}
});
}
// --- end added ---
if (input.classList.contains("expandable-input")) {
attachExpandEvents(input);
}
td.appendChild(input);
tr.appendChild(td);
});
// เซลล์ Renewed (Checkbox และ Icon)
const tdRenewed = document.createElement("td");
tdRenewed.className = "renewed-cell";
tdRenewed.style.width = "1%";
tdRenewed.style.textAlign = "center";
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.className = "form-check-input renewed-checkbox";
checkbox.checked = d.renewed;
const icon = document.createElement("span");
icon.className = "alert-icon";
icon.textContent = "🚨";
tdRenewed.appendChild(checkbox);
tdRenewed.appendChild(icon);
tr.appendChild(tdRenewed);
// เซลล์ Actions
const tdActions = document.createElement("td");
// ⭐️ FIX: บังคับให้คอลัมน์นี้มีความกว้างขั้นต่ำตามเนื้อหา (สำคัญมาก)
tdActions.style.width = "1%";
tdActions.style.textAlign = "center";
// ⭐️ สร้าง DIV ตัวกลางเพื่อควบคุม Flexbox
const divContainer = document.createElement("div");
divContainer.style.display = "flex";
divContainer.style.justifyContent = "center";
divContainer.style.gap = "5px";
divContainer.style.whiteSpace = "nowrap"; // ห้ามแตกแถว
// โค้ดเดิม: ปุ่มคัดลอก (⧉)
const btnDup = document.createElement("button");
btnDup.className = "btn btn-warning btn-sm action-btn act-dup";
btnDup.textContent = "⧉";
// โค้ดเดิม: ปุ่มลบ (🗑)
const btnDel = document.createElement("button");
btnDel.className = "btn btn-danger btn-sm action-btn act-del";
btnDel.textContent = "🗑";
// เพิ่มปุ่มเข้าใน DIV Container
divContainer.appendChild(btnDup);
divContainer.appendChild(btnDel);
// เพิ่ม DIV Container เข้าใน Cell
tdActions.appendChild(divContainer);
tr.appendChild(tdActions);
return tr;
}
// 🟢 สิ้นสุดฟังก์ชัน// code V66-1
function createTableRow(d) {
const tr = document.createElement(“tr”);
// ข้อมูลเซลล์หลัก 9 ช่อง (รวมวันที่)
const cellData = [
{ type: 'date', value: d.date, className: 'date-cell-status' }, // คอลัมน์ D/M/Y
{ 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: 'number', value: d.premium },
{ type: 'checkbox', value: d.paid === "true" || d.paid === true, ispaid: true }, // คอลัมน์ Paid/Receive
{ type: 'checkbox', value: d.pay === "true" || d.pay === true, isPay: true }, // คอลัมน์ 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");
// ⭐️ FIX 1: บังคับความกว้างขั้นต่ำ (width: 1%) ให้กับคอลัมน์ D/M/Y และ Checkbox
if (cell.type === 'date' || cell.type === 'checkbox') {
td.style.width = "1%"; // บังคับให้ TD แคบที่สุด
if (cell.type === 'checkbox') td.classList.add('text-center');
}
if (cell.className) td.className = cell.className;
const input = document.createElement("input");
input.type = cell.type;
// ⭐️ FIX 2: จัดการ Class ของ Input อย่างแม่นยำ
if (cell.type !== 'checkbox') {
// สำหรับ Text, Number, Date: ใช้ form-control-sm
input.className = "form-control form-control-sm";
input.value = cell.value;
// ⭐️ FIX A (D/M/Y): ใช้ Inline Style บังคับความกว้าง input date โดยตรง
if (cell.type === 'date') {
// กำหนดความกว้างขั้นต่ำที่เหมาะสมที่สุด (120px)
// การกำหนด inline style นี้จะ override CSS และ form-control class
input.style.width = "120px";
}
} else {
// สำหรับ Checkbox: ใช้ form-check-input เท่านั้น
input.classList.add('form-check-input');
}
// ⭐️ สำคัญ: เพิ่ม class expandable-input สำหรับช่องที่ต้องขยาย
if (index > 0 && index < 4 || index > 6 && index < 9) {
input.classList.add('expandable-input');
}
// --- Added: handle paid/Pay as checkboxes with flashing backgrounds ---
if (cell.ispaid) {
input.checked = !!cell.value;
input.type = 'checkbox';
if (!input.checked) td.classList.add('flash-paid');
input.addEventListener('change', () => {
if (!input.checked) td.classList.add('flash-paid'); else td.classList.remove('flash-paid');
try { saveDataToLocalStorage(); } catch(e){}
});
}
if (cell.isPay) {
input.checked = !!cell.value;
input.type = 'checkbox';
input.classList.add('form-check-input'); // Ensure Checkbox class is added
if (!input.checked) td.classList.add('flash-pay');
input.addEventListener('change', () => {
if (!input.checked) td.classList.add('flash-pay'); else td.classList.remove('flash-pay');
try { saveDataToLocalStorage(); } catch(e){}
});
}
// --- end added ---
if (input.classList.contains("expandable-input")) {
attachExpandEvents(input);
}
td.appendChild(input);
tr.appendChild(td);
});
// เซลล์ Renewed (Checkbox และ Icon)
const tdRenewed = document.createElement("td");
tdRenewed.className = "renewed-cell";
// ⭐️ FIX 3: บังคับความกว้างขั้นต่ำ (width: 1%)
tdRenewed.style.width = "1%";
// ⭐️ FIX 4: สร้าง DIV ตัวกลางเพื่อจัดการ Flexbox (ตามที่แก้ไขใน CSS)
const divRenewedContent = document.createElement("div");
divRenewedContent.className = "renewed-content"; // ใช้คลาส .renewed-content
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.className = "form-check-input renewed-checkbox";
checkbox.checked = d.renewed;
const icon = document.createElement("span");
icon.className = "alert-icon";
icon.textContent = "🚨";
divRenewedContent.appendChild(checkbox);
divRenewedContent.appendChild(icon);
tdRenewed.appendChild(divRenewedContent);
tr.appendChild(tdRenewed);
// ⭐️ FIX 5: เซลล์ Actions (มีความกว้างพอดี 1% และปุ่มไม่แตกแถว)
const tdActions = document.createElement("td");
tdActions.style.width = "1%"; // บังคับให้แคบที่สุดตามเนื้อหา
tdActions.style.textAlign = "center";
const divContainer = document.createElement("div");
divContainer.style.display = "flex";
divContainer.style.justifyContent = "center";
divContainer.style.gap = "5px";
divContainer.style.whiteSpace = "nowrap"; // ห้ามแตกแถว
const btnDup = document.createElement("button");
btnDup.className = "btn btn-warning btn-sm action-btn act-dup";
btnDup.textContent = "⧉";
const btnDel = document.createElement("button");
btnDel.className = "btn btn-danger btn-sm action-btn act-del";
btnDel.textContent = "🗑";
divContainer.appendChild(btnDup);
divContainer.appendChild(btnDel);
tdActions.appendChild(divContainer);
tr.appendChild(tdActions);
return tr;}
✅ สรุปสั้นที่สุด: V66-1 = เวอร์ชันปรับปรุง Layout, ความกว้างคอลัมน์, ความถูกต้องของ Class Bootstrap และความเสถียรของ checkbox
V66 = เวอร์ชันเริ่มต้น ที่เน้นแค่ทำงาน
V66-1 = เวอร์ชันปรับ UI/UX ทั้งหมด และแก้หลายปัญหาที่ V66 ยังไม่ทำ
📌 สรุปแบบละเอียดทีละจุด
1) การจัดความกว้างคอลัมน์ (width)
✔ V66
ไม่มีการควบคุมความกว้างเฉพาะคอลัมน์ → ทำให้ “วันที่” และ “checkbox” กว้างเกินไป และทำให้ตารางเบี้ยวในบางจอ
✔ V66-1
เพิ่มโค้ดบังคับความกว้าง:
if (cell.type === 'date' || cell.type === 'checkbox') {
td.style.width = "1%";
}
- สำหรับ input date มี inline style:
input.style.width = "120px";
ผลลัพธ์ → ตารางสวยขึ้น ไม่เบี้ยว ไม่โดนขยายจนล้น
2) การจัดการ class ของ input (Bootstrap)
✔ V66
ทุก input ใช้ class เดียว:
"class=form-control"
จึงทำให้ date box ใหญ่, checkbox ใหญ่, และการแสดงผลผิดปกติ
✔ V66-1
แยกอย่างถูกต้อง:
Text / Number / Date ใช้:
form-control form-control-sm
Checkbox ใช้:
form-check-input
➡ UI เล็กลง เข้ารูปแบบ Bootstrap 100%
3) การจัด layout สำหรับคอลัมน์ Renewed (🚨)
✔ V66
Renewed cell ใส่ checkbox + icon ปนกันใน tdเดียว ไม่มี flex →
ผล: บางจอ icon ล้น, เบี้ยว, ไม่ตรงกลาง
✔ V66-1
ทำ container กลาง:
<div class="renewed-content">
[checkbox] [icon]
</div>
- ใช้ CSS flex จัดให้อยู่กึ่งกลางแน่นอน
ผล = ตรงกลางสวย 100% ทุกอุปกรณ์
4) การควบคุมพื้นที่ปุ่ม (Actions column)
V66
ต้องคอยแก้เองใน CSS
V66-1
เพิ่มความเสถียร:
tdActions.style.width = "1%";
divContainer.style.whiteSpace = "nowrap";
ปุ่ม ⧉ และ 🗑 ไม่แตกแถวแน่นอน
5) Checkbox Receive/Pay – ระบบกระพริบพื้นหลัง
ทั้งสองเวอร์ชันมีเหมือนกัน
แต่ V66-1 จัด Class ถูกต้องกว่า เช่น:
if (cell.isPay) {
input.classList.add('form-check-input');
}
V66 ลืมใส่ในบางตำแหน่ง
6) ความเป็นระเบียบของโค้ด
✔ V66
ดูยาวและปน class บางอย่างไม่ถูกหลัก
✔ V66-1
จัดรูปแบบให้ “consistent” + ลำดับชัดเจน
อ่านง่ายกว่า 30–40%
7) ความเข้ากันกับระบบขยายช่อง (expandable-input)
เหมือนกัน แต่ใน V66-1 layout เสถียรกว่าเพราะ input กว้างเหมาะสม → เมื่อ hover ขยายแล้ว ไม่ดันตารางข้างๆ
🎉 สรุปสุดท้าย
| เรื่อง | V66 | V66-1 |
|---|---|---|
| ความกว้างคอลัมน์ | ❌ ผันผวน | ✅ คงที่ 1% และ date 120px |
| Checkbox layout | ❌ ใหญ่และเบี้ยว | ✅ form-check-input ถูกต้อง |
| Date input | ❌ ขนาดแปลก | ✅ fix 120px |
| Renewed column | ❌ ล้น/เบี้ยว | ✅ flex กลางสมบูรณ์ |
| Actions column | ❌ ปุ่มบางจอแตกแถว | ✅ fix |
| ความเสถียร UI | ปานกลาง | สูง |
| ความเรียบร้อยโค้ด | ปกติ | ดีมาก |