• December 3, 2025

    ปัญหาที่คุณพบเกิดจาก การแปลงชนิดข้อมูลที่ไม่ถูกต้อง (Type Coercion) ระหว่างการโหลดข้อมูลจาก Local Storage เข้าสู่ฟังก์ชัน addRow ซึ่งทำให้ค่าที่เป็น Boolean (true / false) ถูกแปลงเป็น String ('true' / 'false') โดยไม่ได้ตั้งใจ

    ส่วนประเด็นเรื่องตัวอักษร P (ตัวใหญ่) กับ p (ตัวเล็ก) นั้น ไม่มีผลต่อโค้ด JavaScript ที่ใช้ในการบันทึกและแสดงผล เพราะโค้ดทั้งหมดใช้คีย์เป็น paid (ตัวเล็ก) ตรงกัน แต่มีผลต่อการอ่านค่าจาก Local Storage เมื่อมีการแปลงชนิดข้อมูลผิดพลาดครับ

    การแก้ไข: 2 จุดในโค้ด JavaScript

    คุณต้องแก้ไขในฟังก์ชัน addRow และ duplicateRow เพื่อให้แน่ใจว่าค่าสำหรับ paid และ pay ถูกเก็บเป็น Boolean เสมอ:

    1. แก้ไขในฟังก์ชัน addRow (แก้ปัญหาหลัก: การโหลดจาก Local Storage)

    ในฟังก์ชัน addRow ให้เปลี่ยนวิธีการกำหนดค่า paid และ pay จากการแปลงเป็น String ให้เป็นการบังคับให้เป็น Boolean (!!)

    ค้นหาส่วนนี้ในฟังก์ชัน addRow:

    JavaScript

    // โค้ดเดิม (ทำให้ boolean กลายเป็น string เช่น 'false')
    const rowData = {
        // ...
        premium: String(d.premium || ''),
        paid: String(d.paid || ''), // ❌ บรรทัดนี้ทำให้เกิดปัญหา
        pay: String(d.pay || ''),   // ❌ บรรทัดนี้ทำให้เกิดปัญหา
        note: d.note || '',
        // ...
    };
    

    แก้ไขเป็น:

    JavaScript

    // โค้ดที่แก้ไข (บังคับให้เป็น boolean: true หรือ false)
    const rowData = {
        // ...
        premium: String(d.premium || ''),
        paid: !!d.paid, // ✅ ใช้ !! เพื่อให้แน่ใจว่าเป็น Boolean
        pay: !!d.pay,   // ✅ ใช้ !! เพื่อให้แน่ใจว่าเป็น Boolean
        note: d.note || '',
        // ...
    };
    

    2. แก้ไขในฟังก์ชัน duplicateRow (แก้ปัญหาเสริม: การคัดลอกแถว)

    เมื่อคุณกดปุ่ม Duplicate (คัดลอก) ฟังก์ชันนี้จะดึงค่าจาก Input Element มาใช้ ซึ่งสำหรับ Checkbox คุณต้องดึงค่า .checked ไม่ใช่ .value

    ค้นหาส่วนนี้ในฟังก์ชัน duplicateRow:

    JavaScript

    // โค้ดเดิม (อ่านค่า .value ซึ่งเป็น string 'on' หรือ '')
    const d={ 
        // ...
        premium:cells[4].value, 
        paid:cells[5].value, // ❌ ต้องเป็น .checked
        pay:cells[6].value,  // ❌ ต้องเป็น .checked
        note:cells[7].value, 
        // ...
    }; 
    

    แก้ไขเป็น:

    JavaScript

    // โค้ดที่แก้ไข (อ่านค่า .checked ซึ่งเป็น boolean true หรือ false)
    const d={ 
        // ...
        premium:cells[4].value, 
        paid:cells[5].checked, // ✅ ใช้ .checked
        pay:cells[6].checked,  // ✅ ใช้ .checked
        note:cells[7].value, 
        // ...
    }; 
    

    เมื่อแก้ไขทั้งสองจุดแล้ว ระบบจะสามารถโหลดค่าสถานะ paid ที่เป็น Boolean จาก Local Storage ได้อย่างถูกต้อง และแสดงผลเป็น Checkbox ที่ถูกติ๊ก/ไม่ถูกติ๊ก ตามค่าที่บันทึกไว้ครับ

    เดิมที โค๊ดทำงานได้เพราะ

    // ใน addRow
    paid: String(d.paid || ''),
    pay: String(d.pay || ''),
    
    // ใน duplicateRow
    paid:cells[5].value, // ❌ โค้ดเดิม
    pay:cells[6].value,  // ❌ โค้ดเดิม

    ตามหลักต้องทำแบบนี้

    // ใน addRow
    paid: !!d.paid, // บังคับให้เป็น true/false ก่อนบันทึก
    pay: !!d.pay,
    
    // ใน duplicateRow
    paid: cells[5].checked, // อ่านค่าเป็น Boolean
    pay: cells[6].checked,  // อ่านค่าเป็น Boolean

    คำอธิบาย ละเอียด

    เมื่อ Input type เป็น Checkbox การเรียกใช้ .value จะไม่คืนค่าสถานะว่าถูกติ๊กหรือไม่ แต่จะคืนค่าเป็น String ตามคุณสมบัติ value ของ Input นั้นแทนครับ ซึ่งโดยทั่วไปแล้ว:

    • ถ้า Checkbox ถูกติ๊ก (.checked = true): .value จะคืนค่าเป็น "on" (String) หรือค่าใดก็ตามที่คุณกำหนดไว้ในแอตทริบิวต์ value ของ HTML
    • ถ้า Checkbox ไม่ถูกติ๊ก (.checked = false): .value จะคืนค่าเป็น "" (Empty String) หรือค่าใดก็ตามที่คุณกำหนดไว้

    ดังนั้น ในโค้ด duplicateRow ที่มีอยู่เดิม:

    JavaScript

    paid:cells[5].value, // ❌ โค้ดเดิม
    pay:cells[6].value,  // ❌ โค้ดเดิม
    

    ผลกระทบของการใช้ .value กับ Checkbox

    1. สำหรับ Checkbox ที่ถูกติ๊ก: จะได้ค่าเป็น String "on" (หรือค่าอื่นที่ไม่ใช่ Empty String)
      • เมื่อนำไปใช้ในบริบทของ Boolean (เช่น ใน addRow) ค่า "on" จะถูกแปลงเป็น true (Boolean)
      • ผลลัพธ์: ถูกต้อง
    2. สำหรับ Checkbox ที่ไม่ถูกติ๊ก: จะได้ค่าเป็น Empty String ""
      • เมื่อนำไปใช้ในบริบทของ Boolean (เช่น ใน addRow) ค่า "" (Empty String) จะถูกแปลงเป็น false (Boolean)
      • ผลลัพธ์: ถูกต้อง

    สรุป

    ถึงแม้ว่าการใช้ .value จะให้ผลลัพธ์ true หรือ false ทางตรรกะที่ถูกต้องอยู่แล้ว เนื่องจาก JavaScript มีการ Type Coercion (การแปลงชนิดข้อมูลอัตโนมัติ) แต่ก็เป็นวิธีที่ ไม่ถูกต้องตามหลักการเขียนโปรแกรม และอาจสร้างความสับสนได้ในอนาคต

    การแก้ไขที่ถูกต้องและชัดเจนตามวัตถุประสงค์ที่สุดคือการใช้ .checked เสมอ เพราะมันถูกออกแบบมาเพื่อคืนค่าสถานะ Boolean ของ Checkbox โดยตรง:

    JavaScript

    paid:cells[5].checked, // ✅ คืนค่าเป็น true หรือ false ตรงๆ
    pay:cells[6].checked,  // ✅ คืนค่าเป็น true หรือ false ตรงๆ
    

    คำแนะนำ: แม้ว่าโค้ดเดิมจะบังเอิญทำงานได้ (โดยอาศัย Type Coercion) แต่คุณควรเปลี่ยนไปใช้ .checked ตามที่ผมได้แนะนำไปในคำตอบก่อนหน้า เพื่อให้โค้ดของคุณชัดเจนและเชื่อถือได้มากขึ้นครับ



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

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






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

Categories


Uncategorized