rtindru
rtindru

Reputation: 5337

Google Apps Script getRanges returns a list with a single Range

I am trying to get the range of selected cells in Google Apps Scripts and chain them into an HtmlOutput.

One of the columns in my spreadsheet has HTML input. For example: <p>Hello <em>World</em></p>. The idea is to simply give a nice preview of the HTML.

My use case is that the user selects a range of cells (multiple rows, same column) by dragging their cursor across, and then previews content for the selected rows.

I am trying to do this with this code:

function previewModal() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var ranges =  sheet.getActiveRangeList().getRanges();
  var html = HtmlService.createHtmlOutput('');
  for (var i = 0; i < ranges.length; i++) {
    var contentCell = ranges[i];        
    var htmlContent = contentCell.getValue();
    html.append('<div>').append(htmlContent).append('</div>').append('<hr>');
  }
  html.setWidth(1000).setHeight(1000);
  SpreadsheetApp.getUi().showModalDialog(html, 'Preview');
}

However, when I run this, I see that ranges.length is equal to 1, regardless of how many cells I have selected. And the cell that ranges contains is the "active" cell -> this is the one which you first clicked, before dragging across to cover more cells. As a result, my HTML output just contains the value from that 1 cell and not the range.

What I mean by "Active Cell" and "Active Range":

What I know so far:

Upvotes: 1

Views: 5289

Answers (1)

tehhowch
tehhowch

Reputation: 9872

A contiguous selection is a single Range. Use Range#getValues instead, to access all the values of a given Range. Range#getValue() will always return only the top-left value, even if there is more than 1 cell in the Range.

function previewModal() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet(),
        ranges =  sheet.getActiveRangeList().getRanges(),
        htmlPrefix = "",
        html = ranges.reduce(function (rgSummary, rg) {
          var summary = rg
              .getValues() // 2D array
              .reduce(arrayToHtmlReduceCallback_, "");
          return rgSummary + summary;
        }, htmlPrefix);
  const output = HtmlService.createHtmlOutput(html).setWidth(1000).setHeight(1000);
  SpreadsheetApp.getUi().showModalDialog(output, 'Preview');
}

function arrayToHtmlReduceCallback_(acc, row, i, allArrayRows) {
  const rowSummary = row[0]; // Using only the content of the first column.
  return acc + '<div>' + rowSummary + '</div><hr>';
}

Additional Reading:

Upvotes: 1

Related Questions