How to use google.script.run to call a server side function on drop down change? (Google Docs)

48 Views Asked by At

I am working on a way auto-populate my google docs using google apps scripting. I want to populate a dropdown in a sidebar with a column from my google sheet, then fetch this on the server side when it changes.

function onOpen() {
  DocumentApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .createMenu('FCAR')
      .addItem('Select Class', 'showSidebar')
      .addToUi();
}

function showSidebar() {
  var sheet = SpreadsheetApp.openById("XXXXXXXXXXXXX").getSheetByName("Sheet1");
  var data = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastColumn());
  console.log(sheet.getLastColumn());
  var classes = [];
  for(var i = 0; i < sheet.getLastColumn()-1; i++) {
    classes.push(data[i][0]);
  }
  console.log(classes);

  var html = HtmlService.createHtmlOutput();
  html.append(generateHtml(classes));
  console.log(html.getContent())
  DocumentApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .showSidebar(html);
}

// Function to generate HTML string for the dropdown
function generateHtml(options) {
    var dropdownHTML = '<base target="_top">';
    dropdownHTML += '<select id="myDropdown" onchange="dropdownChanged(this)">';
    options.forEach(function(option) {
        dropdownHTML += '<option value="' + option + '">' + option + '</option>';
    });
    dropdownHTML += '</select>';

    // Add client-side JavaScript function
    dropdownHTML += '<script>';
    dropdownHTML += 'function dropdownChanged(dropdown) {';
    dropdownHTML += 'var selectedValue = dropdown.value;';
    dropdownHTML += 'alert("Selected value: " + selectedValue);';
    dropdownHTML += 'google.script.run.doSomething(selectedValue);'; // Call server-side function
    dropdownHTML += '}';
    dropdownHTML += '</script>';

    return dropdownHTML;
}


// Function to handle dropdown change event
function doSomething(value) {
      // Get the active Google Document
  var doc = DocumentApp.getActiveDocument();
  
  // Get the header of the document
  var header = doc.getHeader();
  
  // Set the text of the header to the selected value
  header.appendParagraph(value);
}

The drop down is populated successfully, and when I change it, I get the alert of the new value, but doSomething does not execute or give any error.

Any help is appreciated, Thanks!

1

There are 1 best solutions below

24
Tanaike On

About The drop down is populated successfully, and when I change it, I get the alert of the new value, but doSomething does not execute or give any error., it seems that doSomething is not used in your script. And at google.script.run.dropdownChanged(selectedValue);, the function dropdownChanged is tried to be run in the Google Apps Script side. I guess that this might be the reason for your current issue. In this case, how about modifying it to doSomething? When this is reflected in your script, it becomes as follows.

From:

dropdownHTML += 'google.script.run.dropdownChanged(selectedValue);';

To:

dropdownHTML += 'google.script.run.doSomething(selectedValue);';

By this, the function doSomething at the Google Apps Script is run with a value of selectedValue.

Note:

  • If the 1st page header is enabled, please disable it and test it again. Because I'm worried that your doSomething might not be able to put the value to the 1st page header. Please be careful about this.

Added 1:

From your following reply,

it seems through my many revisions I forgot to change this. After calling the correct function as you suggested there is still no change in the header.

Although I'm not sure about your actual Google Document, I'm worried about "Note" section in my answer. If you are required to enable the 1st page header, please modify your function doSomething as follows. By this, appendParagraph(value) is run on both the 1st page header and other pages.

function doSomething(value) {
  // Get the active Google Document
  var doc = DocumentApp.getActiveDocument();

  // I modified the below script.
  const document = doc.getBody().getParent();
  let s = null;
  while (s = document.findElement(DocumentApp.ElementType.HEADER_SECTION, s)) {
    s.getElement().asHeaderSection().appendParagraph(value);
  }
}

Added 2:

From your following reply,

My current google document is a completely blank document

In this case, please modify doSomething as follows.

function doSomething(value) {
      // Get the active Google Document
  var doc = DocumentApp.getActiveDocument();
  
  // Get the header of the document
  var header = doc.getHeader() || doc.addHeader();
  
  // Set the text of the header to the selected value
  header.appendParagraph(value);
}

In the case of new Document, no header is existing as the default. So, it is required to use addHeader.

Added 3:

From your following reply,

I am seeing errors on the doSomething() call in this Executions tab. I cannot seem to get any information from these other than they failed though.

However it is worth noting that I have not been able to get an error to show from doSomething in the last hour.

I think that you can see the error message in "Executions" of the script editor. But, I'm worried that you might not be able to understand this. So, please modify the function doSomething as follows. By this, when an error occurs at doSomething, the error message is shown in the dialog.

function doSomething(value) {
  try {
    // Get the active Google Document
    var doc = DocumentApp.getActiveDocument();

    // Get the header of the document
    var header = doc.getHeader() || doc.addHeader();

    // Set the text of the header to the selected value
    header.appendParagraph(value);

  } catch (e) {
    DocumentApp.getUi().showModalDialog(HtmlService.createHtmlOutput(e.stack), "sample");
  }
}