使用 Google 表格中的数组在 html 中创建数据列表,该列表可提供给 Google Apps 脚本以自动完成文本输入
use an array from Google Sheets to create a data list in html that can be served to a Google Apps Script for Autocomplete a Text Input
几天来,我一直在努力为我的同事构建一个简单的界面来记录每一次客户互动。他们将输入以下内容:
- 客户姓名(自动完成功能,来自电子表格中一列中所有姓名的超集)
- 互动日期
- 互动总结
- 前景(热、暖、温、冷)
我的问题是让自动完成工作。
我已经看到@Tanaika 漂亮地布置了服务器端、HTML+JS 等线程,但我无法让它工作。附上我的文件。感谢您的宝贵时间!
HTML+JS
<!DOCTYPE html>
<html>
<head>
<style>
label {
display: inline-block;
width: 150px;
}
</style>
<base target="_top">
<script>
function submitForm() {
google.script.run.appendRowFromFormSubmit(document.getElementById("feedbackForm"));
document.getElementById("form").style.display = "none";
document.getElementById("thanks").style.display = "block";
}
</script>
</head>
<body>
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
<div>
<div id="form">
<h1>Record Interaction</h1>
<form id="feedbackForm">
<label for="name">Parent Name</label>
<input type="text" id="name" name="name" list="datalist"><br><br>
<label for="doi">Date of Interaction</label>
<input id="today" type="date" name="doi"><br><br>
<label for="feedback">Interaction Summary</label>
<textarea rows=4 cols=35 id="feedback" name="feedback">Enter Interaction Summary Here...
</textarea><br><br>
<div>
<label for="temperature">Likely Candidate?</label><br>
<input type="radio" id="Hot" name="temperature" value="Hot">
<label for="yes">Hot</label><br>
<input type="radio" id="Warm" name="temperature" value="Warm">
<label for="yes">Warm</label><br>
<input type="radio" id="Tepid" name="temperature" value="Tepid">
<label for="yes">Tepid</label><br>
<input type="radio" id="Cold" name="temperature" value="Cold">
<label for="no">Cold</label><br><br>
<input type="button" value="Submit Interaction" onclick="submitForm();">
</form>
</div>
</div>
<div id="thanks" style="display: none;">
<p>Thank you for speaking to our customers!</p>
</div>
</body>
</html>
CODE.GS
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Customer Engagement')
.addItem('Record Interaction', 'showDialog')
.addToUi();
}
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
function readData() {
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data")
return filArray;
}
function activateSheetById(sheetId) {
//Access all the sheets in the Google Sheets spreadsheet
var sheets = SpreadsheetApp.getActive().getSheets();
//Filter out sheets whose Ids do not match
var sheetsForId = sheets.filter(function(sheet) {
return sheet.getSheetId() === sheetId;
});
//If a sheet with the Id was found, activate it
if(sheetsForId.length > 0)
sheetsForId[0].activate();
}
function appendRowFromFormSubmit(form) {
var row = [form.name, form.doi, form.feedback, form.temperature];
console.info("Appending Row");
activateSheetById(2059810756);
SpreadsheetApp.getActiveSheet().appendRow(row);
}
function makeUL(array) {
// Create the list element:
var namelist = document.createElement('ul');
for (var i = 0; i < array.length; i++) {
// Create the list item:
var item = document.createElement('li');
// Set its contents:
item.appendChild(document.createTextNode(array[i]));
// Add it to the list:
list.appendChild(item);
}
// Finally, return the constructed list:
return namelist;
}
向电子邮件对话框提出建议的示例
html:
<div id="emaildialog">
Recipient Search:<br />
<input id="rec" type="text" oninput="getSuggestions();" placeholder="Enter Search String slowly. Yellow=accessing server" size="50" /><br />
Suggestions:<br />
<div id="sugdiv" style="width:100%;background-color:#ffffff;"></div>
Recipients:<br />
<textarea id="recipients" cols="50" rows="4" placeholder="Sent to first recipient. Remaining recipients are blind copied."></textarea><br />
Message:<br />
<textarea id="msg" cols="50" rows="4" placeholder="Enter message to send with the attachments." >This is a copy of our apps Final Report.</textarea><br>
<input type="button" id="send" value="Create PDF and Send Email" onClick="createAndSendReport();" />
</div>
Javascript(含JQuery):
function updateDiv(vA){
var s='';
for(var i=0;i<vA.length;i++){
s+='<input type="button" id="btn-' + i + '" onClick="selectRecipient1(\'btn-' + i + '\')" value="' + vA[i][0] + '" />';
}
$('#sugdiv').html(s);
}
function getSuggestions(){
var txt=$('#rec').val();
if(txt.length>0){
$('#rec').css('background','yellow');
google.script.run
.withSuccessHandler(function(vA){
$('#rec').css('background','white');
//updateSelectList(vA);
updateDiv(vA);
})
.getSuggestions(txt)
}else{
updateSelectList([]);
}
}
Google 应用程序脚本:
function getSuggestions(s){
if(s){
var vA=[];
var cA=getAllContacts();
for(var i=0;i<cA.length;i++){
if(cA[i].toString().toLowerCase().indexOf(s.toLowerCase())>-1){
vA.push([cA[i][0]]);
}
}
}
return vA;
}
这段代码已有 5 年历史了。在原来的申请中还是运行
修改点:
- 在您的 HTML 中使用了模板。在这种情况下,请使用
createTemplateFromFile
而不是 createHtmlOutputFromFile
。
<?!= ... ?>
的脚本是 Force-printing scriptlets
(like printing scriptlets except that they avoid contextual escaping.
)。 Ref
我认为这些是您遇到问题的原因。当这些点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
Google Apps 脚本端:
发件人:
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
收件人:
function showDialog() {
var html = HtmlService.createTemplateFromFile('index.html');
html.data = readData();
SpreadsheetApp.getUi().showModalDialog(html.evaluate().setWidth(400).setHeight(600), 'Please Enter Details');
}
- 这里用到了你
readData()
的函数
HTML和Javascript方:
发件人:
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/###/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
收件人:
<datalist id="datalist">
<? data.forEach(e => { ?>
<option value="<?= e ?>">
<? }); ?>
</datalist>
参考:
几天来,我一直在努力为我的同事构建一个简单的界面来记录每一次客户互动。他们将输入以下内容:
- 客户姓名(自动完成功能,来自电子表格中一列中所有姓名的超集)
- 互动日期
- 互动总结
- 前景(热、暖、温、冷)
我的问题是让自动完成工作。
我已经看到@Tanaika 漂亮地布置了服务器端、HTML+JS 等线程,但我无法让它工作。附上我的文件。感谢您的宝贵时间!
HTML+JS
<!DOCTYPE html>
<html>
<head>
<style>
label {
display: inline-block;
width: 150px;
}
</style>
<base target="_top">
<script>
function submitForm() {
google.script.run.appendRowFromFormSubmit(document.getElementById("feedbackForm"));
document.getElementById("form").style.display = "none";
document.getElementById("thanks").style.display = "block";
}
</script>
</head>
<body>
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
<div>
<div id="form">
<h1>Record Interaction</h1>
<form id="feedbackForm">
<label for="name">Parent Name</label>
<input type="text" id="name" name="name" list="datalist"><br><br>
<label for="doi">Date of Interaction</label>
<input id="today" type="date" name="doi"><br><br>
<label for="feedback">Interaction Summary</label>
<textarea rows=4 cols=35 id="feedback" name="feedback">Enter Interaction Summary Here...
</textarea><br><br>
<div>
<label for="temperature">Likely Candidate?</label><br>
<input type="radio" id="Hot" name="temperature" value="Hot">
<label for="yes">Hot</label><br>
<input type="radio" id="Warm" name="temperature" value="Warm">
<label for="yes">Warm</label><br>
<input type="radio" id="Tepid" name="temperature" value="Tepid">
<label for="yes">Tepid</label><br>
<input type="radio" id="Cold" name="temperature" value="Cold">
<label for="no">Cold</label><br><br>
<input type="button" value="Submit Interaction" onclick="submitForm();">
</form>
</div>
</div>
<div id="thanks" style="display: none;">
<p>Thank you for speaking to our customers!</p>
</div>
</body>
</html>
CODE.GS
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Customer Engagement')
.addItem('Record Interaction', 'showDialog')
.addToUi();
}
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
function readData() {
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data")
return filArray;
}
function activateSheetById(sheetId) {
//Access all the sheets in the Google Sheets spreadsheet
var sheets = SpreadsheetApp.getActive().getSheets();
//Filter out sheets whose Ids do not match
var sheetsForId = sheets.filter(function(sheet) {
return sheet.getSheetId() === sheetId;
});
//If a sheet with the Id was found, activate it
if(sheetsForId.length > 0)
sheetsForId[0].activate();
}
function appendRowFromFormSubmit(form) {
var row = [form.name, form.doi, form.feedback, form.temperature];
console.info("Appending Row");
activateSheetById(2059810756);
SpreadsheetApp.getActiveSheet().appendRow(row);
}
function makeUL(array) {
// Create the list element:
var namelist = document.createElement('ul');
for (var i = 0; i < array.length; i++) {
// Create the list item:
var item = document.createElement('li');
// Set its contents:
item.appendChild(document.createTextNode(array[i]));
// Add it to the list:
list.appendChild(item);
}
// Finally, return the constructed list:
return namelist;
}
向电子邮件对话框提出建议的示例
html:
<div id="emaildialog">
Recipient Search:<br />
<input id="rec" type="text" oninput="getSuggestions();" placeholder="Enter Search String slowly. Yellow=accessing server" size="50" /><br />
Suggestions:<br />
<div id="sugdiv" style="width:100%;background-color:#ffffff;"></div>
Recipients:<br />
<textarea id="recipients" cols="50" rows="4" placeholder="Sent to first recipient. Remaining recipients are blind copied."></textarea><br />
Message:<br />
<textarea id="msg" cols="50" rows="4" placeholder="Enter message to send with the attachments." >This is a copy of our apps Final Report.</textarea><br>
<input type="button" id="send" value="Create PDF and Send Email" onClick="createAndSendReport();" />
</div>
Javascript(含JQuery):
function updateDiv(vA){
var s='';
for(var i=0;i<vA.length;i++){
s+='<input type="button" id="btn-' + i + '" onClick="selectRecipient1(\'btn-' + i + '\')" value="' + vA[i][0] + '" />';
}
$('#sugdiv').html(s);
}
function getSuggestions(){
var txt=$('#rec').val();
if(txt.length>0){
$('#rec').css('background','yellow');
google.script.run
.withSuccessHandler(function(vA){
$('#rec').css('background','white');
//updateSelectList(vA);
updateDiv(vA);
})
.getSuggestions(txt)
}else{
updateSelectList([]);
}
}
Google 应用程序脚本:
function getSuggestions(s){
if(s){
var vA=[];
var cA=getAllContacts();
for(var i=0;i<cA.length;i++){
if(cA[i].toString().toLowerCase().indexOf(s.toLowerCase())>-1){
vA.push([cA[i][0]]);
}
}
}
return vA;
}
这段代码已有 5 年历史了。在原来的申请中还是运行
修改点:
- 在您的 HTML 中使用了模板。在这种情况下,请使用
createTemplateFromFile
而不是createHtmlOutputFromFile
。 <?!= ... ?>
的脚本是Force-printing scriptlets
(like printing scriptlets except that they avoid contextual escaping.
)。 Ref
我认为这些是您遇到问题的原因。当这些点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
Google Apps 脚本端:
发件人:
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
收件人:
function showDialog() {
var html = HtmlService.createTemplateFromFile('index.html');
html.data = readData();
SpreadsheetApp.getUi().showModalDialog(html.evaluate().setWidth(400).setHeight(600), 'Please Enter Details');
}
- 这里用到了你
readData()
的函数
HTML和Javascript方:
发件人:
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/###/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
收件人:
<datalist id="datalist">
<? data.forEach(e => { ?>
<option value="<?= e ?>">
<? }); ?>
</datalist>