Sunday, September 8, 2013

Sidebars in Google Docs

So as of May 22, from the I/O Google (you can watch it here) released an API (or maybe an SDK, I am not positive of the acronym but it is the documentation for the classes and methods) for Documents and some other great stuff.
I have been playing around with creating some scripts that are container bound (they can only be used in one product). One of these has been the sidebar creation in Documents.
You can see here I created a sidebar called "My Custom Comments". You can also create your own menu items and I created a menu called "My Custom Comments Menu" as well.

Here is the code I used to create the sidebar:
//create a sidebar with width 300 called My Custom Comments. The inside of the sidebar is populated //by index.html
function showSidebar() {
  var ui = DocumentApp.getUi();
  var html = HtmlService.createHtmlOutputFromFile('index').setTitle('My Custom Comments').setWidth(300);
  ui.showSidebar(html);
}

Now the important part of this script to run is I need to add the html file to the script. I go to File->New->Html file.

This is the really cool part!!! I can insert Html code into the sidebar content!!! Here is what I did with a quick snippet of code.
You can see that the 4th line of code tells the html to run the method addParagraphSign() in the script that I have in the Code.gs.
The html does limit some things, like iframe, embed, and some other things (unfortunately you still cannot embed Wolfram CDF files.
Here are the methods addParagraphSign and addParagraph:

//repeat this code for each custom comment you want to put just change the text in the quotes ' add a new paragraph here'
function addParagraph(){
  //From: https://developers.google.com/apps-script/reference/document/cursor
  // Insert some text at the cursor position and make it bold.
 var cursor = DocumentApp.getActiveDocument().getCursor();
 if (cursor) {
   // Attempt to insert text at the cursor position. If the insertion returns null, the cursor's
   // containing element doesn't allow insertions, so show the user an error message.
   var element = cursor.insertText(' add a new paragraph here ');
   // possibly try to use .insertInlineImage to add an image blob
 
   if (element) {
    element.setBold(true);
   } else {
     DocumentApp.getUi().alert('Cannot insert text here.');
   }
 } else {
   DocumentApp.getUi().alert('Cannot find a cursor.');
 }

}

function addParagraphSign(){
  //From: https://developers.google.com/apps-script/reference/document/cursor
  // Insert some text at the cursor position and make it bold.
 var cursor = DocumentApp.getActiveDocument().getCursor();
 if (cursor) {
   // Attempt to insert text at the cursor position. If the insertion returns null, the cursor's
   // containing element doesn't allow insertions, so show the user an error message.
   // possibly try to use .insertInlineImage to add an image blob
   var pilcrowUrl = "http://www.merriam-webster.com/top-ten-lists/top-10-words-you-didnt-know-vol-2/top10_unknown2_pilcrow_sm.gif";
   var pilcrowBlob = UrlFetchApp
                          .fetch(pilcrowUrl)
                          .getBlob()
                          .setName("pilcrowBlob");
 
   var element = cursor.insertInlineImage(pilcrowBlob);
   if (element) {
   
   } else {
     DocumentApp.getUi().alert('Cannot insert text here.');
   }
 } else {
   DocumentApp.getUi().alert('Cannot find a cursor.');
 }

This is pretty cool to now have a Custom Menu for items to insert into a document inline by clicking on the button. (Thanks to +Michael Wacker for the #autoAwesome tip in the #gafesummit talk, take multiple screenshots and then upload to G+ to create the animated gif!!!)