appscript.dev
Automation Intermediate Sheets

Build a custom sidebar data-entry form

Capture structured input inside Northwind's Sheets — sidebar UI bound to the workbook.

Published Jul 3, 2025

Typing straight into a spreadsheet is fast until it isn’t. At Northwind, the projects log kept drifting: dates entered in the wrong column, the timestamp forgotten, a client name spelled three different ways. The data was right there in the grid, so people skipped the discipline a form would have forced on them.

A sidebar form fixes that without leaving the sheet. It opens in a panel beside the grid, takes a small set of required fields, and appends a clean, consistently shaped row every time. The person entering data never touches a cell directly, so the columns stay in order and the timestamp is never missed.

What you’ll need

  • A Google Sheet whose first tab is the log you want to append to. The script writes three columns in this order: timestamp, client, project — so the sheet should have headers to match in row 1.
  • An HTML file named Sidebar in the same Apps Script project (created with File > New > HTML file).
  • No add-on, no deployment — the sidebar runs inside the bound script, so anyone who can edit the sheet can open it.

The sidebar HTML (Sidebar.html)

<!-- A minimal form. "required" makes the browser block an empty submit. -->
<form id="f">
  <label>Client <input name="client" required></label>
  <label>Project <input name="project" required></label>
  <button>Add</button>
</form>
<script>
  // Intercept the submit so the page never reloads.
  document.getElementById('f').addEventListener('submit', (e) => {
    e.preventDefault();

    // Turn the form fields into a plain { client, project } object.
    const data = Object.fromEntries(new FormData(e.target));

    // Call the server-side addRow function with that object.
    google.script.run.addRow(data);

    // Clear the fields so the next entry starts fresh.
    e.target.reset();
  });
</script>

The Apps Script

// The tab the form appends to. The first sheet in the workbook.
const TARGET_SHEET_INDEX = 0;

/**
 * Runs when the spreadsheet opens. Adds a Northwind menu so anyone
 * can launch the sidebar without opening the script editor.
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Northwind')
    .addItem('Add row…', 'showSidebar')
    .addToUi();
}

/**
 * Opens the Sidebar.html file as a panel beside the grid.
 */
function showSidebar() {
  const html = HtmlService.createHtmlOutputFromFile('Sidebar')
    .setTitle('Add a row');
  SpreadsheetApp.getUi().showSidebar(html);
}

/**
 * Called from the sidebar form. Appends one clean row with a
 * timestamp, so the columns stay consistent on every entry.
 */
function addRow(data) {
  // Guard: ignore an empty or malformed payload.
  if (!data || !data.client || !data.project) return;

  // appendRow always writes after the last row — no row-counting needed.
  SpreadsheetApp.getActive()
    .getSheets()[TARGET_SHEET_INDEX]
    .appendRow([new Date(), data.client, data.project]);
}

How it works

  1. onOpen runs automatically when the workbook is opened and adds a Northwind menu with a single Add row… item.
  2. Choosing that item calls showSidebar, which loads Sidebar.html and docks it as a panel on the right of the spreadsheet.
  3. The form has two required fields. The browser blocks an empty submit before the script ever sees it.
  4. On submit, the page’s script cancels the default reload, collects the fields into a { client, project } object, and hands it to the server with google.script.run.addRow(data).
  5. addRow runs on the Apps Script side. It bails out if either field is missing, then appends a row of [timestamp, client, project] to the first tab — so the date is always recorded and the columns never drift.
  6. The form resets, ready for the next entry, while the sidebar stays open.

Example run

A user opens the sheet, picks Northwind > Add row…, and types into the panel:

FieldValue
ClientAtlas Foods
ProjectQ3 rebrand

After clicking Add, a new row appears at the bottom of the first tab:

TimestampClientProject
2025-07-03 09:14:22Atlas FoodsQ3 rebrand

The fields clear, and the next entry can go straight in without reaching for the mouse.

Run it

This is an on-demand tool, so there is no trigger to schedule:

  1. Paste the Apps Script into the bound project and create the Sidebar HTML file alongside it.
  2. Reload the spreadsheet so onOpen runs and the Northwind menu appears.
  3. Choose Northwind > Add row… and approve the authorisation prompt the first time.
  4. Enter a client and project, then click Add.

Watch out for

  • The menu only appears after a reload. onOpen runs when the workbook opens, so the first time you add the code you must refresh the tab to see it.
  • google.script.run is fire-and-forget here. The form resets immediately without waiting for the server. If you want a “saved” confirmation, add a .withSuccessHandler() callback before .addRow(data).
  • Column order is fixed in addRow. If you add a field to the form, add it to the appendRow array too, or the new value will land in the wrong column.
  • The sidebar is roughly 300px wide and cannot be resized. Keep the form short; it is built for quick structured entry, not long records.
  • Anyone who can edit the sheet can open the form and append rows. There is no per-user permission layer — the sidebar inherits the spreadsheet’s sharing.

Related