包括页面的函数以便脚本加载DOM引用

huangapple go评论102阅读模式
英文:

include(page) function for script not loading DOM references

问题

以下是代码部分的翻译:

  1. Using Google Apps Script HtmlService class to produce some output. This specific case is for a Google Sheets sidebar, but I'm also running into it when utilizing as a web app.
  2. I'm running into an issue where if I put my script directly into the html file, the DOM references work fine. Once I put them into and <?!= include("page") ?> scriptlet, it throws an error;
  3. > Uncaught TypeError: Cannot read properties of null (reading 'value')
  4. Here is the html form and scriptlet:


First Name
Last Name
ID#
Job
Wage





```

This is the AddEmpJS.html referenced by the include function;

  1. <script>
  2. function addRecord() {
  3. let fname = document.getElementById("fName").value
  4. let lname = document.getElementById("lName").value
  5. let empId = document.getElementById("empId").value
  6. let job = document.getElementById("job").value
  7. let wage = document.getElementById("wage").value
  8. let job2 = document.getElementById("jobtwo").value
  9. let wage2 = document.getElementById("wagetwo").value
  10. let job3 = document.getElementById("jobthree").value
  11. let wage3 = document.getElementById("wagethree").value
  12. let record = [
  13. fname, lname, empId, job, wage, job2, wage2, job3, wage3
  14. ]
  15. console.log(record)
  16. google.script.run.addEmpRecord(record);
  17. document.getElementById("add").reset()
  18. }
  19. function moreJobs() {
  20. if(document.getElementById("job2").style.display == "none") {
  21. document.getElementById("job2").style.display = "block"
  22. document.getElementById("wage2").style.display = "block"
  23. return "job 2 showing"
  24. }
  25. if(document.getElementById("job3").style.display == "none") {
  26. document.getElementById("job3").style.display = "block"
  27. document.getElementById("wage3").style.display = "block"
  28. return "job 3 showing"
  29. }
  30. }
  31. function lessJobs() {
  32. if(document.getElementById("job3").style.display == "block") {
  33. document.getElementById("job3").style.display = "none"
  34. document.getElementById("wage3").style.display = "none"
  35. return "removing job 3"
  36. }
  37. if(document.getElementById("job2").style.display == "block") {
  38. document.getElementById("job2").style.display = "none"
  39. document.getElementById("wage2").style.display = "none"
  40. return "removing job 2"
  41. }
  42. }
  43. function closeSide() {
  44. google.script.host.close()
  45. }
  46. </script>

The include function on the server side,

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

The UI that calls the sidebar,

  1. function addEmp() {
  2. var page = HtmlService.createTemplateFromFile("AddEmp").evaluate();
  3. page.setTitle("&#128188; Add Employee")
  4. ui.showSidebar(page)

and the whole script,

  1. const ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EMPLOYEES");
  2. const setup = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SETUP");
  3. const summary = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SUMMARY");
  4. const ui = SpreadsheetApp.getUi();
  5. function onOpen(e) {
  6. ui.createMenu("&#128084; Employees")
  7. .addItem("&#128188; Add Employee", "addEmp")
  8. .addItem("✨ Edit Employee", "editEmp")
  9. .addItem("&#128293; Del Employee", "delEmp")
  10. .addToUi();
  11. ui.createMenu("&#128203; Departments")
  12. .addItem("➕ Add Department", "addDept")
  13. .addItem("&#128295; Edit Department", "editDept")
  14. .addItem("➖ Del Department", "delDept")
  15. .addToUi();
  16. ui.createMenu("⌚ Schedule")
  17. .addItem("&#128197; Add Week", "addSched")
  18. .addItem("&#128270; Update Summary Tab", "updateTabs")
  19. .addToUi();
  20. updateTabs();
  21. }
  22. function updateTabs() {
  23. var tabList = SpreadsheetApp.getActiveSpreadsheet().getSheets().map((s) => s.getName())
  24. .filter((s) => s != "SETUP" && s != "EMPLOYEES" && s != "TEMPLATE" && s != "SUMMARY")
  25. Logger.log(tabList)
  26. var rule = SpreadsheetApp.newDataValidation().requireValueInList(tabList)
  27. var dropDown = summary.getRange("A1").setDataValidation(rule).activate();
  28. }
  29. function include(page) {
  30. return HtmlService.createHtmlOutputFromFile(page).getContent();
  31. }
  32. //ADD EDIT & REMOVE EMPLOYEE HTML
  33. function addEmp() {
  34. var page = HtmlService.createTemplateFromFile("AddEmp").evaluate();
  35. page.setTitle("&#128188; Add Employee")
  36. ui.showSidebar(page)
  37. }
  38. function editEmp() {
  39. var page = HtmlService.createHtmlOutputFromFile("EditEmp")
  40. .setTitle("✨ Edit Employee");
  41. ui.showSidebar(page)
  42. }
  43. function delEmp() {
  44. var page = HtmlService.createHtmlOutputFromFile("DelEmp")
  45. .setTitle("&#128293; Delete Employee");
  46. ui.showSidebar(page)
  47. }
  48. //checks for an id# and job code
  49. // if id# already exist, err to checkId
  50. // if job doesn't exist, eff to checkJob
  51. function addEmpRecord(record) {
  52. let array
  53. <details>
  54. <summary>英文:</summary>
  55. Using Google Apps Script HtmlService class to produce some output. This specific case is for a Google Sheets sidebar, but I&#39;m also running into it when utilizing as a web app.
  56. I&#39;m running into an issue where if I put my script directly into the html file, the DOM references work fine. Once I put them into and &lt;?!= include(&quot;page&quot;) ?&gt; scriptlet, it throws an error;
  57. &gt; Uncaught TypeError: Cannot read properties of null (reading &#39;value&#39;)
  58. Here is the html form and 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>

  1. This is the AddEmpJS.html referenced by the include function;

<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()
}

  1. function moreJobs() {
  2. if(document.getElementById(&quot;job2&quot;).style.display == &quot;none&quot;) {
  3. document.getElementById(&quot;job2&quot;).style.display = &quot;block&quot;
  4. document.getElementById(&quot;wage2&quot;).style.display = &quot;block&quot;
  5. return &quot;job 2 showing&quot;
  6. }
  7. if(document.getElementById(&quot;job3&quot;).style.display == &quot;none&quot;) {
  8. document.getElementById(&quot;job3&quot;).style.display = &quot;block&quot;
  9. document.getElementById(&quot;wage3&quot;).style.display = &quot;block&quot;
  10. return &quot;job 3 showing&quot;
  11. }
  12. }
  13. function lessJobs() {
  14. if(document.getElementById(&quot;job3&quot;).style.display == &quot;block&quot;) {
  15. document.getElementById(&quot;job3&quot;).style.display = &quot;none&quot;
  16. document.getElementById(&quot;wage3&quot;).style.display = &quot;none&quot;
  17. return &quot;removing job 3&quot;
  18. }
  19. if(document.getElementById(&quot;job2&quot;).style.display == &quot;block&quot;) {
  20. document.getElementById(&quot;job2&quot;).style.display = &quot;none&quot;
  21. document.getElementById(&quot;wage2&quot;).style.display = &quot;none&quot;
  22. return &quot;removing job 2&quot;
  23. }
  24. }
  25. function closeSide() {
  26. google.script.host.close()
  27. }

</script>

  1. The include function on the server side,
  2. `function include(page) {
  3. return HtmlService.createHtmlOutputFromFile(page).getContent();
  4. }`
  5. The UI that calls the sidebar,

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

  1. and the whole script,

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")
}

  1. I&#39;d like to utilize the include(&quot;page&quot;) function to keep the style, script, and html separate and readable. What am I missing here?
  2. I think it has something to do with how the data is loaded and evaluated, but don&#39;t see how to apply a fix.
  3. When I split apart the code over to the scriplet include function, I looked into using a window.onload eventhandler to re-evaluate the code, but I don&#39;t know if that is the best approach with a form.
  4. </details>
  5. # 答案1
  6. **得分**: 0
  7. 我相信你的目标如下。
  8. - 你想要解决当前的问题`Uncaught TypeError: Cannot read properties of null (reading 'value')`
  9. 当我看到你的脚本时,在HTML的顶部,使用了`&lt;div&gt;&lt;input id=&quot; fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;`。在这种情况下,`id``&quot; fName&quot;`。但是,在你的Javascript中,使用了`let fname = document.getElementById(&quot;fName&quot;).value`
  10. 我认为你当前的问题`Uncaught TypeError: Cannot read properties of null (reading 'value')`的原因是这个。所以,请按照以下方式进行修改。
  11. ### 从:
  12. &lt;div&gt;&lt;input id=&quot; fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;
  13. ### 到:
  14. &lt;div&gt;&lt;input id=&quot;fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;
  15. <details>
  16. <summary>英文:</summary>
  17. I believe your goal is as follows.
  18. - You want to remove your current issue of `Uncaught TypeError: Cannot read properties of null (reading &#39;value&#39;)`.
  19. When I saw your script, at the top HTML, `&lt;div&gt;&lt;input id=&quot; fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;` is used. In this case, `id` is `&quot; fName&quot;`. But, in your Javascript, `let fname = document.getElementById(&quot;fName&quot;).value` is used.
  20. I think that the reason for your current issue of `Uncaught TypeError: Cannot read properties of null (reading &#39;value&#39;)` is due to this. So, please modify as follows.
  21. ### From:
  22. &lt;div&gt;&lt;input id=&quot; fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;
  23. ### To:
  24. &lt;div&gt;&lt;input id=&quot;fName&quot; type=&quot;text&quot; /&gt; First Name&lt;/div&gt;
  25. </details>

huangapple
  • 本文由 发表于 2023年4月4日 10:59:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定