Drive Picker - View Only Spreadsheets - Shows Forms also

503 views
Skip to first unread message

Alan Wells

unread,
Jun 14, 2019, 10:46:35 PM6/14/19
to Google Apps Script Community
Why does the picker show both Spreadsheets and Forms with using:

.addView(google.picker.ViewId.SPREADSHEETS)

It's supposed to only show spreadsheets.

Also, it shows files from multiple folders.  I want the picker to show folders and then the contents of just a specific folder.

Server Code:


/**
 * Displays an HTML-service dialog in Google Sheets that contains client-side
 * JavaScript code for the Google Picker API.
 */

function showPicker() {
 
var html = HtmlService.createHtmlOutputFromFile('H_Picker_Goog.html')
     
.setWidth(600)
     
.setHeight(425)
     
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
 
FormApp.getUi().showModalDialog(html, 'Select a file');
}

/**
 * Gets the user's OAuth 2.0 access token so that it can be passed to Picker.
 * This technique keeps Picker from needing to show its own authorization
 * dialog, but is only possible if the OAuth scope that Picker needs is
 * available in Apps Script. In this case, the function includes an unused call
 * to a DriveApp method to ensure that Apps Script requests access to all files
 * in the user's Drive.
 *
 * @return {string} The user's OAuth 2.0 access token.
 */

function getOAuthToken() {
 
return ScriptApp.getOAuthToken();
}

Client Side HTML file: H_Picker_Goog.html

<!DOCTYPE html>
<html>
<head>
 
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
 
<script>
   
// IMPORTANT: Replace the value for DEVELOPER_KEY with the API key obtained
   
// from the Google Developers Console.
   
var DEVELOPER_KEY = 'my key';
   
var DIALOG_DIMENSIONS = {width: 600, height: 425};
   
var pickerApiLoaded = false;

   
/**
     * Loads the Google Picker API.
     */

   
function onApiLoad() {
      gapi
.load('picker', {'callback': function() {
        pickerApiLoaded
= true;
     
}});
     
}

   
/**
     * Gets the user's OAuth 2.0 access token from the server-side script so that
     * it can be passed to Picker. This technique keeps Picker from needing to
     * show its own authorization dialog, but is only possible if the OAuth scope
     * that Picker needs is available in Apps Script. Otherwise, your Picker code
     * will need to declare its own OAuth scopes.
     */

   
function getOAuthToken() {
      google
.script.run.withSuccessHandler(createPicker)
         
.withFailureHandler(showError).getOAuthToken();
   
}

   
/**
     * Creates a Picker that can access the user's spreadsheets. This function
     * uses advanced options to hide the Picker's left navigation panel and
     * default title bar.
     *
     * @param {string} token An OAuth 2.0 access token that lets Picker access the
     *     file type specified in the addView call.
     */

   
function createPicker(token) {
     
//console.log('token: ' + token)
     
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.SPREADSHEETS)
           
// 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.');
     
}
   
}

   
/**
     * A callback function that extracts the chosen document's metadata from the
     * response object. For details on the response object, see
     * https://developers.google.com/picker/docs/result
     *
     * @param {object} data The response object.
     */

   
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.';
     
}
   
}

   
/**
     * Displays an error message within the #result element.
     *
     * @param {string} message The error message to display.
     */

   
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>

I'm using sample code from:

But make sure to comment out:DriveApp.getRootFolder()



Clark Lind

unread,
Jun 15, 2019, 7:14:13 AM6/15/19
to Google Apps Script Community
Not sure, but maybe it is showing those forms connected to those sheets? Is it showing ALL forms? That is where I would look for possible solution first.

Clark Lind

unread,
Jun 15, 2019, 7:37:10 AM6/15/19
to google-apps-sc...@googlegroups.com
Amit has a good example over at Digital Inspiration. He already implemented the line of thinking I was going for: filter by MIME type. You should be able to isolate the sheets from the forms using MIME type like in this example: https://ctrlq.org/code/20393-google-file-picker-example. (also consider sending a Bug report).

Faustino Rodriguez

unread,
Jun 15, 2019, 8:17:17 AM6/15/19
to Google Apps Script Community
I am also now testing the Picker with drive.file scope, using the same code example ...

To restrict the files I am using view.setMimeTypes("comma-separate-types") and also view.setQuery("like a seacrh inn drive")

BUT, I have a fundamental issue when trying to access the selected file with a simple call Drive.Files.get(id)
I just add a code line within the pickerCallback() PICKED action calling server-side as google.script.run.testingAccessToFile(id);

- Selecting a file with the Picker does NOT give the script access to that file, UNLESS the selected file was created by me with the same app
- If the file was created with the same app by other user, I get the error below
- If the file was created by me with another app, I also get the same error below

This is the error I got server-side:
Execution failed: API call to drive.files.get failed with error: File not found: 1HpZu5xE2...Hu8K

* Are you able to access a file in those scenarios, just by selecting it with the Picker?

I guess, I should be missing something trivial
What would that be?
Thanks, Fausto

On Friday, June 14, 2019 at 10:46:35 PM UTC-4, aj.addons wrote:

Alan Wells

unread,
Jun 15, 2019, 2:01:03 PM6/15/19
to Google Apps Script Community
I tried that code, but didn't get a different result.  His code is configured differently, but the end result was the same.

Alan Wells

unread,
Jun 15, 2019, 2:03:46 PM6/15/19
to Google Apps Script Community
I tried using the mime type:
"application/vnd.google-apps.spreadsheet"
but it either didn't work, or the result was the same

Fausto

unread,
Jun 15, 2019, 5:26:42 PM6/15/19
to google-apps-sc...@googlegroups.com
Just in case, I just tried as follow and only get G Sheets in the list, no Forms
Let me know how it goes on your side

var view = new google.picker.DocsView(google.picker.ViewId.SPREADSHEETS);
view
.setMode(google.picker.DocsViewMode.LIST).setMimeTypes("application/vnd.google-apps.spreadsheet");



... then in PickerBuilder()
.addView(view)



--

Alan Wells

unread,
Jun 15, 2019, 8:10:56 PM6/15/19
to Google Apps Script Community
That worked.  Thank you.  I wish I understood the configuration better, but at this point I may not worry about it.  What the settings are for is self-explanatory for the most part, that's not hard to understand, but at this point I'm just mindlessly using code that I don't understand, and I don't feel like spending lots of time on learning the API.  But if it works, I'll just hope for the best, and keep on moving forward.  There may be other problems with the "auth/drive.file" scope, like what files get recognized as being available under what conditions.
Reply all
Reply to author
Forward
0 new messages