Doc List Viewer



 Document list Utility - Google Apps script



This document will show how to build a simple user interface (UI) to browse into your Google Document list with the ability to open documents or to send to yourself pdf copies of them.
It makes use of powerful Google Apps Script capabilities and shows the responsiveness of the user interface.
This example is primarily designed to run from a Spreadsheet but you’ll see that it can be easily adapted to function as a standalone web application (see ** in the script at beginning & end of the doclistUI function).


The first thing we do in this Spreadsheet version is to create a single item menu to start the script without needing to open the script editor.

Create a custom menu :

// personal doclist EN
//
var email = String(Session.getUser().getUserLoginId());
//
function onOpen() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var menuEntries = [ {name: "Doclist UI", functionName: "doclistUI"},
                   ];
 ss.addMenu("Utilities", menuEntries);
}

the variable ‘email’ is defined outside the function so that it becomes available to every function in the script. In a way it might be considered as a ‘global variable’.



Building the User Interface :

Before calling UiApp.createApplication() we call the Doclist method to populate the folder list from which we will begin to navigate.
Then we determine the main window size and color and draw all the labels, buttons and lists that we are going to use.   The style attributes that we use to define margins and other display parameters are ‘browser dependant’, meaning that the resulting display might be different in Chrome, Firefox or any other browser you use;  all other methods are executed on server side and are therefore fully guaranteed to work the expected way.  
Note that some of the labels and buttons are made invisible in this function as they will be useable later in execution.

function doclistUI(){   //** or replace by function doGet(e){//for web app published as service. See also end of function**
 var folderlist = new Array();
 var folders=DocsList.getFolders()
   for(ff=0;ff<folders.length;++ff){
     folderlist.push(folders[ff].getName());
     }
 var app = UiApp.createApplication().setHeight(260).setWidth(700).setStyleAttribute('background', 'beige')
 .setStyleAttribute('margin-top', '10px').setStyleAttribute('margin-left', '10px').setTitle("Doclist UI");
 var panel = app.createVerticalPanel()
 var hpanel = app.createHorizontalPanel();
 var Flist= app.createListBox(false).setName("Flb").setId("Flb").setVisibleItemCount(4).setWidth("180");
 var Dlist= app.createListBox(false).setName("Dlb").setId("Dlb").setVisibleItemCount(8).setWidth("280");
 var hidden = app.createHidden('hidden').setId('hidden');
 var hiddenlink = app.createHidden('hiddenlink').setId('hiddenlink');
 var Flab=app.createLabel('Folder List').setWidth("80");
 var Dlab=app.createLabel('Document List').setWidth("100");
 var spacer=app.createLabel(' ').setWidth("30");
//  
 Flist.addItem('Choose a folder').addItem('Root content');
   for(ff=0;ff<folderlist.length;++ff){
     Flist.addItem(folderlist[ff]);
     }
 hpanel.add(Flab).add(Flist).add(spacer).add(Dlab).add(Dlist).add(hidden).add(hiddenlink);
 var docname = app.createLabel().setId('doc').setSize("360", "35");
 var link = app.createAnchor('open ', 'href').setId("link").setVisible(false);
 var send = app.createButton("Send by mail as pdf (docs & spreadsheets) to "+email).setId("send").setVisible(false);
 var sent = app.createButton("Mail sent to "+email).setId("sent").setVisible(false);
 panel.add(hpanel).add(docname).add(link).add(send).add(sent);
//
 var clihandler = app.createClientHandler()
    .forTargets(sent).setVisible(true)
    .forEventSource().setVisible(false);
  send.addClickHandler(clihandler);
//
 var FHandler = app.createServerHandler("click");
 Flist.addChangeHandler(FHandler)
 FHandler.addCallbackElement(hpanel);
//
 var DHandler = app.createServerHandler("showlab");
 Dlist.addChangeHandler(DHandler);
 DHandler.addCallbackElement(hpanel);
//
 var keyHandler = app.createServerHandler("sendmail");
 send.addClickHandler(keyHandler)
 keyHandler.addCallbackElement(hpanel);
//
 app.add(panel);  
 var doc = SpreadsheetApp.getActive();//**
 doc.show(app);//**
 }
/* ** if you want to publish the script as a service, rename this function as do Get(e) ,  remove both lines marked with ** and replace them by the following :
return app;
*/


Using handlers to make the script live :

What would be a UI if we couldn’t interact with it ?
Server handlers are an easy way to assign functions to buttons or to any other UI element, they communicate with the server and trigger some functions.  For some special cases it can be more efficient and fast to use Client side handlers if the actions we need to trigger are simple.
In this example we use a client handler to show / hide a text , the content of this text being defined in a server function somewhere else. It makes the process instantaneous and gives the user a nice feeling of responsiveness.
The first function call in the serie is called ‘click’ as it is used to populate the second list in the UI with folders contents.  This function shows the use of so called ‘callbackElements’, i.e. data sent by the UI to the function as an event parameter (in short e.parameter).
Every e.parameter can be addressed by its origin name : in this first occurrence e.parameter.Flb refers to the value returned by the folder list selection that was populated in the UI construction itself.  From that point we can show the folder’s content (the actual document list) and this second list will become our handler source for the coming events.

function click(e){
  var app = UiApp.getActiveApplication();
  var Dlist = app.getElementById("Dlb");  
  var hidden = app.getElementById("hidden");  
  var doclist=new Array();
  var label = app.getElementById('doc')
  var folderName = e.parameter.Flb
      if (folderName=='Choose a folder'){Dlist.clear();label.setText(" ");return app}
      if (folderName!='Root content'){
  doclist=DocsList.getFolder(folderName).getFiles(0,2000)
  var names = new Array();
     for (nn=0;nn<doclist.length;++nn){
       names.push([doclist[nn].getName(),doclist[nn].getId(),doclist[nn].getType()]);
       }
     }else{
        doclist=DocsList.getRootFolder().getFiles(0,2000)
        var names = new Array();
           for (nn=0;nn<doclist.length;++nn){
           names.push([doclist[nn].getName(),doclist[nn].getId(),doclist[nn].getType()]);
           }
}
 names.sort();
 Dlist.clear();
   for(dd=0;dd<names.length;++dd){
     Dlist.addItem(names[dd][0]+" (doc Nr:"+dd+")");
     }
 hidden.setValue(names.toString());
return app   ;// update UI
}


Showing and using data :


Once we have chosen a document in our list we can decide what to do with it.  Depending of its type we could open it or send it by email as a pdf attachment.
Since every necessary handlers where already defined in our main UI definition function we only have to recall the buttons and labels and make them visible to use them.
We’ve also make use of special items called ‘hidden’ to store data usable by each function. Since it stores only strings, every necessary data item is converted to string when writing and eventually converted back to an array when reading using toString() and split() respectively.

function showlab(e){
 var app = UiApp.getActiveApplication();
 var label = app.getElementById('doc');
 var link = app.getElementById('link');
 var send = app.getElementById("send");
 var sent = app.getElementById("sent");
 var hidden = e.parameter.hidden.split(',');
 var hiddenlink = app.getElementById("hiddenlink");
//Logger.log(hidden)
 if (e.parameter.Dlb!=""){
   var docname = e.parameter.Dlb
   var docN = docname.substr(0,docname.lastIndexOf("("));
   var docindex = docname.substring(Number(docname.lastIndexOf(":"))+1,Number(docname.lastIndexOf(")")));
   var doctype = hidden[docindex*3+2]
//Logger.log(doctype)
   label.setText(doctype+" : "+docN).setEnabled(false).setStyleAttribute('fontSize', '15');
if (doctype=='document'){var urlstring = "https://docs.google.com/document/d/";var poststring = "/edit"} if (doctype=='spreadsheet'){var urlstring = "https://docs.google.com/spreadsheet/ccc?key=";var poststring = "#gid=0"} if (doctype=='item'||doctype=='other'||doctype=='blob_item'||doctype=='photo'){var urlstring = "https://docs.google.com/file/d/";var poststring = "/edit"} //
   var doclink = urlstring+hidden[docindex*3+1]+poststring;
//Logger.log(doclink)
   link.setVisible(true).setText("Open "+doctype+" in browser").setHref(doclink);
   sent.setText("Mail sent to "+email).setVisible(false);
   if(doctype=='document'||doctype=='spreadsheet'){send.setVisible(true)}else{send.setVisible(false)};
   hiddenlink.setValue(hidden[docindex*3+1]+"|"+doctype);
   }
return app   ;// update UI
}


Converting and sending documents :

This last function converts spreadsheets and text documents to pdf and sends it by mail to the user’s adress (collected in the very beginning of the script : Session.getUser().getUserLoginId() )
If this option isn’t available the concerned buttons are simply hidden so no further precaution should be taken to trap errors.

function sendmail(e){
  var app = UiApp.getActiveApplication();
  var sent = app.getElementById("sent");
  var hiddenlink =  e.parameter.hiddenlink;  
  var ID = hiddenlink.substring(0,Number(hiddenlink.lastIndexOf("|")));
  var doctype = hiddenlink.substr(Number(hiddenlink.lastIndexOf("|"))+1);
  var docname = e.parameter.Dlb
  var docN = docname.substr(0,docname.lastIndexOf("("));
//Logger.log(docN+"   "+doctype)   
  var pdf = DocsList.getFileById(ID).getAs('application/pdf').getBytes();
  var attach = {fileName: docN+".pdf",content:pdf, mimeType:'application/pdf'};
  MailApp.sendEmail(email, 'Your '+doctype+' as PDF ('+docN+')', 'see attachment', {attachments:[attach]});
return app   ;// update UI
}


Conclusion :

This example has shown how easy it can be to get a working application using Google Apps Script. You probably noticed a lot of Logger.log commands that are commented by a //, these can be used if you feel like examining data through the script execution. The logger is indeed a precious tool during app development and debugging but it’s probably a good practice to neutralise them when everything if working fine.

Complete code in one piece :

This is shown in very small typeface to take the less possible space. Just copy and paste in the script editor (the size will be normalized by the script editor).

// personal doclist EN
//
var email = String(Session.getUser().getUserLoginId());
//
function onOpen() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var menuEntries = [ {name: "Doclist UI", functionName: "doclistUI"},
                   ];
 ss.addMenu("Utilities", menuEntries);//
}
//
function doclistUI(){ // or function doGet(){  //** see text
 var folderlist = new Array();
 var folders=DocsList.getFolders()
   for(ff=0;ff<folders.length;++ff){
     folderlist.push(folders[ff].getName());
     }
 var app = UiApp.createApplication().setHeight(260).setWidth(700).setStyleAttribute('background', 'beige')
 .setStyleAttribute('margin-top', '10px').setStyleAttribute('margin-left', '10px').setTitle("Doclist UI");
 var panel = app.createVerticalPanel()
 var hpanel = app.createHorizontalPanel();
 var Flist= app.createListBox(false).setName("Flb").setId("Flb").setVisibleItemCount(4).setWidth("180");
 var Dlist= app.createListBox(false).setName("Dlb").setId("Dlb").setVisibleItemCount(8).setWidth("280");
 var hidden = app.createHidden('hidden').setId('hidden');
 var hiddenlink = app.createHidden('hiddenlink').setId('hiddenlink');
 var Flab=app.createLabel('Folder List').setWidth("80");
 var Dlab=app.createLabel('Document List').setWidth("100");
 var spacer=app.createLabel(' ').setWidth("30");
//  
 Flist.addItem('Choose a folder').addItem('Root content');
   for(ff=0;ff<folderlist.length;++ff){
     Flist.addItem(folderlist[ff]);
     }
 hpanel.add(Flab).add(Flist).add(spacer).add(Dlab).add(Dlist).add(hidden).add(hiddenlink);
 var docname = app.createLabel().setId('doc').setSize("360", "35");
 var link = app.createAnchor('open ', 'href').setId("link").setVisible(false);
 var send = app.createButton("Send by mail as pdf (docs & spreadsheets) to "+email).setId("send").setVisible(false);
 var sent = app.createButton("Mail sent to "+email).setId("sent").setVisible(false);
 panel.add(hpanel).add(docname).add(link).add(send).add(sent);
//
 var clihandler = app.createClientHandler()
    .forTargets(sent).setVisible(true)
    .forEventSource().setVisible(false);
  send.addClickHandler(clihandler);
//
 var FHandler = app.createServerHandler("click");
 Flist.addChangeHandler(FHandler)
 FHandler.addCallbackElement(hpanel);
//
 var DHandler = app.createServerHandler("showlab");
 Dlist.addChangeHandler(DHandler);
 DHandler.addCallbackElement(hpanel);
//
 var keyHandler = app.createServerHandler("sendmail");
 send.addClickHandler(keyHandler)
 keyHandler.addCallbackElement(hpanel);
//
 app.add(panel);  
 var doc = SpreadsheetApp.getActive();//**
 doc.show(app);//**
 }
/* ** if you want to publish the script as a service, rename this function as doget(e) ,  remove both lines marked with ** and replace them by the following :
return app;
*/
}
//
function click(e){
  var app = UiApp.getActiveApplication();
  var Dlist = app.getElementById("Dlb");  
  var hidden = app.getElementById("hidden");  
  var doclist=new Array();
  var label = app.getElementById('doc')
  var folderName = e.parameter.Flb
      if (folderName=='Choose a folder'){Dlist.clear();label.setText(" ");return app}
      if (folderName!='Root content'){
  doclist=DocsList.getFolder(folderName).getFiles(0,2000)
  var names = new Array();
     for (nn=0;nn<doclist.length;++nn){
       names.push([doclist[nn].getName(),doclist[nn].getId(),doclist[nn].getType()]);
       }
     }else{
        doclist=DocsList.getRootFolder().getFiles(0,2000)
        var names = new Array();
           for (nn=0;nn<doclist.length;++nn){
           names.push([doclist[nn].getName(),doclist[nn].getId(),doclist[nn].getType()]);
           }
}
 names.sort();
 Dlist.clear();
   for(dd=0;dd<names.length;++dd){
     Dlist.addItem(names[dd][0]+" (doc Nr:"+dd+")");
     }
 hidden.setValue(names.toString());
return app   ;// update UI
}
//
function showlab(e){
 var app = UiApp.getActiveApplication();
 var label = app.getElementById('doc');
 var link = app.getElementById('link');
 var send = app.getElementById("send");
 var sent = app.getElementById("sent");
 var hidden = e.parameter.hidden.split(',');
 var hiddenlink = app.getElementById("hiddenlink");
//Logger.log(hidden)
 if (e.parameter.Dlb!=""){
   var docname = e.parameter.Dlb
   var docN = docname.substr(0,docname.lastIndexOf("("));
   var docindex = docname.substring(Number(docname.lastIndexOf(":"))+1,Number(docname.lastIndexOf(")")));
   var doctype = hidden[docindex*3+2]
//Logger.log(doctype)
   label.setText(doctype+" : "+docN).setEnabled(false).setStyleAttribute('fontSize', '15');
if (doctype=='document'){var urlstring = "https://docs.google.com/document/d/";var poststring = "/edit"} if (doctype=='spreadsheet'){var urlstring = "https://docs.google.com/spreadsheet/ccc?key=";var poststring = "#gid=0"} if (doctype=='item'||doctype=='other'||doctype=='blob_item'||doctype=='photo'){var urlstring = "https://docs.google.com/file/d/";var poststring = "/edit"} //
   var doclink = urlstring+hidden[docindex*3+1]+poststring;
//Logger.log(doclink)
   link.setVisible(true).setText("Open "+doctype+" in browser").setHref(doclink);
   sent.setText("Mail sent to "+email).setVisible(false);
   if(doctype=='document'||doctype=='spreadsheet'){send.setVisible(true)}else{send.setVisible(false)};
   hiddenlink.setValue(hidden[docindex*3+1]+"|"+doctype);
   }
return app   ;// update UI
}
//
function sendmail(e){
  var app = UiApp.getActiveApplication();
  var sent = app.getElementById("sent");
  var hiddenlink =  e.parameter.hiddenlink;  
  var ID = hiddenlink.substring(0,Number(hiddenlink.lastIndexOf("|")));
  var doctype = hiddenlink.substr(Number(hiddenlink.lastIndexOf("|"))+1);
  var docname = e.parameter.Dlb
  var docN = docname.substr(0,docname.lastIndexOf("("));
//Logger.log(docN+"   "+doctype)   
  var pdf = DocsList.getFileById(ID).getAs('application/pdf').getBytes();
  var attach = {fileName: docN+".pdf",content:pdf, mimeType:'application/pdf'};
  MailApp.sendEmail(email, 'Your '+doctype+' as PDF ('+docN+')', 'see attachment', {attachments:[attach]});
return app   ;// update UI
}
//eof


Test it online from here


ċ
doclistUI.rtf
(6k)
Serge Gabet,
Jul 10, 2012, 4:27 PM
Comments