• November 24, 2025
    // 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 ขยายแล้ว ไม่ดันตารางข้างๆ


    🎉 สรุปสุดท้าย

    เรื่องV66V66-1
    ความกว้างคอลัมน์❌ ผันผวน✅ คงที่ 1% และ date 120px
    Checkbox layout❌ ใหญ่และเบี้ยว✅ form-check-input ถูกต้อง
    Date input❌ ขนาดแปลก✅ fix 120px
    Renewed column❌ ล้น/เบี้ยว✅ flex กลางสมบูรณ์
    Actions column❌ ปุ่มบางจอแตกแถว✅ fix
    ความเสถียร UIปานกลางสูง
    ความเรียบร้อยโค้ดปกติดีมาก



เวอไนน์ไอคอร์ส

ประหยัดเวลากว่า 100 เท่า!






เวอไนน์เว็บไซต์⚡️
สร้างเว็บไซต์ ดูแลเว็บไซต์

Categories


Uncategorized