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

Google Apps Script点击提交后modalDialog内HTML全部消失问题

Google Apps Script 弹窗提交后内容全部消失问题修复

问题现象

在Google Apps Script中通过modalDialog()加载HTML表单,实现用户输入采集、数据写入表格的功能,数据传输存储逻辑运行正常。新增个人编号格式校验后,点击提交按钮时弹窗内所有HTML内容直接消失,并非普通的输入框清空状态。

根本原因

  1. 表单内的提交按钮未指定type属性,form标签内的按钮默认type为submit,点击时会触发表单默认提交行为,导致弹窗内页面上下文刷新,所有内容被清空。
  2. HTML结构非法:主表单内部嵌套了第二个form标签(包裹单选按钮的<form action="#">),HTML规范不允许form元素嵌套,浏览器解析DOM时会出现结构错乱,加剧提交异常。
  3. 现有个人编号校验逻辑存在边界漏洞:如果用户输入的内容不含-符号,indexOf()会返回-1,后续字符串切割逻辑会出现异常。

修复步骤

  • 给提交按钮添加type="button"属性,彻底阻止默认表单提交行为
  • 删除单选按钮区域多余的嵌套form标签,将单选元素直接放在外层主form内部
  • 补充个人编号校验的边界判断,当输入不含横杠时直接触发格式错误提示
  • (可选)添加提交成功后的回调,提交完成后可选择清空表单或关闭弹窗,优化交互

修复后完整代码

HTML表单代码(userform.html)

<!DOCTYPE html>
<html>
<head>
  <!--Import Google Icon Font-->
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  <!-- Compiled and minified CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
  <!--Let browser know website is optimized for mobile-->
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div class="container">
    <div class="row">
    <form class="col s12" id="Formid">
      <div class="row">
        <div class="input-field col s12">
          <i class="material-icons prefix">account_circle</i>
          <input id="lawyername" type="text" class="validate">
          <label for="lawyername">Lawyer First Name</label>
        </div>
        <div class="input-field col s12">
          <i class="material-icons prefix">account_circle</i>
          <input id="clientname" type="text" class="validate">
          <label for="clientname">Client Name</label>
        </div>
        <!-- 已删除多余的嵌套form标签 -->
        <fieldset>
          <p>
            <label>
              <input class="with-gap" value="individual" id="check1" name="group1" type="radio" checked />
              <span>Individual</span>
            </label>
          </p>
          <p>
            <label>
              <input class="with-gap" value="corporation" id="check2" name="group1" type="radio" />
              <span>Corporation</span>
            </label>
          </p>
        </fieldset>
        <div class="input-field col s12">
          <i class="material-icons prefix">input</i>
          <input id="clientpersonnummer" type="text" class="validate">
          <label for="clientpersonnummer">Personnummber (YYMMDD-XXXX)</label>
        </div>
        <div class="input-field col s12">
          <i class="material-icons prefix">input</i>
          <input id="address" type="text" class="validate">
          <label for="address">Client Address</label>
        </div>
        <div class="input-field col s12">
          <!-- 新增type="button"阻止默认提交 -->
          <button type="button" class="btn waves-effect waves-light" id="btn">Add Client
            <i class="material-icons right">send</i>
          </button>
        </div>
      </div>
    </form>
  </div>
</div>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
  document.getElementById("btn").addEventListener("click",addRecord);
  function addRecord(){
    var lName = document.getElementById("lawyername");
    var cName = document.getElementById("clientname");
    var address = document.getElementById("address"); 
    var radiobtn = document.querySelector('input[name="group1"]:checked');
    var personnum = document.getElementById("clientpersonnummer").value.trim();
    var indHyp = personnum.indexOf("-");
    // 补充横杠不存在的边界判断
    if (indHyp === -1) {
      alert("Check Personal number! Format MUST be 'XXXXXX-XXXX'");
      return;
    }
    var sStart = personnum.slice(0,indHyp);
    var sFin = personnum.slice(indHyp + 1, personnum.length);
    if (sStart.length !== 6 || sFin.length !== 4) {
      alert("Check Personal number! Format MUST be 'XXXXXX-XXXX'");
      return;
    }
    var data = {
      lawyer: lName.value.trim(),
      client: cName.value.trim(),
      pn: personnum,
      address: address.value.trim(),
      radio: radiobtn.value
    };
    // 提交成功后回调,可选:清空表单/关闭弹窗
    google.script.run
      .withSuccessHandler(() => {
        document.getElementById("Formid").reset();
        // 如需提交后关闭弹窗可打开下方注释
        // google.script.host.close();
      })
      .appendData(data);
  }
</script>
</body>
</html>

Apps Script 代码(.gs文件)

function showUserForm() {
  var template = HtmlService.createTemplateFromFile("userform");
  var html = template.evaluate();
  html.setHeight(650);
  SpreadsheetApp.getUi().showModalDialog(html, "Enter New Client Data");
}

function appendData(data) {
  var radout = data.radio;
  var wsurl = 'urlLinkHere';
  var destinationSpreadSheet = SpreadsheetApp.openByUrl(wsurl);
  var ws;
  if (radout == 'individual') {
    ws = destinationSpreadSheet.getSheets()[1];
  } else if (radout == 'corporation') {
    ws = destinationSpreadSheet.getSheets()[2];
  } else {
    throw new Error('Selection Unclear');
  }
  ws.appendRow([data.client, data.pn, data.address, data.lawyer]);
  SpreadsheetApp.getUi().alert("New Data Submitted");
}

注:修复时顺便修正了两个单选按钮id重复的问题(原代码两个单选都用了id="check1",id需全局唯一,第二个已改为check2),同时把DOM元素获取逻辑移到点击事件内部,避免页面加载时元素未渲染完成导致的空值问题,增加了输入值trim()去除首尾空格的处理,减少格式误判。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:03:19