apps script checkbox selections only sending 1st selection to google sheet?

I’m having an issue with my Google Apps Script for handling form submissions that include multiple checkbox selections (parcel ID). Specifically, I need to process all selected checkboxes and send their values to a Google Sheet, but currently, only the first selection is being processed.

Here’s a detailed overview of the problem, along with the relevant code I’m working with:

Problem Description
I have a form that allows users to select multiple checkboxes representing Parcel IDs. When the form is submitted, the selected Parcel IDs should be sent to a Google Sheet, but only the first selected checkbox value is being sent. I need to modify the existing code to ensure that all selected Parcel IDs are processed and recorded in the Google Sheet.

Here is the relevant code.gs

function doPost(e) {
  if (e && e.parameter) {
    var landowner = e.parameter.landowner ? e.parameter.landowner.toString() : '';
    var substation = e.parameter.substation ? e.parameter.substation.toString() : '';
    var comment = e.parameter.comment ? e.parameter.comment.toString() : '';
    var status = e.parameter.status ? e.parameter.status.toString() : '';
    var supervisor = e.parameter.supervisor ? e.parameter.supervisor.toString() : '';
    var date = e.parameter.date ? e.parameter.date : '';
    var parcelIds = e.parameter.parcelId ? e.parameter.parcelId.split(',') : []; // Split the comma-separated parcel IDs into an array

    // Ensure parcelIds is an array
    if (!Array.isArray(parcelIds)) {
      parcelIds = [parcelIds];
    }

    // Loop through each parcel ID and add records
    for (var i = 0; i < parcelIds.length; i++) {
      var parcelId = parcelIds[i].trim(); // Trim any extra whitespace

      if (parcelId) {
        addRecord(landowner, comment, date, supervisor, parcelId, substation); // Add record to Agent Notes
        addToStatuses(landowner, status, date, supervisor, parcelId, substation); // Add record to Statuses
      }
    }

    removeDuplicateStatuses();

    var htmlOutput = HtmlService.createTemplateFromFile('DependentSelect');
    var subs = getDistinctSubstations();
    htmlOutput.message = 'Records Added';
    htmlOutput.subs = subs;

    return htmlOutput.evaluate();
  } else {
    return ContentService.createTextOutput("Error: Invalid request parameters");
  }
}

function addRecord(landowner, comment, date, supervisor, parcelId, substation) {
  var dateObject = new Date(date);
  dateObject.setDate(dateObject.getDate() + 1);
  var formattedDate = Utilities.formatDate(dateObject, Session.getScriptTimeZone(), "MM/dd/yyyy");
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Agent Notes");
  dataSheet.appendRow([landowner, comment, formattedDate, supervisor, parcelId, substation]);

  var backupSS = SpreadsheetApp.openById("...");
  var backupCommentsSheet = backupSS.getSheetByName("Comments");
  backupCommentsSheet.appendRow([landowner, comment, formattedDate, supervisor, parcelId, substation]);
}


function addToStatuses(landowner, status, date, supervisor, parcelId, substation) {
  var dateObject = new Date(date);
  dateObject.setDate(dateObject.getDate() + 1);
  var formattedDate = Utilities.formatDate(dateObject, Session.getScriptTimeZone(), "MM/dd/yyyy");
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var statusSheet = ss.getSheetByName("Statuses");
  statusSheet.appendRow([landowner, status, formattedDate, supervisor, parcelId, substation]);

  var backupSS = SpreadsheetApp.openById("...");
  var backupStatusesSheet = backupSS.getSheetByName("Statuses");
  backupStatusesSheet.appendRow([landowner, status, formattedDate, supervisor, parcelId, substation]);
}

Is there anything glaringly obvious I’m missing?

Here is my html side incase there’s something I am missing there

...html stuff
  <script src="https://apis.google.com/js/api.js"></script>
  <script>
    // Function to set the default date to today's date
    function setDefaultDate() {
      var today = new Date();
      var day = today.getDate();
      var month = today.getMonth() + 1; // Months are zero indexed
      var year = today.getFullYear();

      // Format the date as YYYY-MM-DD for the input field
      var formattedDate = year + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;

      // Set the default value of the date picker input field directly
      var datePicker = document.getElementById("datePicker");
      datePicker.setAttribute("value", formattedDate);

      // Set the value of the text box to the same date
      datePicker.value = formattedDate;
    }

    function updateSubstations(supervisor) {
      google.script.run.withSuccessHandler(function(substations) {
        var substationDropdown = document.getElementById("substation");
        substationDropdown.innerHTML = "";
        var option = document.createElement("option");
        option.value = "";
        option.text = "";
        substationDropdown.appendChild(option);

        // Populate Substation dropdown with matching substations
        substations.forEach(function(substation) {
          var option = document.createElement("option");
          option.value = substation;
          option.text = substation;
          substationDropdown.appendChild(option);
        });

        // Select the previously selected substation if available
        var savedSubstation = localStorage.getItem("substation");
        if (savedSubstation && substations.includes(savedSubstation)) {
          substationDropdown.value = savedSubstation;
        }
      }).getDistinctSubstations(supervisor); // Call server function to get matching substations
    }

    function updateMaxStatusAndLandownerInfo() {
      var selectedParcelIds = Array.from(document.querySelectorAll("#parcelIdContainer input[type=checkbox]:checked"))
        .map(checkbox => checkbox.value);

      if (selectedParcelIds.length > 0) {
        // Call updateMaxStatusForParcel with the first selected Parcel ID
        updateMaxStatusForParcel(selectedParcelIds[0]);

        // Call getLandownerInfo with the first selected Parcel ID
        getLandownerInfo(selectedParcelIds[0]);
      }
    }

    function updateParcelInfo(landowner) {
      // Trigger search in "Raw Data" worksheet for landowner value
      google.script.run.withSuccessHandler(function(parcelIds) {
        var parcelIdContainer = document.getElementById("parcelIdContainer");
        parcelIdContainer.innerHTML = ""; // Clear previous checkboxes

        // Populate Parcel ID checkboxes with matching rows from columns U3:U
        parcelIds.forEach(function(parcelId) {
          var checkbox = document.createElement("input");
          checkbox.type = "checkbox";
          checkbox.name = "parcelId";
          checkbox.value = parcelId;
          checkbox.id = parcelId;
          checkbox.addEventListener("change", updateMaxStatusAndLandownerInfo);

          var label = document.createElement("label");
          label.htmlFor = parcelId;
          label.appendChild(document.createTextNode(parcelId));

          parcelIdContainer.appendChild(checkbox);
          parcelIdContainer.appendChild(label);
          parcelIdContainer.appendChild(document.createElement("br"));
        });
      }).getParcelIdsByLandowner(landowner); // Call server function to get matching parcel IDs
    }

    function getLandownerInfo(parcel) {
      google.script.run.withSuccessHandler(function(landownerInfo) {
        document.getElementById("landowner-info-content").innerText = landownerInfo;
      }).getLandownerInfo(parcel);
    }

    function getParcels(substation) {
      google.script.run.withSuccessHandler(function(parcels) {
        var parcelDropdown = document.getElementById("parcel");
        parcelDropdown.innerHTML = "";
        var option = document.createElement("option");
        option.value = "";
        option.text = "";
        parcelDropdown.appendChild(option);

        // Sort the parcel options alphabetically
        parcels.sort().forEach(function(parcel) {
          var option = document.createElement("option");
          option.value = parcel;
          option.text = parcel;
          parcelDropdown.appendChild(option);
        });

        // Update parcel info immediately after selecting a parcel
        var selectedParcel = parcelDropdown.value;
        updateParcelInfo(selectedParcel);
      }).getParcels(substation);
    }

    function updateMaxStatusForParcel(parcel) {
      google.script.run.withSuccessHandler(function(maxStatus) {
        var statusDropdown = document.getElementById("status");
        statusDropdown.innerHTML = ""; // Clear previous options

        // Define status options in the desired order
        var statusOptions = ["", "Assigned to Agent", "Outreach", "Negotiating", "Pledged", "Signed", "Dropped"];

        // Add options to the dropdown in the defined order
        statusOptions.forEach(function(status) {
          var option = document.createElement("option");
          option.value = status;
          option.text = status;
          if (status === maxStatus) {
            option.selected = true; // Select the option if it matches the max status
          }
          statusDropdown.appendChild(option);
        });
      }).getMaxStatusForParcel(parcel);
    }

    function saveSubmittedValues() {
      var supervisor = document.getElementById("supervisor").value;
      var substation = document.getElementById("substation").value;

      // Save submitted values to local storage
      localStorage.setItem("supervisor", supervisor);
      localStorage.setItem("substation", substation);
    }

    function prefillDropdowns() {
      // Retrieve saved values from local storage
      var supervisor = localStorage.getItem("supervisor");
      var substation = localStorage.getItem("substation");

      // Pre-fill supervisor dropdown
      if (supervisor) {
        document.getElementById("supervisor").value = supervisor;
        // Trigger the onchange event of supervisor dropdown to update substation dropdown
        updateSubstations(supervisor);
      }

      // Pre-fill substation dropdown
      if (substation) {
        document.getElementById("substation").value = substation;
        // Trigger the onchange event of substation dropdown to populate parcels
        getParcels(substation);
      }
    }

    window.onload = function() {
      setDefaultDate();
      prefillDropdowns();
    };

  function validateForm() {
  var isValid = true;
  var supervisor = document.getElementById("supervisor").value;
  var substation = document.getElementById("substation").value;
  var parcelIdCheckboxes = document.querySelectorAll("#parcelIdContainer input[type=checkbox]:checked");
  var status = document.getElementById("status").value;
  var date = document.getElementById("datePicker").value;
  var comment = document.getElementById("comment").value;

  // Collect all selected parcel IDs
  var parcelIds = Array.from(parcelIdCheckboxes).map(checkbox => checkbox.value);

  // Check if any field is null or blank
  if (!supervisor || !substation || parcelIds.length === 0 || !status || !date || !comment) {
    document.getElementById("submit-message").innerText = "All fields must be filled.";
    return false; // Prevent form submission
  }

  // Save submitted values to local storage
  saveSubmittedValues();

  // Set the parcel IDs as a comma-separated string
  document.getElementById("parcelId").value = parcelIds.join(',');

  // Call server-side function to sort sheets after form submission
  google.script.run.withSuccessHandler(function() {
    // Form submission will only proceed after sorting is done
    document.forms[0].submit();
  }).sortSheets();

  // Disable form submit button to prevent resubmission
  document.getElementById("submit-button").disabled = true;

  return false; // Prevent default form submission to wait for sorting
}



    // Prevent form resubmission popup on page reload
    if (window.history.replaceState) {
      window.addEventListener("beforeunload", function () {
        window.history.replaceState(null, null, window.location.href);
      });
    }
  </script>
</head>
<body>
  <div class="container">
    <img src="https://i.imgur.com/16QsZja.png" alt="Header Image" style="width: 100%; max-width: 200px;">

    <h1>Daily Contact Form</h1>

    <form method="post" action="<?= getUrl() ?>" onsubmit="return validateForm();">

      <label><strong>Land Agent</strong></label><br>
      <select name="supervisor" id="supervisor" onchange="updateSubstations(this.value)">
        <option value=""></option>
        <option value="Dan">Dan</option>
        <option value="Ian">Ian</option>
        <option value="Parker">Parker</option>
        <option value="Scott">Scott</option>
      </select><br><br>

      <label><strong>Substation</strong></label><br>
      <select name="substation" id="substation" onchange="getParcels(this.value)">
        <option value=""></option>
      </select><br><br>

      <label><strong>Landowner</strong></label><br>
      <select name="landowner" id="parcel" onchange="updateParcelInfo(this.value)">
        <!-- Parcel dropdown will be populated dynamically -->
      </select><br><br>

      <div id="parcelIdContainer">
      </div>


      <label><strong>Status</strong></label><br>
      <select name="status" id="status">
        <option value=""></option>
        <option value="Assigned to Agent">Assigned to Agent</option>
        <option value="Outreach">Outreach</option>
        <option value="Negotiating">Negotiating</option>
        <option value="Pledged">Pledged</option>
        <option value="Signed">Signed</option>
        <option value="Dropped">Dropped</option>
      </select><br><br>

      <label><strong>Date</strong></label><br>
      <input type="date" name="date" id="datePicker"><br><br>

      <label><strong>Comment</strong></label><br>
      <textarea name="comment" id="comment"></textarea><br><br>

      <input type="submit" name="submitButton" id="submit-button" value="Submit" />
      <span id="submit-message" class="submit-message"></span>
    </form>

    <div class="landowner-info">
      <h2>Landowner Info</h2>
      <p id="landowner-info-content"></p> <!-- Display landowner information -->
    </div>
  </div>
</body>
</html>

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật