0
votes

** UPDATED** I have an html form that goes into a google sheet when it is submitted. Currently, one of the fields (student name select) takes multiple values (which I would like to be in separate rows in the google sheet) but only the first selected value shows up. I am not sure how to make the multiple selections appear as separate rows.

Here's the html code for the form. The STUDENT NAME[] options are populated by a function that pulls names from a list (not shown here).

        <form id = "entry" name="entry" style="display:none">
        <b>Select Date:</b> <input type = "date" id = "date" name = "Date[]">
        <b>Your Name: </b> <input type = "text" id = "person" name = "Name[]">
        <!-- Student Name Selection Section -->
        <b> Student Name:</b>
        <select multiple size = "10" id = "students" name = "Student Name[]" ></select>
        <br><b>Type: </b>
        <input type = "text" id = "type" list = "typeList" name = "Type[]">
            <datalist id = "typeList">
                <option name = "Baseline">Baseline</option>
                <option name = "Trial">Trial</option>
            </datalist>
        <br>
        <!-- Domain/Unit/Skill Section (dependent on previous selection) -->
        <br><b>Domain: </b>
        <input type = "text" id="domain" list = "domainList" onchange="getUnits($('#domain').val())" name = "Domain[]">
        <datalist id = "domainList"></datalist>
        <br><b>Unit: </b>
        <input type = "text" id ="unit" list = "unitList" onchange="getSkills($('#unit').val())" name = "Unit[]">
        <datalist id = "unitList"></datalist>
        <br><b>Skill: </b>
        <input type = "text" id="skill" list = "skillList" name = "Skill[]">
        <datalist id = "skillList"></datalist>
        <br><b>Prompting Level: </b>
        <input type = "text" id = "promptingLevel" list = "promptingLevelList" name = "Prompting Level[]">
        <datalist id = "promptingLevelList"></datalist>
        <!-- <input type = "button" id = "addline" value = "Add Another Entry"> -->
        <input id="submit" type="submit" value="Submit" class="btn btn-info">
    </form>

Here's the next part that posts the entry:

   //post submission
   const form = document.forms["entry"];
    $('#entry').submit(function(e){
        e.preventDefault(); fetch('https://script.google.com.....',
              {method: 'POST', mode: 'no-cors', body: new FormData(form)})
              .then(response => console.log('Success!', response))
              .catch(error => console.error('Error!', error.message))
    });

And then in the Google Apps Script, this is triggered on form submit:

var sheetName = 'Submissions';
var scriptProp = PropertiesService.getScriptProperties()

function intialSetup () {
  var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  scriptProp.setProperty('key', activeSpreadsheet.getId());
}

function doPost (e) {
  var lock = LockService.getScriptLock()
  lock.tryLock(10000)

  try {
    var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    var sheet = doc.getSheetByName(sheetName) 
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    var nextRow = sheet.getLastRow() + 1

    var newRow = headers.map(function(header) {
      return header === 'timestamp' ? new Date()
      : e.parameter[header]
    });

    sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  catch (e) {
    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  finally {
    lock.releaseLock()
  }
}

I added [] to the end of the names of the fields in the form but I'm not sure what to do next.

2
You can view this video to get a clear idea about saving the html form in google sheets: youtube.com/watch?v=ZAkESLyXO74Hassaan Ali
I can't repo this because: 1) The select element doesn't have any option elements within it 2) when creating the request body with new FormData the form variable is not defined. In this line e.parameter[header] you're returning the value for the multiple selected values (which is an array) to the newRow array, you should apply, for example, the join method to the multiple selected array to be returned as a string instead of an array.Andres Duarte
@AndresDuarte - I updated my question- 1) select element gets options when the form loads using a function; 2) I just forgot to include the form variable definition in the segment of code that I posted (it's added now). 3) I tried to use join and to iterate through options in the Google Apps Script section but it didn't work.Lucy Scholz
Could you please log and post the results of the headers and e.parameters variables in the line right before defining the newRow variable? Use e.parameters instead of e.parameter which only retrieves the first value for parameters with multiple values as stated in the documentationAndres Duarte

2 Answers

1
votes

If you want to just fetch the value of <select> then you can use the jquery function as follows:

$("#option_id").change(function(){
   //this will fetch the value of your select option.
   var select_value = $("#option_id option:selected").text();
}

You can use the jquery to post the data from your html to the google sheets. Here's a demo code for you:

function PostToGoogle(){
   var field1 = $("field_name").val();
   var field2 = $("field_name").val();

   //Validate if any field is empty
   if(field1 == ''){
       alert("Please fill your name");
       document.getElementById("nameField").focus();
    }

    .
    .


    $.ajax({
        url = "paste your google sheets url here",
        data: {"input_field_name": field1, "input_field_name": field2, .... },
        type: "POST",
        dataType: "xml",
        success: function(d){
           //show your success message
        },
        error: function(x,y,z){
            //show your error message
            $("form").hide();
       }
    });
}

you can use this function on a click event of form submission to enter the data inside the google sheets. Everytime a user fills the form it'll be saved inside the google sheet in a new row.

1
votes

I've solved it.

I added this function:

    function serializeSelects (select) {
        var array = [];
        select.each(function(){ array.push($(this).val()) });
        return array;
    }

And when the user clicks submit, I adjusted the code to call that function and then loop through all options and submit the form each time:

           //post submission
    $('#entry').submit(function(e){
        //turn multiple students selected into an array
        saved_names = $('#student').val();
        student_names = serializeSelects($(".student_names"));
        //rotate through array of students and submit form each time
        for (var i = 0; i < student_names[0].length; i++) {
            $('#student').val(student_names[0][i]);
            const form = document.forms["entry"];
            e.preventDefault(); fetch('https://script.google.com/macros....',
              {method: 'POST', mode: 'no-cors', body: new FormData(form)})
              .then(response => console.log('Success!', response))
              .catch(error => console.error('Error!', error.message))
            var btn = $(document.activeElement).attr('id');
        }