我希望通过点击Google表单插件侧边栏中的按钮来加载Google云端硬盘文件选择器。
问题
我无法直接从侧边栏找出如何加载选择器(在模态对话框中),然后将文档ID回调到侧边栏。
我已经能够成功加载模态对话框,然后从模态对话框加载选择器,但是我很难理解如何直接从侧边栏加载选择器。
感谢任何指导。我目前的代码如下所示。
.gs文件:
function onOpen(e) {
FormApp.getUi()
.createAddonMenu()
.addItem('Picker', 'showSidebar')
.addToUi();
}
function showSidebar(){
var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Title');
FormApp.getUi().showSidebar(ui);
}
function openPicker(){
var html = HtmlService.createHtmlOutputFromFile('Picker')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
FormApp.getUi().showModalDialog(html, 'Select a file');
}
function getOAuthToken() {
DriveApp.getRootFolder();
return ScriptApp.getOAuthToken();
}
侧边栏html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<base target="_top">
</head>
<body>
<button onclick='openPicker()'>Select a file</button>
</body>
</html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>
function openPicker() {
google.script.run
.withSuccessHandler(success)
.withFailureHandler(failure)
.openPicker();
}
function success() {
console.log('success');
}
function failure() {
console.log('failure');
}
</script>
选择器HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script>
var DEVELOPER_KEY = '';
var DIALOG_DIMENSIONS = {width: 600, height: 425};
var pickerApiLoaded = false;
function onApiLoad() {
gapi.load('picker', {'callback': function() {
pickerApiLoaded = true;
}});
}
function getOAuthToken() {
google.script.run
.withSuccessHandler(createPicker)
.withFailureHandler(showError)
.getOAuthToken();
}
function createPicker(token) {
console.log("here");
if (pickerApiLoaded && token) {
var picker = new google.picker.PickerBuilder()
// Instruct Picker to display only spreadsheets in Drive. For other
// views, see https://developers.google.com/picker/docs/#otherviews
.addView(google.picker.ViewId.DOCUMENTS)
// Hide the navigation panel so that Picker fills more of the dialog.
.enableFeature(google.picker.Feature.NAV_HIDDEN)
// Hide the title bar since an Apps Script dialog already has a title.
.hideTitleBar()
.setOAuthToken(token)
.setDeveloperKey(DEVELOPER_KEY)
.setCallback(pickerCallback)
.setOrigin(google.script.host.origin)
// Instruct Picker to fill the dialog, minus 2 pixels for the border.
.setSize(DIALOG_DIMENSIONS.width - 2,
DIALOG_DIMENSIONS.height - 2)
.build();
picker.setVisible(true);
} else {
showError('Unable to load the file picker.');
}
}
function pickerCallback(data) {
var action = data[google.picker.Response.ACTION];
if (action == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var id = doc[google.picker.Document.ID];
var url = doc[google.picker.Document.URL];
var title = doc[google.picker.Document.NAME];
document.getElementById('result').innerHTML =
'<b>You chose:</b><br>Name: <a href="' + url + '">' + title +
'</a><br>ID: ' + id;
} else if (action == google.picker.Action.CANCEL) {
document.getElementById('result').innerHTML = 'Picker canceled.';
}
}
function showError(message) {
document.getElementById('result').innerHTML = 'Error: ' + message;
}
</script>
</head>
<body>
<div>
<button onclick='getOAuthToken()'>Select a file</button>
<p id='result'></p>
</div>
<script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>
答案 0 :(得分:1)
只需修改您的选择器Html代码,以便在加载模式对话框上的html时自动运行getOAuthToken()
函数,如下所示:
... Code till here remains as above
<body onload = 'getOAuthToken()'>
<div>
<p id='result'></p>
</div>
<script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>
有关onload
活动的详情,请参阅here
希望有所帮助。
答案 1 :(得分:1)
这是我提出的快速而肮脏的解决方案。我的'。gs'文件包含用于显示通过 HtmlService 提供的UI容器并获取OAuth令牌的功能。请注意,您可以将数据模型传递给 HtmlTemplate 对象,然后再将其转换为原始HTML并传递给客户端。当我们从自定义菜单调用'showSidebar'函数时,不会传递任何参数,因此它是第一次调用。如果'params'不是'undefined',我们知道调用来自模态对话框。
<强> Code.gs 强>
var ui = SpreadsheetApp.getUi()
//add custom menu to the spreadsheet;
function onOpen() {
ui.createMenu('Sidebar')
.addItem('Show sidebar', 'showSidebar')
.addToUi();
}
function showSidebar(params){
var sidebar = HtmlService.createTemplateFromFile('sidebar');
var model = "your selection"; //default message to be displayed
if (params) { //if arguments are passed, it's a callback from modal dialog
model = "You selected document with id: " +
params.id + ", title: " + params.title +
" url: " + params.url;
}
sidebar.model = model; // pass model to the template
var htmlOutput = sidebar.evaluate(); //execute inline scriplets from the template to complete DOM construction.
ui.showSidebar(htmlOutput); //pass resulting UI object to sidebar container
}
function showModalDialog() {
// produce HtmlOutput for modal dialog
var modalDialog = HtmlService.createTemplateFromFile('modal_dialog')
.evaluate()
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
ui.showModalDialog(modalDialog, 'Picker');
}
function getOAuthToken() {
DriveApp.getRootFolder();
return ScriptApp.getOAuthToken();
}
<强> sidebar.html:强>
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input type="button" id="button" value="Open picker">
<div> Selection: <?!= model ?> </div>
<script>
window.onload = (function(){
var button = document.getElementById('button');
button.addEventListener('click', function(event){
google.script.run
.withSuccessHandler(function(){
google.script.host.close();
})
.showModalDialog();
});
})();
</script>
</body>
</html>
&lt ;?之间的小脚架当'evaluate()'在属于 HtmlTemplate 类的对象上调用时,将触发?&gt; 。有几种类型的scriptlet - 更多关于scriptlet的信息:
https://developers.google.com/apps-script/guides/html/templates#scriptlets
在第一个'?后立即添加'!'会强制打印结果到页面。加载DOM树后,我添加了在用户单击按钮时在'。gs'文件中执行'showDialog()'功能的事件监听器。
对话框窗口的模板来自此处的选择器快速入门
https://developers.google.com/apps-script/guides/dialogs
我修改了'onApiLoaded'功能,以便在加载时立即显示选择器。
function onApiLoad() {
gapi.load('picker', {'callback': function() {
pickerApiLoaded = true;
getOAuthToken();
}});
}
最后,我将以下代码添加到'pickerCallback'函数中。
if (action == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var id = doc[google.picker.Document.ID];
var url = doc[google.picker.Document.URL];
var title = doc[google.picker.Document.NAME];
google.script.run.withSuccessHandler(function(){
google.script.host.close();
}).showSidebar({id: id, url: url, title: title});
当用户进行选择时,数据将作为参数传递给'。gs'文件中的'showSideBar'函数。由于'google.script.host(run)'调用是异步的,我将窗口关闭调用放在'withSuccessHandler'中,以防止提前关闭。
结果:选择数据显示在侧栏中。
还有另一种我更喜欢的方法。在GAS中,即使是文件绑定脚本也可以作为Web应用程序发布,因此您可以通过UrlFetchApp.fetch()进行调用来创建多页面应用程序。例如,您可以定义一个包含单个“容器”div的母版页。您还可以存储所有JS代码并在母版页上加载API。如果您需要导航到另一个页面,您只需通过fetch(url)查询Web应用程序,并将生成的html粘贴到母版页上的容器中
containerDiv.innerHTML = html;
可以通过调用ScriptApp.getService()。getUrl()动态获取Web应用程序的URL。但是,必须首先将脚本发布为可匿名访问的Web应用程序。希望这会有所帮助。