Отправка данных на разные вкладки с помощью редактора сценариев Google. - PullRequest
0 голосов
/ 17 февраля 2020

В моем редакторе сценариев электронных таблиц у меня есть следующие коды:

Code.gs

function doGet() {
    return HtmlService.createTemplateFromFile('checkForm.html')
}

function doPost1(e) {

  Logger.log(JSON.stringify(e))
  if (!e || !e.parameter) {
    return;
  }
  var lock = LockService.getScriptLock();
  lock.tryLock(10 * 1000);
  var scriptProp = PropertiesService.getScriptProperties();

  try {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var checkForm = ss.getSheetByName("checkForm");
    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]);

    var startTime = newRow[1];
    var endTime = newRow[2];
    var cal = CalendarApp.getCalendarById("ID");
    var allEvents = cal.getEvents(new Date(startTime), new Date(endTime));
    if (allEvents.length > 0) {
    return HtmlService.createTemplateFromFile('calendarAgenda.html')
    }else {
    return HtmlService.createTemplateFromFile('bookingForm.html')
    };

  }

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

  finally {
    lock.releaseLock()
  }
}

function doPost2(e) {

  Logger.log(JSON.stringify(e))
  if (!e || !e.parameter) {
    return;
  }
  var lock = LockService.getScriptLock();
  lock.tryLock(10 * 1000);
  var scriptProp = PropertiesService.getScriptProperties();

  try {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var bookForm = ss.getSheetByName("bookForm");
    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('Successfully received. Thank you!'))
      .setMimeType(ContentService.MimeType.JSON)
  }

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

  finally {
    lock.releaseLock()
  }
}

checkForm. html

<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" action="ScriptURL" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
  google.script.run.withSuccessHandler(postData).doPost1(e);
}
</script>
</body>
</html>

bookingForm. html

<!DOCTYPE html>
<body>
<form name="class1Booking" id="class1Booking" action="ScriptURL" target="_self" method="POST">
<inputs> ..
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
  google.script.run.withSuccessHandler(postData).doPost2(e);
}
</script>
</body>
</html>

Функция goGet возвращает страницу «checkForm. html», которая при отправке должна запускать функцию doPost1 для отправки данных на вкладку «checkForm» в электронной таблице, а затем возвращает вторая страница "bookingForm. html", которая при отправке должна запускать функцию doPost2 для отправки данных на вкладку "bookForm", а затем возвращает определенный текстовый вывод

Когда я отправляю форму проверки, я получаю ошибка «Функция сценария не найдена: doPost», и я думаю, что у меня могут быть некоторые проблемы с google.script.run, которые я попытался изменить несколько раз, но безуспешно. Любая помощь и спасибо заранее

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Вы не используете google.script.run функции правильно, как указано в документации , вы можете возвращать только значения типов:

Number, Boolean, String или null, а также JavaScript объекты и массивы, состоящие из примитивов, объектов и массивов.

В вашем случае вы пытаетесь вернуть textOutput Объект, который не разрешен, этот класс предназначен для Веб-приложений функций (doGet (e) или doPost (e)).

В документации о [Связь клиент-сервер] (https://developers.google.com/apps-script/guides/html/communication) объясняется, как работать с google.script.run. Вот пример, примененный к вашему делу, чтобы вы могли лучше понять, как он работает:

checkForm. html

<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button onclick="postData(this.parentNode)">Check</button>
</form>
<script>
//It’s run when form button is clicked 
function postData(form) {
   //Calls doSomething function in code.gs with form parameter
  google.script.run.withSuccessHandler(handlerFunction).doSomething(form);
}

//Handles the response from doSomething function
function handlerFunction(responseData) {
  //Logs ‘It worked!’ in developer console
  console.log(responseData);
}
</script>
</body>
</html>

code.gs

//Web App function
function doGet() {
    return HtmlService.createTemplateFromFile('checkForm.html')
}

//Apps script function to receive form object and return response
function doSomething(form) {
//Do something
  return ‘It worked!’;
}

Приложения Веб-приложения Script предназначены для одностраничного приложения (одна HTML страница), а не многостраничного приложения, хотя существуют различные примеры обходных путей, которые можно использовать для достижения многостраничное поведение:

[1] Ссылка на другую HTML страницу в скрипте Google Apps

[2] https://sites.google.com/corp/view/googlappsscript/recent-scripts/multiple-page-webapp-example

0 голосов
/ 17 февраля 2020

Забудьте о doPost (). Попробуйте что-то вроде этого.

HTML:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <style>#msg{display:none;}</style>
  </head>
  <body>
    <form>
      <!--><inputs type="text" name="name1">--> 
      <button type="button"  value="Submit" onclick="processForm(this.parentNode);" />
      </form>
 <div id="msg"></div>
 <script>
   $(function(){
     //You can get stuff from the server after the dom has loaded.  I know it takes some time but it's a simple way to intialize.  Personally for my own sutff Id rather do this that use templated html
   });

  function processFormC(form) {
    //input validation
    google.script.run
    .withSuccessHandler(function(obj){
      $('#msg').css("display","block");
      $('#msg').html(obj.msg);
    })
    .processFormS(form);
  }
</script>
  </body>
</html>

GS:

function processFormS(obj) {
  //obj.name1...
  return {msg:'Got it.'}
}

function doGet() {
    return HtmlService.createHtmlOutputFromFile('whatever file name')
}

И лично я предпочитаю ставить все javascript и css в том же файле, потому что это легче найти позже. Да, я знаю, что он может стать большим, но опять же, это мой выбор, он не должен быть вашим выбором.

...