Google Webapp:如何将数组值动态传递给jquery脚本 [英] Google Webapp: How to dynamically pass array values to jquery script
问题描述
我一直在寻找StackOverflow问题的答案 Datepicker:禁用数据中的日期.我已经成功开发了一个小型Web应用程序,它使用beforeShowDay
选项和一组硬编码日期从jQuery Datepicker中排除了特定日期.
问题
目前,排除日期的数组是硬编码的,但是这些日期应动态生成.尽管我在code.gs getuserdates()
中有一个函数,该函数将返回"userdates"数组["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
,但我在网络上找不到一个引用来解释如何将数组值动态传递给webapp.>
@Tanaike在根据Google表格中的值使用Google Apps脚本禁用日期选择器中的日期的答案似乎与此问题相关,但我无法适应任何包含数组的成功代码.我认为部分问题是Tanaike的答案是100%使用Javascript,而这种情况需要Javascript和jQuery.
我尝试了scriptlet(不希望它们起作用,但您永远不知道.它们都产生了错误Uncaught SyntaxError: Unexpected token '<'
-
var userdates = <? getuserdates(); ?>
-
var userdates = <?= getuserdates(); ?>
-
var userdates = <?!= getuserdates(); ?>
目标
要动态更新变量array
的值.
代码
以下代码可完美运行;唯一的问题是数组值是硬编码的.
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>
在Google Apps脚本端的getuserdates()
返回["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
的值时,var userdates = <?= getuserdates(); ?>
的userdates
是字符串类型的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] ?>);
<? } ?>
- 运行脚本时,
userdates
是["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();
- 运行脚本时,将从
getuserdates()
中检索到的userdates
用作["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:
关于发生Uncaught SyntaxError: Unexpected token '<'
错误的原因,此问题的原因是<?!= 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>
- 在这种情况下,请不要在
<?!= include('JavaScript'); ?>
的JavaScript
中添加<script>###</script>
. - 不幸的是,这些脚本似乎无法在脚本中使用.
关于问题2:
关于从getuserdates()
返回[""12/11/2019"", ""12/15/2019"", ""12/16/2019"", ""12/17/2019"", ""12/24/2019""]
的原因,此问题的原因是userdates.push('"' + datasheetData[i][5]+ '"');
.因此,请进行如下修改.
发件人:
userdates.push('"' + datasheetData[i][5]+ '"');
收件人:
userdates.push(datasheetData[i][5]);
使用模式1时,脚本如下.关于GAS端的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>
I've been working on an answer to StackOverflow question Datepicker: Disabling dates in the data. I've successfully developed a small webapp that excludes specific dates from a jQuery Datepicker using the beforeShowDay
option and an array of hardcoded dates.
Problem
At present, the array of excluded dates is hard coded, but these dates should be generated dynamically. Although I have a function in code.gs getuserdates()
which will return the "userdates" array ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
, I haven't found a single reference on the web to explain how to pass the array values dynamically to the webapp.
The answer by @Tanaike on Disable dates in the datepicker based on values from the Google Sheet using Google Apps Script seems relevant to this problem, but I've failed to adapt any successful code that includes the array. I think part of the problem here is that Tanaike's answer was 100% Javascript whereas this scenario requires both Javascript and jQuery.
I tried scriptlets (not expecting them to work, but you never know. They all generated an error Uncaught SyntaxError: Unexpected token '<'
var userdates = <? getuserdates(); ?>
var userdates = <?= getuserdates(); ?>
var userdates = <?!= getuserdates(); ?>
Goal
To update dynamically the values of the variable array
.
Code
The following code works flawlessly; the only problem is that the array values are hard coded.
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>
When getuserdates()
in Google Apps Script side returns the value of ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
, userdates
of var userdates = <?= getuserdates(); ?>
is 12/13/2019,12/14/2019,12/16/2019,12/17/2019,12/24/2019
of the string type. I thought that by this, your script doesn't work.
So, as one of several answers, how about this answer? Please modify JavaScript.html
.
Pattern 1:
In this pattern, the scriptlets are used. I thought that this thread might be useful.
From:
var userdates = ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"];
To:
var userdates = [];
<? var data = getuserdates(); ?>
<? for (var i = 0; i < data.length; i++) { ?>
userdates.push(<?= data[i] ?>);
<? } ?>
- When the script is run,
userdates
is["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
. - As one more pattern using the scriptlets, for example, if you want to use
var userdates = <?= getuserdates(); ?>
, you can also modifyvar userdates = <?= getuserdates(); ?>
tovar userdates = <?= getuserdates() ?>.split(",");
.
Pattern 2:
In this pattern, google.script.run is used.
From:
var userdates = ["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"];
To:
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();
- When the script is run,
userdates
retrieved fromgetuserdates()
is used as["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
.
Note:
- In this case, it supposes that
getuserdates()
returns["12/13/2019", "12/14/2019", "12/16/2019", "12/17/2019", "12/24/2019"]
.
References:
If I misunderstood your question and this was not the direction you want, I apologize.
Edit 1:
About issue 1:
About the reason that the error of Uncaught SyntaxError: Unexpected token '<'
occurs, the reason of this issue is <?!= include('JavaScript'); ?>
. So please modify as follows.
From:
</div>
<?!= include('JavaScript'); ?>
</body>
To:
</div>
<script>
var userdates = [];
<? var data = getuserdates(); ?>
<? for (var i = 0; i < data.length; i++) { ?>
userdates.push(<?= data[i] ?>);
<? } ?>
</script>
<?!= include('JavaScript'); ?>
</body>
- In this case, please don't add
<script>###</script>
toJavaScript
of<?!= include('JavaScript'); ?>
. - Unfortunately, it seems that the scriptlets cannot be used into the scriptlets.
About issue 2:
About the reason that [""12/11/2019"", ""12/15/2019"", ""12/16/2019"", ""12/17/2019"", ""12/24/2019""]
is returned from getuserdates()
, the reason of this issue is userdates.push('"' + datasheetData[i][5]+ '"');
. So please modify as follows.
From:
userdates.push('"' + datasheetData[i][5]+ '"');
To:
userdates.push(datasheetData[i][5]);
Edit 2:
When the pattern 1 is used, the script is as follows. About getuserdates()
of GAS side, please modify from userdates.push('"' + datasheetData[i][5]+ '"');
to userdates.push(datasheetData[i][5]);
. And please modify HTML & Javascript side as follows.
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>
这篇关于Google Webapp:如何将数组值动态传递给jquery脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!