Dynamic Dropdown Form (Autocomplete 4 level)

 



โค้ดนี้สร้างฟอร์มแบบไดนามิกโดยใช้ dropdown ที่ข้อมูลของแต่ละ dropdown ขึ้นอยู่กับค่าที่เลือกก่อนหน้า.

ฟังก์ชันหลัก:
  • populateDropdown: เติมข้อมูลใน dropdown.
  • addForm: สร้างฟอร์มใหม่.
  • initForm: เริ่มต้นฟอร์มแรกด้วยข้อมูลจาก Google Sheet.

การออกแบบนี้ยืดหยุ่นต่อการเพิ่มฟอร์มหรือปรับข้อมูลใหม่.

code.js

function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
      .setTitle("ระบบจัดทีม")
      .addMetaTag('viewport','width=device-width , initial-scale=1.0')
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}


// ดึงข้อมูลจาก Google Sheet
function getSheetData() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('list');
  const data = sheet.getDataRange().getValues();
  const obj = {};
 
  data.slice(1).forEach(([area, subArea, mainWork, detailWork]) => {
    if (!obj[area]) obj[area] = {};
    if (!obj[area][subArea]) obj[area][subArea] = [];
    obj[area][subArea].push([mainWork, detailWork]);
  });

  return obj;
}


index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Dynamic Dropdown</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container mt-4">
      <h3>Dynamic Dropdown Form</h3>
      <div id="formContainer"></div>
      <button class="btn btn-primary mt-3" onclick="addForm()">Add Form</button>
    </div>

    <template id="formTemplate">
      <div class="formGroup">
        <div class="card mb-3">
          <div class="card-body">
            <div class="row">
              <div class="col mb-3">
                <label for="colA">AREA</label>
                <select class="form-select colA" required>
                  <option value="" disabled selected>Select AREA</option>
                </select>
              </div>
              <div class="col mb-3">
                <label for="colB">LOCATION</label>
                <select class="form-select colB" disabled required>
                  <option value="" disabled selected>Select LOCATION</option>
                </select>
              </div>
            </div>
            <div class="row">
              <div class="col mb-3">
                <label for="colC">MAIN WORK</label>
                <select class="form-select colC" disabled required>
                  <option value="" disabled selected>Select MAIN WORK</option>
                </select>
              </div>
              <div class="col mb-3">
                <label for="colD">WORK DETAIL</label>
                <select class="form-select colD" disabled required>
                  <option value="" disabled selected>Select WORK DETAIL</option>
                </select>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>

    <script>
      let sheetData = {};

      // โหลดข้อมูลจาก Google Sheet
      google.script.run.withSuccessHandler(initForm).getSheetData();

      function initForm(data) {
        sheetData = data;
        addForm(); // สร้างฟอร์มแรกเมื่อโหลดเสร็จ
      }

      function addForm() {
        const template = document.getElementById('formTemplate').content.cloneNode(true);
        const container = document.getElementById('formContainer');
        const formGroup = template.querySelector('.formGroup');

        const colA = formGroup.querySelector('.colA');
        const colB = formGroup.querySelector('.colB');
        const colC = formGroup.querySelector('.colC');
        const colD = formGroup.querySelector('.colD');

        // เติมข้อมูลใน Dropdown แรก (AREA)
        populateDropdown(colA, Object.keys(sheetData));
        colA.addEventListener('change', () => {
          populateDropdown(colB, Object.keys(sheetData[colA.value] || {}));
          colB.disabled = !colA.value;
          colC.disabled = true;
          colD.disabled = true;
          colC.innerHTML = '<option value="" disabled selected>Select MAIN WORK</option>';
          colD.innerHTML = '<option value="" disabled selected>Select WORK DETAIL</option>';
        });

        colB.addEventListener('change', () => {
          populateDropdown(colC, (sheetData[colA.value]?.[colB.value] || []).map(item => item[0]));
          colC.disabled = !colB.value;
          colD.disabled = true;
          colD.innerHTML = '<option value="" disabled selected>Select WORK DETAIL</option>';
        });

        colC.addEventListener('change', () => {
          populateDropdown(colD, (sheetData[colA.value]?.[colB.value] || [])
            .filter(item => item[0] === colC.value)
            .map(item => item[1]));
          colD.disabled = !colC.value;
        });

        container.appendChild(formGroup);
      }

      function populateDropdown(dropdown, options) {
        dropdown.innerHTML = '<option value="" disabled selected>Select an Option</option>';
        options.forEach(option => {
          const opt = document.createElement('option');
          opt.value = option;
          opt.textContent = option;
          dropdown.appendChild(opt);
        });
      }
    </script>
  </body>
</html>


1. โครงสร้าง HTML

<div id="formContainer"></div>
<button class="btn btn-primary mt-3" onclick="addForm()">Add Form</button>
  • formContainer: เป็นคอนเทนเนอร์ที่ใช้เก็บฟอร์มต่าง ๆ ที่ถูกสร้างขึ้น.
  • ปุ่ม Add Form: ใช้เพื่อเพิ่มฟอร์มใหม่เมื่อกดปุ่ม โดยเรียกใช้ฟังก์ชัน addForm().

2. Template ฟอร์ม (ใช้ <template>)


<template id="formTemplate"> <div class="formGroup"> <div class="card mb-3"> <div class="card-body"> <!-- Dropdowns สำหรับ AREA, LOCATION, MAIN WORK และ WORK DETAIL --> </div> </div> </div> </template>
  • <template>: ใช้เก็บโครงสร้าง HTML ของฟอร์มแต่ละชุด.
  • formGroup: คลาสที่ครอบฟอร์มหนึ่งชุด.
  • มี 4 dropdown:
    • AREA (เลือกโซน)
    • LOCATION (เลือกตำแหน่งในโซน)
    • MAIN WORK (เลือกประเภทงาน)
    • WORK DETAIL (รายละเอียดงาน)

3. การโหลดข้อมูลจาก Google Apps Script


google.script.run.withSuccessHandler(initForm).getSheetData();
  • google.script.run: ใช้สำหรับเรียกฟังก์ชันจาก Google Apps Script.
  • getSheetData(): ฟังก์ชันใน Google Apps Script ที่ส่งข้อมูลจาก Google Sheet กลับมา (ในรูปแบบ JSON).
  • withSuccessHandler(initForm): กำหนดฟังก์ชัน initForm เพื่อรับข้อมูลที่ส่งกลับมา.

4. ฟังก์ชัน initForm


function initForm(data) { sheetData = data; // เก็บข้อมูลจาก Google Sheet ลงในตัวแปร `sheetData` addForm(); // สร้างฟอร์มแรกเมื่อโหลดข้อมูลเสร็จ }
  • data: เป็นข้อมูลที่ดึงมาจาก Google Sheet ในรูปแบบ JSON ที่มีโครงสร้างดังนี้:

{ "CONSTRUCTION ZONE1": { "BUILDING01": [["PIPING1", "Preparation"], ["PIPING2", "Lifting and Installation"]], "BUILDING02": [["PIPING3", "Fit-up/Bolt Tightening"], ["PIPING4", "Welding"], ["PIPING5", "NDE/Inspection"]] }, "CONSTRUCTION ZONE2": { "BUILDING03": [["PIPING6", "Pipe Support Installation"], ["PIPING7", "Equipment&Valve Installation"]], "BUILDING04": [["PIPING9", "Walkdown Line Check"], ["PIPING10", "Punch Closeout"]] } }

5. ฟังก์ชัน addForm


function addForm() { const template = document.getElementById('formTemplate').content.cloneNode(true); const container = document.getElementById('formContainer'); const formGroup = template.querySelector('.formGroup');
  • template: ดึง <template> จาก HTML และสร้างสำเนาของมัน.
  • container: อ้างอิงถึงคอนเทนเนอร์ที่เก็บฟอร์ม.
  • formGroup: กลุ่มฟอร์มที่สร้างจาก template.

Dropdown Binding


const colA = formGroup.querySelector('.colA'); const colB = formGroup.querySelector('.colB'); const colC = formGroup.querySelector('.colC'); const colD = formGroup.querySelector('.colD');
  • อ้างอิงถึง dropdown 4 ตัว (AREA, LOCATION, MAIN WORK, WORK DETAIL) ในฟอร์มที่ถูกสร้างใหม่.

6. การเติมข้อมูลลงใน Dropdown

เติม AREA (Dropdown แรก)


populateDropdown(colA, Object.keys(sheetData)); colA.addEventListener('change', () => { populateDropdown(colB, Object.keys(sheetData[colA.value] || {})); colB.disabled = !colA.value; colC.disabled = true; colD.disabled = true; });
  • populateDropdown(colA, Object.keys(sheetData)):

    • ดึงชื่อ AREA จาก sheetData (คีย์หลักของ JSON).
    • เติมข้อมูลใน dropdown colA.
  • colA.addEventListener('change'):

    • เมื่อเลือก AREA:
      • เติม dropdown LOCATION (colB) ด้วยข้อมูลจาก JSON ที่เกี่ยวข้อง.
      • ปิดการใช้งาน dropdown ถัดไป (MAIN WORK, WORK DETAIL) จนกว่าจะเลือกค่า.

เติม LOCATION และรีเซ็ต Dropdown ถัดไป


colB.addEventListener('change', () => { populateDropdown(colC, (sheetData[colA.value]?.[colB.value] || []).map(item => item[0])); colC.disabled = !colB.value; colD.disabled = true; });
  • เมื่อเลือก LOCATION:
    • เติม dropdown MAIN WORK (colC) ด้วยงานหลักที่เกี่ยวข้อง (PIPING1, PIPING2, ...).

เติม MAIN WORK และแสดง WORK DETAIL


colC.addEventListener('change', () => { populateDropdown(colD, (sheetData[colA.value]?.[colB.value] || []) .filter(item => item[0] === colC.value) .map(item => item[1])); colD.disabled = !colC.value; });
  • เมื่อเลือก MAIN WORK:
    • เติม dropdown WORK DETAIL (colD) ด้วยรายละเอียดงานที่ตรงกับงานหลัก.

7. ฟังก์ชัน populateDropdown


function populateDropdown(dropdown, options) { dropdown.innerHTML = '<option value="" disabled selected>Select an Option</option>'; options.forEach(option => { const opt = document.createElement('option'); opt.value = option; opt.textContent = option; dropdown.appendChild(opt); }); }
  • ใช้เติมข้อมูลใน dropdown:
    1. เคลียร์ตัวเลือกเก่าทั้งหมด.
    2. เพิ่ม <option> สำหรับแต่ละค่าที่ได้รับมาใน options.


Download Now


ถ้ามีประโยชน์โปรดสนับสนุนเพื่อเป็นกำลังใจในการพัฒนาต่อไป






1 ความคิดเห็น

แสดงความคิดเห็น
ใหม่กว่า เก่ากว่า