Google Apps Script:选择行号无法填充HTML输入框,报Uncaught eval错误
问题修复方案
核心问题分析
- HTML语法错误:select标签的
id="rowNum"与onchange属性之间无空格,导致浏览器无法正确解析事件;同时重复绑定onchange(标签内+script内)引发冲突。 - 参数传递失效:调用
google.script.run.setValue()时未传入选中行号,服务端函数无法获取有效参数。 - 前后端逻辑混淆:服务端模板直接调用依赖客户端localStorage的
headerRowToInsert,但服务端无法读取客户端存储数据。 - 表格取值逻辑错误:
getRange(e,1,LastRow,LastCol)会从第e行开始取LastRow行数据,不符合仅获取目标行的需求。 - 字段匹配逻辑缺陷:找到第一个匹配字段就返回整行数组,未正确收集所有匹配值。
修复后的代码
1. export_getRow.html(行号选择侧边栏)
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <p>Header row</p> <select name="rowNum" id="rowNum" style="width:280px;height:30px;"> <option value="none" selected>Please select a row</option> <?!= options ?> </select> <p>Select the row with the field title of the data to export.</p> <button onclick='prevPage()'>prev</button> <button onclick='nextPage()'>next</button> <button onclick='insertData()'>insert Data</button> <script> const headerRow = document.getElementById("rowNum"); // 统一通过script绑定onchange事件,传递选中行号 headerRow.onchange = function(){ const selectedRow = headerRow.value; console.log(selectedRow); localStorage.setItem("selectRowNum", selectedRow); google.script.run.setValue(selectedRow); } const valueToInsert = localStorage.getItem("selectObjToInsert"); console.log(valueToInsert); function prevPage() { google.script.run.getSheetListforExport(); } function insertData() { google.script.run.salesforceEntryPoint(valueToInsert, headerRow.value); } function nextPage() { const selectedRow = headerRow.value; if(selectedRow !== "none"){ google.script.run.setValue(selectedRow); } else { alert("Please select a row first!"); } } </script> </body> </html>
2. export_MatchingField.html(匹配字段输入框侧边栏)
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <!-- 直接使用服务端传入的匹配后数据 --> <? for(var i=0; i<value.length; i++){ ?> <div style="margin-top:5px;"> <!-- 给input设置唯一ID,避免重复 --> <input type="text" id="textValue_<?=i?>" name='textValue' value="<?= value[i] ?>"> </div> <? } ?> <button onclick='prevPage()'>Prev</button> <script> const textBoxes = document.querySelectorAll('[id^=textValue]'); let textToWrite; for(let i = 0; i < textBoxes.length; i++){ textToWrite = textBoxes[i].value; console.log(textToWrite); } function prevPage() { google.script.run.getRowNum(); } </script> </body> </html>
3. matchField.gs(服务端逻辑)
function matchingField(selectedRow){ // 先校验参数有效性 if(!selectedRow || selectedRow === "none"){ return []; } const ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const lastCol = ss.getLastColumn(); // 仅获取选中行的整行数据(第selectedRow行,1行,所有列) const rowData = ss.getRange(selectedRow, 1, 1, lastCol).getValues()[0]; const url = 'example.com'; const response = UrlFetchApp.fetch(url, getUrlFetchOptions()); const json = response.getContentText(); const data = JSON.parse(json); const dataSobjectsField = data.fields; // 提取接口返回的字段名数组 const sfFieldNames = dataSobjectsField.map(field => field.name); // 收集当前行中与接口字段匹配的值 const matchedValues = rowData.filter(cellValue => sfFieldNames.includes(cellValue)); return matchedValues; } function setValue(selectedRow){ // 调用匹配函数获取结果 const matchedValues = matchingField(selectedRow); const html = HtmlService.createTemplateFromFile('export_MatchingField'); // 将匹配结果传入模板 html.value = matchedValues; const sidebar = html.evaluate() .setTitle('DG Connector') .setWidth(400) .setSandboxMode(HtmlService.SandboxMode.IFRAME); SpreadsheetApp.getUi().showSidebar(sidebar); }
额外说明
- 移除了标签内重复的onchange绑定,统一通过script处理事件,避免冲突。
- 修正了表格取值范围,仅获取选中行的数据,优化匹配逻辑返回所有匹配值。
- 模板不再依赖客户端localStorage,通过服务端直接传递匹配后的数据,解决前后端数据隔离问题。
- 给input设置唯一ID,避免DOM元素ID重复引发的潜在问题。
内容的提问来源于stack exchange,提问作者whytili
相关产品推荐
相关产品推荐

