สร้างระบบส่งงานนักเรียนด้วย Google Apps Script



1. สร้าง Google Sheet  

เพื่อใช้เก็บข้อมูลการส่งงาน โดยตั้งชื่อชีต data และเพิ่มคอลัมน์ดังนี้:

| รหัสนักเรียน | ชื่อ นามสกุล | งานที่ 1 | งานที่ 2 | งานที่ 3 | งานที่ 4 | งานที่ 5 | งานที่ 6 | งานที่ 7 | งานที่ 8 | งานที่ 9 | งานที่ 10 |

2. สร้างไฟล์ HTML +  Java Script:

     
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ระบบส่งงานนักเรียน</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    .progress {
      height: 30px;
    }
  </style>
</head>

<body class="bg-light">
  <div class="container mt-5">
    <h1 class="text-center mb-4">ระบบส่งงานนักเรียน</h1>
    <form id="submissionForm">
      <div class="mb-3">
        <label for="studentId" class="form-label">รหัสนักเรียน</label>
        <input type="text" class="form-control" id="studentId" required>
      </div>
      <div class="mb-3">
        <label for="name" class="form-label">ชื่อ</label>
        <input type="text" class="form-control" id="name" required>
      </div>
      <div class="mb-3">
        <label for="assignmentName" class="form-label">เลือกการบ้าน</label>
        <select class="form-select" id="assignmentName" required>
          <option value="" disabled selected>เลือกการบ้าน</option>
          <option value="งานที่ 1">งานที่ 1</option>
          <option value="งานที่ 2">งานที่ 2</option>
          <option value="งานที่ 3">งานที่ 3</option>
          <option value="งานที่ 4">งานที่ 4</option>
          <option value="งานที่ 5">งานที่ 5</option>
          <option value="งานที่ 6">งานที่ 6</option>
          <option value="งานที่ 7">งานที่ 7</option>
          <option value="งานที่ 8">งานที่ 8</option>
          <option value="งานที่ 9">งานที่ 9</option>
          <option value="งานที่ 10">งานที่ 10</option>
        </select>
      </div>
      <div class="mb-3">
        <label for="file" class="form-label">ไฟล์งาน</label>
        <input type="file" class="form-control" id="file" accept=".pdf,.doc,.docx,.jpg,.png" required>
      </div>
      <button type="submit" class="btn btn-primary mb-3">ส่งงาน</button>
    </form>

    <div class="mb-3">
      <button id="checkProgress" class="btn btn-info">ตรวจสอบความก้าวหน้า</button>
    </div>

    <div class="progress mb-3">
      <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
        style="width: 0%;">0%</div>
    </div>

    <div id="progressDetails" class="alert alert-secondary" role="alert" style="display: none;">
      <strong>สถานะ:</strong> <span id="progressStatus"></span>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    const form = document.getElementById('submissionForm');

    form.addEventListener('submit', async (e) => {
      e.preventDefault();

      const studentId = document.getElementById('studentId').value;
      const name = document.getElementById('name').value;
      const assignmentName = document.getElementById('assignmentName').value;
      const fileInput = document.getElementById('file');
      const file = fileInput.files[0];

      if (!file) {
        alert('กรุณาอัพโหลดไฟล์');
        return;
      }

      const reader = new FileReader();
      reader.onload = async () => {
        const base64 = reader.result.split(',')[1];
        const fileData = {
          studentId,
          name,
          assignmentName,
          file: base64,
          fileName: file.name,
          fileType: file.type,
        };

// เรียกใช้ Google Apps Script เพื่อส่งงาน
        google.script.run.withSuccessHandler((response) => {
          if (response.success) {
            progressBar.style.width = '100%';
            progressBar.textContent = '100%';
            alert('ส่งงานสำเร็จ: ' + response.fileUrl);
form.reset();
          } else {
            alert('เกิดข้อผิดพลาด');
          }
        }).submitAssignment(fileData);
      };
      reader.readAsDataURL(file);
    });



    const progressBar = document.getElementById('progressBar');
    const progressDetails = document.getElementById('progressDetails');
    const progressStatus = document.getElementById('progressStatus');

    document.getElementById('checkProgress').addEventListener('click', () => {
      const studentId = document.getElementById('studentId').value;

      if (!studentId) {
        alert('กรุณากรอก รหัสนักเรียน');
        return;
      }

      // เรียกใช้ Google Apps Script เพื่อตรวจสอบความก้าวหน้า
      google.script.run.withSuccessHandler((response) => {
        if (response) {
          const { progressPercentage, completed, total } = response;
          progressBar.style.width = `${progressPercentage}%`;
          progressBar.textContent = `${progressPercentage.toFixed(0)}%`;
          progressDetails.style.display = 'block';
          progressStatus.textContent = `ส่งงานแล้ว ${completed} จากทั้งหมด ${total} งาน`;
form.reset();
        } else {
          alert('ไม่พบข้อมูลนักเรียนนี้');
        }
      }).getProgress(studentId);
    });
  </script>

</body>

</html>

3. สร้างไฟล์ Google Apps Script: 

     
const folderId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data');

function doGet() {
  return HtmlService.createTemplateFromFile('index').evaluate()
    .setTitle("Project Kru Chian")
    .setFaviconUrl("https://semicon.github.io/img/logo2small.png")
    .addMetaTag('viewport', 'width=device-width , initial-scale=1')
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
}


/**
 * ตรวจสอบข้อมูลในชีตและอัปเดตหรือเพิ่มแถวใหม่
 */
function submitAssignment(data) {
  const blob = Utilities.newBlob(Utilities.base64Decode(data.file), data.fileType, data.fileName);
  const folder = DriveApp.getFolderById(folderId);
  const file = folder.createFile(blob);
  const headers = sheet.getDataRange().getDisplayValues()[0]; // หัวตาราง
  const studentIdCol = headers.indexOf('รหัสนักเรียน') + 1; // คอลัมน์รหัสนักเรียน
  const assignmentCol = headers.indexOf(data.assignmentName) + 1; // คอลัมน์การบ้าน
  const lastRow = sheet.getLastRow();
  const studentIdRange = sheet.getRange(1, studentIdCol, lastRow);
  const studentIds = studentIdRange.getDisplayValues().flat();
  const fileUrl = file.getUrl();
  const rowIndex = studentIds.indexOf(data.studentId);
  if (rowIndex !== -1) {
    // พบข้อมูลรหัสนักเรียนในชีต
    const updateRow = rowIndex + 1; // บวก 1 เพราะเริ่มจากแถวที่ 1
    sheet.getRange(updateRow, assignmentCol).setValue(fileUrl);
  } else {
    // ไม่พบข้อมูลนักเรียนในชีต
    //const newRow = lastRow + 1;
    const newRowData = Array(headers.length).fill('');
    newRowData[studentIdCol - 1] = data.studentId;
    newRowData[headers.indexOf('ชื่อ นามสกุล')] = data.name;
    newRowData[assignmentCol - 1] = fileUrl;
    sheet.appendRow(newRowData);
  }

  return { success: true, message: 'ข้อมูลถูกบันทึกแล้ว', fileUrl: fileUrl };
}

/**
 * ตรวจสอบความก้าวหน้า
 */
function getProgress(studentId) {
  const headers = sheet.getDataRange().getDisplayValues()[0];
  const studentIdCol = headers.indexOf('รหัสนักเรียน') + 2;

  const data = sheet.getDataRange().getDisplayValues();
  const studentRow = data.find(row => row[studentIdCol - 2] === studentId.toString());

  if (studentRow) {
    const totalAssignments = headers.length - studentIdCol; // จำนวนงานทั้งหมด
    const completed = studentRow.slice(studentIdCol).filter(value => value).length;
    const progressPercentage = (completed / totalAssignments) * 100;
    return { progressPercentage, completed, total: totalAssignments };
  }

  return null; // ไม่พบข้อมูลนักเรียน
}


อธิบายโค้ด

  1. <select> สำหรับเลือกการบ้าน: ผู้ใช้สามารถเลือกการบ้านได้จากตัวเลือกที่กำหนดไว้ล่วงหน้า
  2. ฟังก์ชัน submitAssignment:
    • ตรวจสอบว่ามีรหัสนักเรียนในชีต data หรือไม่
    • ถ้ามีให้อัปเดตคอลัมน์ของการบ้านด้วย URL
    • ถ้าไม่มีให้เพิ่มแถวใหม่พร้อมข้อมูล
  3. ฟังก์ชัน getProgress:
    • คำนวณความก้าวหน้าโดยหาจำนวนการบ้านที่ส่งแล้วและคำนวณเปอร์เซ็นต์

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