Google Webapp: как динамически передавать значения массива в скрипт jquery - PullRequest
3 голосов
/ 12 ноября 2019

Я работаю над ответом на вопрос StackOverflow Datepicker: отключение дат в данных . Я успешно разработал небольшое веб-приложение, которое исключает определенные даты из jQuery Datepicker с использованием опции beforeShowDay и массива жестко закодированных дат.

Проблема

В настоящее времямассив исключенных дат жестко закодирован, но эти даты должны генерироваться динамически. Хотя у меня есть функция в code.gs getuserdates(), которая будет возвращать массив «userdates» ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"], я не нашел ни одной ссылки в Интернете, чтобы объяснить, как динамически передавать значения массива в веб-приложение.

Ответ @Tanaike на Отключение дат в средстве выбора даты на основе значений из Листа Google с использованием Google Apps Script , похоже, относится к этой проблеме, но мне не удалось адаптировать какой-либо успешный код, который включаетмассив. Я думаю, что отчасти проблема заключается в том, что ответ Танаике был на 100% Javascript, тогда как для этого сценария требуются как Javascript, так и jQuery.

Я пробовал скриптлеты (не ожидая, что они будут работать, но вы никогда не знаете. Все они сгенерировали ошибкуUncaught SyntaxError: Unexpected token '<'

  • var userdates = <? getuserdates(); ?>

  • var userdates = <?= getuserdates(); ?>

  • var userdates = <?!= getuserdates(); ?>

Цель Динамическое обновление значений переменной array.

Ссылка на электронную таблицу

Последний URL веб-приложения (обновленный)

Код

Следующий код работает безупречно; единственная проблема заключается в том, что значения массива жестко закодированы.

code.gs

function doGet(request) {
  return HtmlService.createTemplateFromFile('Page')
      .evaluate();
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}

function getuserdates() {
  var ss = SpreadsheetApp.getActiveSpreadsheet()
  var sheetname = "VL Request";
  var datasheet = ss.getSheetByName(sheetname);

  // assume user name
  //var userName = Session.getEffectiveUser().getUsername()
  var username = "user1";

  // set variables
  var datafirstrow = 2;
  var dataLR = datasheet.getLastRow();
  var dataLC = datasheet.getLastColumn();
  var datasheetRange = datasheet.getRange(datafirstrow,1, dataLR-datafirstrow+1, dataLC);
  //Logger.log(datasheetRange.getA1Notation());

  // sort the data by date
  datasheetRange.sort(6); // sort by Column F - VL date
  var datasheetData = datasheetRange.getDisplayValues();
  //Logger.log(datasheetData);

  //   get the user names as an array
  var datanames = datasheetData.map(function(e){return e[2];});//[[e],[e],[e]]=>[e,e,e]
  //Logger.log(datanames); // DEBUG
  //Logger.log(datanames.length) // DEBUG

  // create an array to hold any dates
  var userdates = [];

  //  loop through the user names; test for equivalence to "username", and save VF date to an array
  for (var i=0;i<datanames.length;i++){
    //Logger.log("dataname = "+datanames[i])
    if (datanames[i] === username){
      // Logger.log("DEBUG: i= "+i+", user name = "+datanames[i]+", VL date = "+datasheetData[i][5]);
      userdates.push('"' + datasheetData[i][5]+ '"');
    }
    else{
      // Logger.log("DEBUG: i= "+i+" - no match");
    }
  }
  // resort the data by Timestamp
   datasheetRange.sort(1); // sort by Column A

  if (userdates.length !=0){
  //Logger.log("There are "+userdates.length+" previous dates for this user.");//DEBUG
  }
  else{
  //Logger.log("There no previous dates for this user");//DEBUG
  }

  //Logger.log(userdates);
  return userdates;
}

Page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/themes/cupertino/jquery-ui.css">
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
  <div class="demo" >
    <h1>jQuery datepicker</h1>
     <p>click here : <input type="text" name="date" id="datepicker" /></p>
  </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>

JavaScript.html

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<script>
var userdates = ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"];

$(function() {
  $('#datepicker').datepicker({
    minDate: "+3W", 
    maxDate: "+12W",
    beforeShowDay: function (date) {
      $thisDate = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
      if ($.inArray($thisDate, userdates) == -1) {
        return [true, ""];
      } else {
        return [false, "", "Unavailable"];
      }
    }
  });
});
</script>

Ответы [ 2 ]

3 голосов
/ 12 ноября 2019

Когда getuserdates() на стороне скрипта Google Apps возвращает значение ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"], userdates из var userdates = <?= getuserdates(); ?> равно 12/13/2019,12/14/2019,12/16/2019,12/17/2019,12/24/2019 типа строки. Я думал, что из-за этого ваш скрипт не работает.

Итак, как один из нескольких ответов, как насчет этого ответа? Пожалуйста, измените JavaScript.html.

Шаблон 1:

В этом шаблоне используются скриптлеты. Я думал, что эта тема может быть полезна.

От:

var userdates = ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"];

Кому:

var userdates = [];
<? var data = getuserdates(); ?>
<? for (var i = 0; i < data.length; i++) { ?>
  userdates.push(<?= data[i] ?>);
<? } ?>
  • Когда сценарийrun, userdates is ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"].
  • В качестве еще одного шаблона с использованием скриптлетов, например, если вы хотите использовать var userdates = <?= getuserdates(); ?>, вы также можете изменить var userdates = <?= getuserdates(); ?> на var userdates = <?= getuserdates() ?>.split(",");.

Шаблон 2:

В этом шаблоне используется google.script.run.

От:

var userdates = ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"];

Кому:

google.script.run.withSuccessHandler(userdates => {
  $(function() {
    $('#datepicker').datepicker({
      minDate: "+3W", 
      maxDate: "+12W",
      beforeShowDay: function (date) {
        $thisDate = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
        if ($.inArray($thisDate, userdates) == -1) {
          return [true, ""];
        } else {
          return [false, "", "Unavailable"];
        }
      }
    });
  });
}).getuserdates();
  • При запуске сценария userdates, полученный из getuserdates(), используется как ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"].

Примечание:

  • В этом случае предполагается, что getuserdates() возвращает ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"].

Ссылки:

Если я неправильно понял ваш вопрос и это не то направление, в котором вы хотите, я приношу свои извинения.

Редактировать 1:

О проблеме 1:

О причине возникновения ошибки Uncaught SyntaxError: Unexpected token '<', причина этой проблемы iс <?!= include('JavaScript'); ?>. Поэтому, пожалуйста, измените следующим образом.

С:

</div>
  <?!= include('JavaScript'); ?>
</body>

Кому:

</div>
<script>
var userdates = [];
<? var data = getuserdates(); ?>
<? for (var i = 0; i < data.length; i++) { ?>
  userdates.push(<?= data[i] ?>);
<? } ?>
</script>
  <?!= include('JavaScript'); ?>
</body>
  • В этом случае, пожалуйста, не добавляйте <script>###</script> кJavaScript из <?!= include('JavaScript'); ?>.
  • К сожалению, кажется, что скриптлеты нельзя использовать в скриплетах.

О проблеме 2:

О причинечто [""12/11/2019"", ""12/15/2019"", ""12/16/2019"", ""12/17/2019"", ""12/24/2019""] возвращается из getuserdates(), причина этой проблемы userdates.push('"' + datasheetData[i][5]+ '"');. Поэтому, пожалуйста, измените следующим образом.

С:

userdates.push('"' + datasheetData[i][5]+ '"');

С:

userdates.push(datasheetData[i][5]);

Редактировать 2:

Когда используется шаблон 1,Сценарий заключается в следующем. О getuserdates() стороны ГАЗА, пожалуйста, измените с userdates.push('"' + datasheetData[i][5]+ '"'); на userdates.push(datasheetData[i][5]);. И, пожалуйста, измените сторону HTML и Javascript следующим образом.

HTML & Javascript: Page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/themes/cupertino/jquery-ui.css">
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
  <div class="demo" >
    <h1>jQuery datepicker</h1>
     <p>click here : <input type="text" name="date" id="datepicker" /></p>
  </div>
    <script>
    var userdates = [];
    <? var data = getuserdates(); ?>
    <? for (var i = 0; i < data.length; i++) { ?>
      userdates.push(<?= data[i] ?>);
    <? } ?>
    </script>
    <?!= include('JavaScript'); ?>
  </body>
</html>

HTML & Javascript: JavaScript.html

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<script>
$(function() {
  $('#datepicker').datepicker({
    minDate: "+3W", 
    maxDate: "+12W",
    beforeShowDay: function (date) {
      $thisDate = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
      if ($.inArray($thisDate, userdates) == -1) {
        return [true, ""];
      } else {
        return [false, "", "Unavailable"];
      }
    }
  });
});
</script>
1 голос
/ 12 ноября 2019

Вы можете получить значения из среды выполнения скрипта Apps с помощью кода на стороне клиента.

Для этого вам нужно обработать ответ от функции, которую вы вызываете, с помощью функции withSuccessHandler .

Изменение вашей функции для создания DatePicker с датой, возвращаемой из бэкэнда, будет выглядеть так:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<script>
function onSuccess(value) {
  var userdates = value;
  $('#datepicker').datepicker({
    minDate: "+3W", 
    maxDate: "+12W",
    beforeShowDay: function (date) {
      $thisDate = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
      if ($.inArray($thisDate, userdates) == -1) {
        return [true, ""];
      } else {
        return [false, "", "Unavailable"];
      }
    }
  });
}

google.script.run.withSuccessHandler(onSuccess).getuserdates();
</script>
...