Chrome include(页面)函数,用于不加载DOM引用的脚本

2o7dmzc5  于 2023-04-09  发布在  Go
关注(0)|答案(1)|浏览(147)

使用GoogleApps脚本HtmlService类来生成一些输出。这个特定的案例是针对GoogleSheets侧边栏的,但我也在使用它作为Web应用程序时遇到过它。
我遇到了一个问题,如果我把我的脚本直接放到html文件中,DOM引用工作正常。
未捕获的类型错误:无法读取null的属性(阅读“value”)
下面是HTML表单和scriptlet:

<body>
  <?!= include('LOGO') ?>
  <form id="add">
    <div><input id=" fName" type="text" /> First Name</div>
    <div><input id="lName" type="text" /> Last Name</div>
    <div><input id="empId" type="text" /> ID#</div>
    <div><input id="job" type="text" /> Job</div>
    <div><input id="wage" type="text" /> Wage</div>
    <div id="job2" type="text" style="display: none"><input id="jobtwo" type="text" /> Job 2</div>
    <div id="wage2" type="text" style="display: none"><input id="wagetwo" type="text" /> Wage 2</div>
    <div id="job3" type="text" style="display: none"><input id="jobthree" type="text" /> Job 3</div>
    <div id="wage3" type="text" style="display: none"><input id="wagethree" type="text" /> Wage 3</div>
    <div>
      <button id="enter" type="button" onclick="addRecord()"> Enter</button>
      <button id="more" type="button" onclick="moreJobs()"> + Job</button>
      <button id="less" type="button" onclick="lessJobs()"> - Job</button>
      <button id="close" type="button" onclick="closeSide()"> Close</button>
    </div>
  </form>

  <?!= include("AddEmpJS") ?>
</body>

这是include函数引用的AddEmpJS.html;

<script>
    function addRecord() {
      let fname = document.getElementById("fName").value
      let lname = document.getElementById("lName").value
      let empId = document.getElementById("empId").value
      let job = document.getElementById("job").value
      let wage = document.getElementById("wage").value
      let job2 = document.getElementById("jobtwo").value
      let wage2 = document.getElementById("wagetwo").value
      let job3 = document.getElementById("jobthree").value
      let wage3 = document.getElementById("wagethree").value
      let record = [
        fname, lname, empId, job, wage, job2, wage2, job3, wage3
      ]
      console.log(record)
      google.script.run.addEmpRecord(record);
      document.getElementById("add").reset()
    }

    function moreJobs() {
      if(document.getElementById("job2").style.display == "none") {
        document.getElementById("job2").style.display = "block"
        document.getElementById("wage2").style.display = "block"
        return "job 2 showing"
      }
      if(document.getElementById("job3").style.display == "none") {
        document.getElementById("job3").style.display = "block"
        document.getElementById("wage3").style.display = "block"
        return "job 3 showing"
      }
    }

    function lessJobs() {
      if(document.getElementById("job3").style.display == "block") {
        document.getElementById("job3").style.display = "none"
        document.getElementById("wage3").style.display = "none"
        return "removing job 3"
      }      
      if(document.getElementById("job2").style.display == "block") {
        document.getElementById("job2").style.display = "none"
        document.getElementById("wage2").style.display = "none"
        return "removing job 2"
      }
    }

    function closeSide() {
      google.script.host.close()
    }

   </script>

服务器端的include函数,
function include(page) { return HtmlService.createHtmlOutputFromFile(page).getContent(); }
调用侧边栏的UI

function addEmp() {
  var page = HtmlService.createTemplateFromFile("AddEmp").evaluate();
  page.setTitle("💼 Add Employee")
  ui.showSidebar(page)

整个剧本

const ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EMPLOYEES");
const setup = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SETUP");
const summary = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SUMMARY");
const ui = SpreadsheetApp.getUi();

function onOpen(e) {
  ui.createMenu("👔 Employees")
    .addItem("💼 Add Employee", "addEmp")
    .addItem("✨ Edit Employee", "editEmp")
    .addItem("🔥 Del Employee", "delEmp")
    .addToUi();
  ui.createMenu("📋 Departments")
    .addItem("➕ Add Department", "addDept")
    .addItem("🔧 Edit Department", "editDept")
    .addItem("➖ Del Department", "delDept")
    .addToUi();
  ui.createMenu("⌚ Schedule")
    .addItem("📅 Add Week", "addSched")
    .addItem("🔎 Update Summary Tab", "updateTabs")
    .addToUi();    
  updateTabs();
}

function updateTabs() {
  var tabList = SpreadsheetApp.getActiveSpreadsheet().getSheets().map((s) => s.getName())
    .filter((s) => s != "SETUP" && s != "EMPLOYEES" && s != "TEMPLATE" && s != "SUMMARY")
  Logger.log(tabList)
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(tabList)
  var dropDown = summary.getRange("A1").setDataValidation(rule).activate();

}

function include(page) {
    return HtmlService.createHtmlOutputFromFile(page).getContent();
}

//ADD EDIT & REMOVE EMPLOYEE HTML 
function addEmp() {
  var page = HtmlService.createTemplateFromFile("AddEmp").evaluate();
  page.setTitle("💼 Add Employee")
  ui.showSidebar(page)
}
function editEmp() {
  var page = HtmlService.createHtmlOutputFromFile("EditEmp")
    .setTitle("✨ Edit Employee");
  ui.showSidebar(page)
}
function delEmp() {
  var page = HtmlService.createHtmlOutputFromFile("DelEmp")
    .setTitle("🔥 Delete Employee");
  ui.showSidebar(page)
}

//checks for an id# and job code
// if id# already exist, err to checkId
// if job doesn't exist, eff to checkJob

function addEmpRecord(record) {
  let array_target = ws.getRange("C2");
  let array_formula = array_target.getFormula();
  array_target.clear();
  if (!checkId(record[2]) && !checkJob(record[3])) {
    ws.getRange(ws.getLastRow() + 1, 1, 1, 10).setValues([[
      record[0], record[1], , record[2].toString(), record[3].toUpperCase(), record[4], record[5].toUpperCase(), record[6], record[7].toUpperCase(), record[8]
    ]])
    var html = HtmlService.createHtmlOutput("<h4>Entry Accepted</h4><p>Close sidebar to continue or add another employee.</p>")
      .setWidth(300)
      .setHeight(125);
    ui.showModalDialog(html, "Success!")

  }
  else if (checkId(record[2].toString())) {
    var html = HtmlService.createHtmlOutput("<h4>User id# already exists</h4><p>Please choose different id#</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  else if (checkJob(record[3])) {
    var html = HtmlService.createHtmlOutput("<h4>Job Code does not exitst</h4><p>Please choose a valid job code.<br>*Case sensitive</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  else {
    var html = HtmlService.createHtmlOutput("<h4>Unspecified error</h4><p>Please contact support.</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  array_target.setValue(array_formula)
}

// checks if an id# already exists
function checkId(num) {
  var result = false;
  var current_ids = ws.getRange(2, 4, ws.getLastRow(), 1).getValues();
  for (id = 0; id < current_ids.length; id++) {
    if (current_ids[id].toString() == num.toString()) {
      result = true
    }
  }
  return result
}

// checks if a job code exists
function checkJob(job) {
  var result = false;
  var current_jobs = setup.getRange(2, 3, setup.getLastRow(), 1).getValues();
  for (job = 0; job < current_jobs.length; job++) {
    if (current_jobs[job] == job) {
      result = true
    }
  }
  return result
}

function editEmp() {
  Logger.log("editting an employee")
}

function delEmp() {
  Logger.log("deleting an employee")
}

我想利用include(“page”)函数来保持样式、脚本和html的独立性和可读性。
我认为这与如何加载和评估数据有关,但不知道如何应用修复。
当我将代码拆分到scriplet include函数时,我考虑使用window.onload eventhandler重新评估代码,但我不知道这是否是表单的最佳方法。

mbskvtky

mbskvtky1#

我相信你的目标如下。

  • 您希望删除当前的Uncaught TypeError: Cannot read properties of null (reading 'value')版本。

当我看到你的脚本时,在HTML的顶部,使用了<div><input id=" fName" type="text" /> First Name</div>。在这种情况下,id" fName"。但是,在你的Javascript中,使用了let fname = document.getElementById("fName").value
我认为您当前的Uncaught TypeError: Cannot read properties of null (reading 'value')问题的原因是由于此。因此,请修改如下。

发件人:

<div><input id=" fName" type="text" /> First Name</div>

收件人:

<div><input id="fName" type="text" /> First Name</div>

相关问题