简体   繁体   中英

Retrieve and update values in Google spreadsheet by row ID by using HTML form

I was able to create a google spreadsheet (with ideas found on here) with these columns: product | size | uid where uid is random five number generated ID (=RANDBETWEEN(10000;99999)). I then used the following apps script:

// original from: http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/
// original gist: https://gist.github.com/willpatera/ee41ae374d3c9839c2d6 

function doGet(e){
  return handleResponse(e);
}

//  Enter sheet name where data is to be written below
        var SHEET_NAME = "Sheet1";

var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service

function handleResponse(e) {
  // shortly after my original solution Google announced the LockService[1]
  // this prevents concurrent access overwritting data
  // [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
  // we want a public lock, one that locks for all invocations
  var lock = LockService.getPublicLock();
  lock.waitLock(30000);  // wait 30 seconds before conceding defeat.
  
  try {
    // next set where we write the data - you could write to multiple/alternate destinations
    var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet = doc.getSheetByName(SHEET_NAME);
    
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    var headRow = e.parameter.header_row || 1;
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row = []; 
    // loop through the header columns
    for (i in headers){
      if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
        row.push(new Date());
      } else { // else use header name to get data
        row.push(e.parameter[headers[i]]);
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
    // return json success results
    return ContentService
          .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(e){
    // if error return this
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  } finally { //release lock
    lock.releaseLock();
  }
}

function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

Then, I put together this php file:

<?php
if (isset($_GET['product'])) $product = $_GET['product'];
if (isset($_GET['size'])) $size = $_GET['size'];
if (isset($_GET['uid'])) $uid = $_GET['uid'];
?>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Submit rows</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

</head>

<body>

Submit new row to google sheet.
<form id="test-form">
  
  <div>
    <label>product</label>
    <input type="text" name="product" value="<?php echo $product; ?>"/>
  </div>

  <div>
    <label>size</label>
    <input type="text" name="size" value="<?php echo $size; ?>"/>
  </div>
  
  <div>
    <label>UID</label>
    <input type="text" name="uid" value="<?php echo $uid; ?>"/>
  </div>

  <div>
    <button type="submit" id="submit-form">Submit form</button>
  </div>
  <div class="thanks"></div>

</form>


  <script>
        $(document).ready(function(){
          $.fn.serializeObject = function()
              {
               var o = {};
               var a = this.serializeArray();
               $.each(a, function() {
                   if (o[this.name]) {
                       if (!o[this.name].push) {
                           o[this.name] = [o[this.name]];
                       }
                       o[this.name].push(this.value || '');
                   } else {
                       o[this.name] = this.value || '';
                   }
               });
               return o;
              };
            var form = $('form#test-form'),
              url = 'https://script.google.com/macros/s/KEY/exec';
              form.submit(function(e){
                e.preventDefault();
              var jqxhr = $.ajax({
                url: url,
                method: "GET",
                dataType: "json",
                data: form.serializeObject()
              });
                $(".thanks").html("Sent to sheet.").css("font-size","2rem");
                $(".form-control").remove();
                $("#submit").remove();
              });
            });
        </script>


</body>
</html>

Why like this? I have a QR code and when it is scanned, user is directed to url like this: htttps://samplesite.com/index.php?product=Pants&size=large&uid=12345

So form fields are prepopulated by values from the qr code/link. Form is submitted, values are written into the google spreadsheet, all is fine.

But now to the question part: ,) There is another qr code on the product and when scanned: it opens url like this: htttps.//samplesite.com/edit?php?uid=12345

I would like this to open another page with form that lists the row values of the same google spreadsheet where uid is 12345. With php, it could be something like select * from sheet_id where uid='12345' and then defining the column values, but obviously it is not that easy.

I did some searching and tabletop.js has been suggested, but they ( https://github.com/jsoma/tabletop ) don't recommend it anymore.

  1. How can I retrieve information from a google spreadsheet by unique row id and insert it as values in html form? I plan to fill in the form with this data and then use drop downs to allow user to change the (size) value. Which leads us to the second part...
  2. How can I update the google spreadsheet by specific row id? I want this form to overwrite the values in same row with id 12345.
  3. And since we're here already: is excel's randbetween function good enough for this use? Or would you recommend a bigger number/letters? The outdated backend system unfortunately does not allow us to progress uid numbers by one, like in a regular database.

Thank you.

One way to do this would be to implement the HTML form directly in the doGet() and use google.script.run.withSuccessHandler(yourClientFunction).yourServerFunction(someParam) to push and pull data between the HTML form and the spreadsheet. This would handle authentication automatically. See the Web App demo .

Alternatively, use the Sheets API in your client code. You would not need a doGet() but would need to handle authentication.

You should not use randbetween() to create IDs, since there will eventually be collisions. If you allocate just five digits for the ID and never check for duplicates, the birthday problem virtually guarantees that there will be collisions after the first few hundred IDs. You should use an incrementing counter. If that is not possible, use Utilities.getUuid() or similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM