Rabu, 28 Januari 2026

Formulir Absensi

 






Code.gs

// Code.gs

var sheetName = "Attendance Form";
var headers = ["Timestamp", "First Name", "Last Name", "Position", "Mobile Number", "Signature Image URL"];
var folderId = "15TdXdrtYNst3V5XDXzKT893-4pDKw9yY"; // Replace with your folder ID

function createFormSheet() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  if (!spreadsheet.getSheetByName(sheetName)) {
    spreadsheet.insertSheet(sheetName);
    var sheet = spreadsheet.getSheetByName(sheetName);
    sheet.appendRow(headers);
  }
}

function onSubmitForm(formData) {
  if (!formData) {
    Logger.log("Form data is undefined or null.");
    return;
  }
 
  if (!formData.firstName || !formData.lastName || !formData.position || !formData.mobileNumber || !formData.signature) {
    Logger.log("One or more required fields are missing in form data.");
    return;
  }

  Logger.log("Received form data: " + JSON.stringify(formData));

  var responseData = [new Date(), formData.firstName, formData.lastName, formData.position, formData.mobileNumber];

  // Save signature image to Google Drive
  var signatureImage = formData.signature.split(',')[1]; // Remove data URL header
  var folder = DriveApp.getFolderById(folderId);
  var file = folder.createFile(Utilities.newBlob(Utilities.base64Decode(signatureImage), 'image/png', 'signature.png'));
  var fileUrl = file.getUrl();
  responseData.push(fileUrl);

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  sheet.appendRow(responseData);
}

function doGet() {
  createFormSheet();
  var htmlOutput = HtmlService.createHtmlOutputFromFile('index').setTitle('Attendance Form');
  return htmlOutput;
}

Index.html

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <base target="_top">
  <title>Attendance Form</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  <style>
    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }
    .form-container {
      max-width: 600px;
    }
    .signature-pad {
      border: 1px solid #cfcfcf;
      width: 300px;
      height: 150px;
      cursor: crosshair;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="form-container">
      <h2 class="mb-4">Attendance Form</h2>
      <form id="attendanceForm">
        <div class="form-row">
          <div class="form-group col-md-6">
            <label for="firstName">First Name:</label>
            <input type="text" class="form-control" id="firstName" name="firstName" required>
          </div>
          <div class="form-group col-md-6">
            <label for="lastName">Last Name:</label>
            <input type="text" class="form-control" id="lastName" name="lastName" required>
          </div>
        </div>
        <div class="form-row">
          <div class="form-group col-md-6">
            <label for="position">Position:</label>
            <input type="text" class="form-control" id="position" name="position" required>
          </div>
          <div class="form-group col-md-6">
            <label for="mobileNumber">Mobile Number:</label>
            <input type="number" class="form-control" id="mobileNumber" name="mobileNumber" required>
          </div>
        </div>
        <div class="form-group">
          <label for="signature">Signature:</label><br>
          <canvas id="signatureCanvas" class="signature-pad"></canvas><br>
          <a href="#" id="clearSignature" class="btn btn-outline-secondary">Clear</a>
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
    </div>
  </div>
 
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  <script>
    var canvas = document.getElementById('signatureCanvas');
    var ctx = canvas.getContext('2d');
    var drawing = false;
    var prevX = 0;
    var prevY = 0;

    canvas.addEventListener('mousedown', function(e) {
      drawing = true;
      prevX = e.clientX - canvas.offsetLeft;
      prevY = e.clientY - canvas.offsetTop;
    });

    canvas.addEventListener('mousemove', function(e) {
      if (drawing) {
        var currX = e.clientX - canvas.offsetLeft;
        var currY = e.clientY - canvas.offsetTop;

        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.stroke();

        prevX = currX;
        prevY = currY;
      }
    });

    canvas.addEventListener('mouseup', function() {
      drawing = false;
    });

    canvas.addEventListener('mouseleave', function() {
      drawing = false;
    });

    document.getElementById('clearSignature').addEventListener('click', function(e) {
      e.preventDefault();
      clearCanvas();
    });

    function clearCanvas() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    document.getElementById('attendanceForm').addEventListener('submit', function(e) {
      e.preventDefault();
      var formData = {
        firstName: document.getElementById('firstName').value,
        lastName: document.getElementById('lastName').value,
        position: document.getElementById('position').value,
        mobileNumber: document.getElementById('mobileNumber').value,
        signature: canvas.toDataURL()
      };
      console.log("Form data to be submitted:", formData);
      google.script.run.withSuccessHandler(showConfirmation).onSubmitForm(formData);
      document.getElementById('attendanceForm').reset();
      clearCanvas();
    });

    function showConfirmation() {
      swal("Success!", "Your attendance has been recorded. Thank you!", "success");
    }
  </script>
</body>
</html>


Tidak ada komentar:

Posting Komentar

Formulir Absensi

  https://www.youtube.com/watch?v=Fxzhcj-yZ-U&list=PL36UuWSN9z2fPYaM8BO-Aa2DVPXzBUI4Z https://www.codewithai.my.id/2024/03/project-1-mem...