boychawin.com
Profile 👤

สร้าง Modal Service ด้วย Vanilla JS

Nov. 17, 2024 · boychawin

เดียววันนี้พาสร้าง Modal Service ด้วย Vanilla JavaScript แบบง่ายๆ แต่ใช้งานได้จริง เอา Modal ไปปรับแต่งได้เลย โดยที่เราไม่พึ่ง Framework ใด ๆ สายเพียวๆ

โครงสร้าง Modal

เริ่มต้นด้วย HTML Template ที่จะใช้เป็น Modal หลักของเรา

ไฟล์ modal.html

<div id="modalTemplate" class="modal">
  <div class="modal-content">
    <span class="modal-close-btn">✕</span>
    <div class="modal-header"></div>
    <div class="modal-info"></div>
    <div class="modal-actions">
      <button class="btn btn-secondary cancel-btn" style="display: none;">ยกเลิก</button>
      <button class="btn btn-primary confirm-btn" style="display: none;">ยืนยัน</button>
    </div>
  </div>
</div>

CSS สำหรับ Modal

ไฟล์ modal.css

.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  justify-content: center;
  align-items: center;
}

.modal-content {
  background: white;
  border-radius: 8px;
  padding: 20px;
  max-width: 400px;
  width: 90%;
  text-align: center;
  position: relative;
}

.modal-header {
  font-size: 1.2em;
  font-weight: bold;
  margin-bottom: 10px;
}

.modal-info {
  margin-bottom: 20px;
}

.modal-actions {
  display: flex;
  justify-content: space-around;
}

.modal-close-btn {
  position: absolute;
  top: 10px;
  right: 15px;
  cursor: pointer;
  font-size: 20px;
}

สร้าง ModalService ด้วย Vanilla JS

มาดู เป็นพระเอกของเรากัน

ไฟล์ modal.service.js

class ModalService {
  constructor() {
    this.modalElement = document.getElementById('modalTemplate');
    this.modalHeader = this.modalElement.querySelector('.modal-header');
    this.modalInfo = this.modalElement.querySelector('.modal-info');
    this.cancelButton = this.modalElement.querySelector('.cancel-btn');
    this.confirmButton = this.modalElement.querySelector('.confirm-btn');
    this.onConfirmCallback = null;
    this.onCancelCallback = null;

    this.cancelButton.addEventListener('click', () => this.close());
    this.confirmButton.addEventListener('click', () => this.confirm());
    this.modalElement.querySelector('.modal-close-btn').addEventListener('click', () => this.close());
  }

  open(data, onConfirm, onCancel) {
    this.modalHeader.innerHTML = data.title || 'Default Title';
    this.modalInfo.innerHTML = data.content || 'Loading content...';
    this.onConfirmCallback = onConfirm;
    this.onCancelCallback = onCancel;

    if (data.showConfirmButton) {
      this.confirmButton.style.display = 'inline-block';
    } else {
      this.confirmButton.style.display = 'none';
    }

    if (data.showCancelButton) {
      this.cancelButton.style.display = 'inline-block';
    } else {
      this.cancelButton.style.display = 'none';
    }


    this.modalElement.style.display = 'flex';
  }

  close() {
    if (typeof this.onCancelCallback === 'function') {
      this.onCancelCallback();
    }
    this.modalElement.style.display = 'none';
  }

  confirm() {
    if (typeof this.onConfirmCallback === 'function') {
      this.onConfirmCallback();
    }
    this.close();
  }

  openModal(modalId, fetchUrl, title) {
    const button = document.getElementById(modalId);
    if (button) {
      button.addEventListener('click', () => {
        fetch(fetchUrl)
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP error! Status: ${response.status}`);
            }
            return response.text();
          })
          .then(htmlContent => {
            modalService.open(
              {
                title: title ?? undefined,
                content: htmlContent
              },
              () => console.log('Action confirmed!'),
              () => console.log('Action canceled!')
            );
          })
          .catch(error => {
            console.error('Error fetching HTML:', error);
            alert('Failed to load modal content. Please try again later.');
          });
      });
    } else {
      console.warn(`Button with ID "${modalId}" not found.`);
    }
  }

}

การใช้งาน Modal Service

เมื่อทุกอย่างพร้อมแล้ว มาลองใช้งาน ModalService กันครับ

<script>
const modalService = new ModalService();

modalService.open(
  {
    title: 'แจ้งปิดปรับปรุง',
    content: '...',
    showConfirmButton: true,
    showCancelButton: false,
  },
  () => {
    console.log('ยืนยันการดำเนินการแล้ว');
  },
  () => {
    console.log('การดำเนินการถูกยกเลิก');
  }
);
</script>

หรือ อีกตัวอย่างที่ผมแนะนำ คือใช้งานร่วมกับ fetch ช่วยให้ Modal Service ของคุณกลายเป็นเครื่องมือที่ทรงพลัง เพราะเนื้อหาไม่ถูกเขียนแบบ inline แต่ถูกโหลดจากไฟล์แยกต่างหาก และต้องดูที่เคสด้วยว่าเหมาะสมกับงานไหม

<button id="openModal" class="btn btn-primary">เปิด Modal</button>
<script>
    document.getElementById('openModal').addEventListener('click', () => {
        fetch('./debug.html')
            .then(response => response.text())
            .then(htmlContent => {
                modalService.open(
                {
                    title: 'แจ้งปิดปรับปรุง',
                    content: htmlContent,
                    showConfirmButton: true,
                    showCancelButton: false,
                },
                () => {
                    console.log('ยืนยันการดำเนินการแล้ว');
                },
                () => {
                    console.log('การดำเนินการถูกยกเลิก');
                }
                );
            })
            .catch(error => {
                console.error('Error fetching HTML:', error);
            });
    });
</script>

เพียงแค่นี้เราก็สามารถเปิด Modal สวย ๆ พร้อมปรับแต่งข้อความและปุ่มได้แล้วจ้าา

สรุป

การสร้าง Modal Service ด้วย Vanilla JS ช่วยลดความยุ่งยากและเพิ่มความคล่องตัวในโปรเจ็กต์ คุณสามารถปรับแต่งทุกอย่างได้ง่าย ๆ ทั้งข้อความและปุ่ม แถมยังใช้โค้ดซ้ำได้ในหลายหน้าอีกด้วย

© 2025 boychawin.com - All Rights Reserved

🛡️ เว็บไซต์นี้ใช้คุกกี้เพื่อปรับปรุงประสบการณ์การใช้งาน อ่านนโยบาย