Google Apps Script: Как создать динамическую форму?

Что такое динамическая форма и зачем она нужна?

Динамическая форма – это Google Форма, структура которой изменяется в зависимости от действий пользователя или внешних данных. В отличие от статических форм, где набор вопросов фиксирован, динамические формы адаптируются, предлагая разные поля и вопросы в зависимости от предыдущих ответов. Это позволяет сделать процесс заполнения более релевантным и эффективным, собирая только необходимую информацию. Представьте форму для регистрации на конференцию, где вопросы о питании и проживании появляются только если пользователь отметил соответствующий пункт.

Преимущества использования Google Apps Script для создания динамических форм

Google Apps Script (GAS) предоставляет мощные инструменты для работы с Google Формами. Основные преимущества:

  • Автоматизация: GAS позволяет автоматизировать процесс создания, изменения и обработки форм, избавляя от рутинных задач.
  • Гибкость: С помощью GAS можно реализовать сложную логику, недоступную в стандартных настройках Google Форм.
  • Интеграция: GAS легко интегрируется с другими сервисами Google (Sheets, Docs, Drive) и сторонними API, расширяя возможности форм.
  • Персонализация: Можно создать уникальный пользовательский опыт, адаптируя форму под конкретные нужды.

Необходимые знания и инструменты

Для создания динамических форм потребуется:

  • Базовое понимание HTML, CSS и JavaScript (хотя бы на уровне концепций).
  • Знание синтаксиса JavaScript (GAS основан на JavaScript).
  • Опыт работы с Google Apps Script (основные объекты, методы и сервисы).
  • Умение работать с редактором Google Apps Script.
  • Понимание принципов работы Google Forms API.

Создание базовой Google Формы и привязка к Google Apps Script

Создание новой Google Формы

Создайте новую Google Форму через Google Drive (Создать -> Google Forms). Добавьте несколько базовых вопросов, чтобы было с чем работать.

Открытие редактора Google Apps Script из формы

В открытой форме нажмите на значок с тремя точками в правом верхнем углу, выберите «Редактор скриптов». Откроется редактор GAS, привязанный к вашей форме.

Основные объекты и методы работы с формой (Form, Item, etc.)

Основные объекты GAS для работы с формами:

  • Form: Представляет саму форму. Получить доступ к форме можно через FormApp.getActiveForm() или FormApp.openById(formId). formId – это идентификатор формы, который можно найти в URL.
  • Item: Представляет отдельный элемент формы (вопрос, секция, изображение и т.д.).
  • ItemType: Определяет тип элемента формы (TEXT, CHECKBOX, LIST, MULTIPLE_CHOICE и т.д.).
  • Response: Представляет ответ пользователя на форму.
  • FormApp: Сервис, предоставляющий доступ к Google Forms API.

Примеры методов:

  • form.addTextItem(title): Добавляет текстовый вопрос с указанным заголовком.
  • form.addCheckboxItem(title): Добавляет вопрос с флажками.
  • form.addListItem(title): Добавляет выпадающий список.
  • item.setTitle(title): Устанавливает заголовок элемента.
  • item.setHelpText(text): Устанавливает текст-подсказку для элемента.

Реализация динамического поведения: добавление и удаление элементов

Добавление новых элементов формы (текстовые поля, списки, и т.д.) на основе условий

Добавление элементов формы в runtime – ключевой момент динамического поведения. Это обычно делается на основе триггеров (например, onFormSubmit или пользовательский интерфейс). Пример:

/**
 * @param {GoogleAppsScript.Events.FormsOnFormSubmit} e
 */
function onFormSubmit(e) {
  /** @type {GoogleAppsScript.Forms.Form} */
  const form = FormApp.getActiveForm();
  /** @type {string} */
  const answerToFirstQuestion = e.response.getItemResponses()[0].getResponse();

  if (answerToFirstQuestion === 'Да') {
    form.addTextItem('Пожалуйста, укажите причину');
  }
}

Удаление элементов формы

Удаление элементов выполняется с использованием form.deleteItem(index). Важно понимать, что индекс элемента может измениться после добавления или удаления других элементов. Лучше всего использовать уникальный идентификатор, если это возможно.

Примеры реализации: зависимые списки, раскрывающиеся вопросы

  • Зависимые списки: Выбор в первом списке определяет варианты во втором списке. Реализуется добавлением/изменением вариантов второго списка на основе выбора в первом.
  • Раскрывающиеся вопросы: Дополнительные вопросы появляются только при выборе определенного варианта ответа.

Обработка отправки формы и сохранение динамически сгенерированных данных

Обработка отправки формы осуществляется через триггер onFormSubmit. В обработчике необходимо извлечь ответы из e.response и сохранить их в Google Sheets или другом хранилище. Важно учесть, что динамически добавленные элементы будут иметь переменные индексы, поэтому лучше искать их по заголовку или другим уникальным атрибутам.

Реклама

Практический пример: Создание формы обратной связи с динамическим добавлением полей

Описание задачи: форма для сбора информации о проблемах пользователей с возможностью добавления нескольких описаний проблем

Создадим форму обратной связи, где пользователь может добавлять несколько описаний проблем. В форме будет поле для ввода имени, email и кнопка «Добавить проблему». При нажатии на кнопку будет добавляться новое текстовое поле для описания проблемы.

Разработка логики скрипта: добавление кнопки ‘Добавить проблему’, обработка нажатия, создание новых текстовых полей

  1. Создаем форму с полями «Имя» и «Email».
  2. Добавляем секцию (Section) в форму, в которой будем динамически добавлять поля.
  3. Создаем пользовательское меню с кнопкой «Добавить проблему». При нажатии на кнопку будет выполняться функция, добавляющая новое текстовое поле в указанную секцию.
  4. В обработчике отправки формы собираем данные из всех добавленных текстовых полей.

Код скрипта с комментариями и пояснениями

/**
 * @OnlyCurrentDoc
 */

/**
 * Creates a custom menu in the Google Form.
 */
function onOpen() {
  /** @type {GoogleAppsScript.Forms.Form} */
  const form = FormApp.getActiveForm();
  /** @type {GoogleAppsScript.Ui.Ui} */
  const ui = FormApp.getUi();
  ui.createMenu('Custom Menu')
      .addItem('Add Problem', 'addProblem')
      .addToUi();
}

/**
 * Adds a new problem description field to the form.
 */
function addProblem() {
  /** @type {GoogleAppsScript.Forms.Form} */
  const form = FormApp.getActiveForm();
  // Assuming the section for problems is the second item (index 1)
  // Adjust the index if necessary
  /** @type {GoogleAppsScript.Forms.SectionItem} */
  const section = form.getItems()[1].asSectionItem();
  form.addTextItem('Описание проблемы').setSection(section);
}

/**
 * Handles form submission.
 * @param {GoogleAppsScript.Events.FormsOnFormSubmit} e
 */
function onFormSubmit(e) {
  /** @type {GoogleAppsScript.Forms.Form} */
  const form = FormApp.getActiveForm();
  /** @type {GoogleAppsScript.Spreadsheet.Spreadsheet} */
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  /** @type {GoogleAppsScript.Spreadsheet.Sheet} */
  const sheet = ss.getSheetByName('Form Responses 1'); // Adjust sheet name if necessary

  // Get all items in the form
  /** @type {GoogleAppsScript.Forms.Item[]} */
  const items = form.getItems();
  /** @type {string[]} */
  const problemDescriptions = [];

  // Iterate through responses to find problem descriptions.
  for (let i = 0; i < items.length; i++) {
    /** @type {GoogleAppsScript.Forms.ItemType} */
    const itemType = items[i].getType();
    if (itemType === FormApp.ItemType.TEXT) {
        /**@type {string} */
        const itemTitle = items[i].getTitle();
        if (itemTitle === 'Описание проблемы'){
             /**@type {string} */
             const problemDescription = e.response.getItemResponses()[i].getResponse();
             problemDescriptions.push(problemDescription);
        }

    }
  }
  // Log descriptions into Spreadsheet (can be adjusted for db or other processing)
  sheet.appendRow([problemDescriptions.join(', ')]);
}

Тестирование и отладка формы

Запустите функцию onOpen, чтобы создать пользовательское меню. Откройте форму и проверьте, что кнопка «Добавить проблему» появилась. Нажмите на кнопку несколько раз и убедитесь, что новые текстовые поля добавляются в форму. Заполните форму и проверьте, что данные сохраняются правильно.

Расширенные возможности и оптимизация

Использование SpreadsheetApp для хранения и обработки данных динамической формы

Как показано в примере выше, SpreadsheetApp может быть использован для хранения ответов на форму, включая динамически добавленные поля. Можно создавать различные отчеты и анализировать данные в Sheets.

Валидация данных, введенных пользователем

GAS позволяет валидировать данные перед отправкой формы. Например, можно проверить формат email, минимальную длину текстового поля и т.д. Валидация осуществляется с помощью методов item.setValidation() и item.require. Пример:

/** @type {GoogleAppsScript.Forms.TextItem} */
const emailItem = form.addTextItem('Email');
/** @type {GoogleAppsScript.Forms.TextValidationBuilder} */
const emailValidation = FormApp.createTextValidation().requireTextIsEmail().build();
emailItem.setValidation(emailValidation);

Оптимизация производительности скрипта (кэширование, асинхронные вызовы)

Для повышения производительности скрипта рекомендуется:

  • Кэширование: Использовать Service Properties или Script Properties для хранения часто используемых данных (например, ID формы, ID таблицы).
  • Асинхронные вызовы: Использовать UrlFetchApp.fetch() для выполнения запросов к внешним API в асинхронном режиме.

Публикация и использование формы

После завершения разработки формы можно опубликовать ее и предоставить доступ пользователям. Убедитесь, что скрипт имеет необходимые разрешения для работы с Google Sheets и другими сервисами.


Добавить комментарий