You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何克隆HTML表单并将完整结果传递至Google Apps Script函数?

解决方案

一、修复表单克隆逻辑

用隐藏模板克隆条目,避免重复携带已填写值:

<!-- 事件条目模板(默认隐藏) -->
<div class="event-entry-template" style="display:none;">
  <div class="event-entry">
    <h3>Event <span class="event-number"></span></h3>
    <div class="filters-container"></div>
    <button class="add-filter">添加过滤器</button>
    <button class="remove-event">删除事件条目</button>
  </div>
</div>

<!-- 过滤器条目模板(默认隐藏) -->
<div class="filter-entry-template" style="display:none;">
  <div class="filter-entry">
    <div>
      <label>过滤字段:</label>
      <select class="filter-field">
        <option value="Event Title">事件标题</option>
        <option value="Guest Domain">访客域名</option>
      </select>
    </div>
    <div>
      <label>操作符:</label>
      <select class="filter-operator">
        <option value="equals">等于</option>
        <option value="contains">包含</option>
      </select>
    </div>
    <div>
      <label>值:</label>
      <input type="text" class="filter-value">
    </div>
    <button class="remove-filter">删除过滤器</button>
  </div>
</div>

对应JS克隆逻辑:

// 绑定添加事件按钮
document.querySelector('.add-event').addEventListener('click', () => {
  const template = document.querySelector('.event-entry-template');
  const newEvent = template.cloneNode(true);
  newEvent.classList.remove('event-entry-template');
  newEvent.style.display = 'block';
  
  // 设置事件编号
  const eventCount = document.querySelectorAll('.event-entry').length + 1;
  newEvent.querySelector('.event-number').textContent = eventCount;
  
  document.querySelector('.events-container').appendChild(newEvent);
  bindFilterButtons(newEvent);
  bindRemoveEventButton(newEvent);
});

// 绑定添加过滤器按钮
function bindFilterButtons(eventEntry) {
  eventEntry.querySelector('.add-filter').addEventListener('click', () => {
    const template = document.querySelector('.filter-entry-template');
    const newFilter = template.cloneNode(true);
    newFilter.classList.remove('filter-entry-template');
    newFilter.style.display = 'flex';
    
    eventEntry.querySelector('.filters-container').appendChild(newFilter);
    bindRemoveFilterButton(newFilter);
  });
}

// 绑定删除事件按钮
function bindRemoveEventButton(eventEntry) {
  eventEntry.querySelector('.remove-event').addEventListener('click', () => {
    eventEntry.remove();
    // 重新编号事件
    document.querySelectorAll('.event-entry').forEach((entry, index) => {
      entry.querySelector('.event-number').textContent = index + 1;
    });
  });
}

// 绑定删除过滤器按钮
function bindRemoveFilterButton(filterEntry) {
  filterEntry.querySelector('.remove-filter').addEventListener('click', () => {
    filterEntry.remove();
  });
}

// 初始化第一个事件条目
bindFilterButtons(document.querySelector('.event-entry'));

二、解析表单为目标JSON格式

编写函数遍历表单,生成符合要求的JSON结构:

function parseFormToJson() {
  const events = {};
  const eventEntries = document.querySelectorAll('.event-entry');
  
  eventEntries.forEach((entry, eventIndex) => {
    const eventKey = `Event ${eventIndex + 1}`;
    const filterObj = {};
    const filterEntries = entry.querySelectorAll('.filter-entry');
    
    filterEntries.forEach((filter, filterIndex) => {
      const filterKey = `Filter ${filterIndex + 1}`;
      filterObj[filterKey] = {
        "Filter Field": filter.querySelector('.filter-field').value,
        "Filter Operator": filter.querySelector('.filter-operator').value,
        "Filter Value": filter.querySelector('.filter-value').value
      };
    });
    
    events[eventKey] = [filterObj];
  });
  
  return JSON.stringify(events, null, 2);
}

三、传递JSON到Google Apps Script

用google.script.run把JSON传给服务器端函数,处理日历上色逻辑:

// 绑定提交按钮
document.querySelector('.submit-config').addEventListener('click', () => {
  const configJson = parseFormToJson();
  
  google.script.run
    .withSuccessHandler(() => alert('配置已应用!'))
    .withFailureHandler(error => alert('处理失败:' + error.message))
    .processCalendarFilters(configJson);
});

对应GS服务器端函数:

function processCalendarFilters(configJson) {
  const config = JSON.parse(configJson);
  // 这里嵌入你已有的日历事件上色逻辑
  // 示例:遍历每个事件配置,筛选并设置日历事件颜色
  for (const eventKey in config) {
    const filters = config[eventKey][0];
    // 你的日历处理代码...
  }
  return 'success';
}

四、保存配置以便复用

用GS的Properties Service保存配置,后续可加载回填:

// GS端保存配置
function saveConfig(configJson) {
  PropertiesService.getUserProperties().setProperty('calendarFilterConfig', configJson);
}

// GS端加载配置
function loadConfig() {
  const configJson = PropertiesService.getUserProperties().getProperty('calendarFilterConfig');
  return configJson ? JSON.parse(configJson) : {};
}

(注:加载配置后可编写前端回填逻辑,自动生成对应数量的事件和过滤器条目并填充值)

内容的提问来源于stack exchange,提问作者MinMin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:48:22