表单下拉框onchange事件函数无法执行问题排查
问题:下拉框onchange绑定的handleFormSubmit函数无法触发执行
开发了仅包含单个下拉框字段的表单,已为下拉框的onchange事件绑定handleFormSubmit函数,但该函数无法触发执行。
相关下拉框代码:
<select type="text" class="form-control" id="searchtext" onchange="handleFormSubmit(this)" name="searchtext" placeholder="Search Text">
完整代码文件
Code.gs
function doGet() { return HtmlService.createTemplateFromFile('Index').evaluate() .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); } /* PROCESS FORM */ function processForm(formObject){ var result = ""; if(formObject.searchtext){//Execute if form passes search text result = search(formObject.searchtext); } return result; } //SEARCH FOR MATCHED CONTENTS function search(searchtext){ var spreadsheetId = '1fVBNWvZkFMOfnlt8r6fevt-ozTPweiR5oXot1GU4g2A'; //** CHANGE !!! var dataRage = 'Data!A2:D'; //** CHANGE !!! var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values; var ar = []; data.forEach(function(f) { if (~f.indexOf(searchtext)) { ar.push(f); } }); return ar; }
Index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o" crossorigin="anonymous"></script> <!--##JAVASCRIPT FUNCTIONS ---------------------------------------------------- --> <script> //PREVENT FORMS FROM SUBMITTING / PREVENT DEFAULT BEHAVIOUR function preventFormSubmit() { var forms = document.querySelectorAll('form'); for (var i = 0; i < forms.length; i++) { forms[i].addEventListener('submit', function(event) { event.preventDefault(); }); } } window.addEventListener("load", preventFormSubmit, true); //HANDLE FORM SUBMISSION function handleFormSubmit(formObject) { google.script.run.withSuccessHandler(createTable).processForm(formObject); document.getElementById("search-form").reset(); } //CREATE THE DATA TABLE function createTable(dataArray) { if(dataArray && dataArray !== undefined && dataArray.length != 0){ var result = "<table class='table table-sm' id='dtable' style='font-size:0.8em'>"+ "<thead>"+ "<tr>"+ //Change table headings to match witht he Google Sheet "<th scope='col'>Model</th>"+ "<th scope='col'>Price</th>"+ "<th scope='col'>Warranty</th>"+ "</tr>"+ "</thead>"; for(var i=0; i<dataArray.length; i++) { result += "<tr>"; for(var j=0; j<dataArray[i].length; j++){ result += "<td>"+dataArray[i][j]+"</td>"; } result += "</tr>"; } result += "</table>"; var div = document.getElementById('search-results'); div.innerHTML = result; }else{ var div = document.getElementById('search-results'); //div.empty() div.innerHTML = "Data not found!"; } } </script> <!--##JAVASCRIPT FUNCTIONS ~ END ---------------------------------------------------- --> </head> <style> body{ margin:0; padding-top: 10px; font-family: sans-serif; } *{ box-sizing: border-box; } .table{ width: 100%; border-collapse: collapse; } .table td,.table th{ padding:12px 15px; border:1px solid #ddd; text-align: center; font-size:16px; } .table th{ background-color: darkblue; color:#ffffff; } .table tbody td:nth-child(even){ background-color: #f5f5f5; } table td:nth-child(1){ display:none;} /*responsive*/ @media(max-width: 500px){ .table tr{ margin-bottom:15px; } .table td::before{ left:0; font-size:15px; font-weight: bold; text-align: left; } } </style> <body> <div class="container"> <!-------------------------- SEARCH FORM ----------------------------------------- --> <form id="search-form" style="margin: 0 auto; width: 50%" > <div class="form-group mx-sm-3 mb-2" > <select type="text" class="form-control" id="searchtext" onchange="handleFormSubmit(this)" name="searchtext" placeholder="Search Text"> <option> Select </option> <option> FLO </option> <option> TUBULAR </option> </select> </div> <button type="submit" class="btn btn-primary mb-2">Search</button> </form> <!-- ## SEARCH FORM ~ END -------------------------------------------- --> <!-- ## TABLE OF SEARCH RESULTS ------------------------------------------ --> <div id="search-results" class="table" > <!-- The Data Table is inserted here by JavaScript --> </div> <!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------ --> </div> </body> </html>
问题原因
核心问题是**handleFormSubmit函数接收的参数类型不匹配**:
- 当前下拉框
onchange事件传递的是this,即单个<select>DOM元素; - 但
handleFormSubmit中调用的google.script.run.processForm(formObject)要求传入的是完整的表单对象,而非单个表单控件。单个控件无法被google.script.run正确解析为包含searchtext属性的对象,导致后端processForm函数无法识别有效参数,最终表现为函数看似未触发。
注:preventFormSubmit函数仅阻止表单提交的默认行为,与onchange事件触发无关,不是问题根源。
解决方案
提供两种可行的修改方式:
方式1:传入完整表单对象
修改下拉框的onchange事件,直接传入整个表单:
<select type="text" class="form-control" id="searchtext" onchange="handleFormSubmit(document.getElementById('search-form'))" name="searchtext" placeholder="Search Text">
方式2:适配单个控件参数
修改handleFormSubmit函数,手动从传入的<select>元素中构建符合要求的表单对象:
function handleFormSubmit(selectElement) { // 手动构建包含searchtext属性的对象 const formObject = { searchtext: selectElement.value }; google.script.run.withSuccessHandler(createTable).processForm(formObject); document.getElementById("search-form").reset(); }
两种方式均可让handleFormSubmit正确触发,调用后端逻辑并渲染搜索结果。
内容的提问来源于stack exchange,提问作者Prabhu Paul
相关产品推荐
相关产品推荐

