I’m trying to create a simple lookup form using Google Apps Script. The form uses data sourced from a spreadsheet to populate a number of autocomplete input fields. I can’t figure out why the autocomplete is not working. In supplierIDLookupFormHTML.html I put the script tag for the materialize js file at the very end of the body tag.
The function showSidebar_sellerID() in show_sidebars.js does append a simple div tag to the end of the body tag. But that shouldn’t affect the materialze js code, should it?
Please help. Here is my code.
supplierIDLookupFormHTML.html
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_top">
<!-- Required meta tags -->
<meta charset="utf-8">
<!--Let browser know website is optimized for mobile-->
<meta id="viewport" content="width=device-width, initial-scale=1.0"/>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" media="screen,projection"/>
<!-- Add the standard Google Style Sheet. -->
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<!--Import supplierIDLookupFormHTML,css -->
<?!= HtmlService.createHtmlOutputFromFile('supplierIDLookupFormHTML.css').getContent(); ?>
</head>
<body>
<div class="container">
<!-- <h1>New Customer</h1> -->
<form id="new-customer-form" onsubmit="onSubmitFormHandler(event)">
<div class="row">
<div class="input-field col m6">
<label for="companyName">Company Name</label>
<input type="text" id="companyName" name="companyName" class="autocomplete">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6">
<label for="ebayID">ebayID</label>
<input type="text" id="ebayID" name="ebayID" class="autocomplete">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6">
<label for="amazonSellerID">Amazon Seller ID</label>
<input type="text" id="amazonSellerID" name="amazonSellerID" class="autocomplete">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6">
<label for="aliexpressSellerID">Aliexpress Seller ID</label>
<input type="text" id="aliexpressSellerID" name="aliexpressSellerID" class="autocomplete">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6">
<label for="supplierID">Seller ID</label>
<input type="text" id="supplierID" name="supplierID" readonly="readonly">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6">
<label for="selectedSupplierName">Selected Supplier Name</label>
<input type="text" id="selectedSupplierName" name="selectedSupplierName" readonly="readonly">
</div>
</div><!-- end .row -->
<div class="row">
<div class="input-field col m6 p-1">
<button type="submit" class="btn waves-effect waves-light" name="submitBtn" id="submitBtn" value="submit">Submit
<i class="material-icons right">Submit</i>
</button>
</div>
<div class="input-field col md6">
<button type="close" class="btn btn-secondary btn-block" id="closeBtn" value="Close" onclick="google.script.host.close()">Close</button>
</div>
</div><!-- end .row -->
</form><!-- end form -->
<p>
<div id="errorMsg"></div>
</p>
<p>
<div id="sucessMsg"></div>
</p>
</div><!-- end .container -->
<!--JavaScript at end of body for optimized loading-->
<!-- Initialise: jQuery -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<!-- Initialise: LoDash-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<!-- Shared javascript functions -->
<?!= HtmlService.createHtmlOutputFromFile('sharedJavascriptFunctionsJS').getContent(); ?>
<?!= HtmlService.createHtmlOutputFromFile('supplierIDLookupFormHTML.js').getContent(); ?>
<!-- Compiled and minified JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</html>
src/supplierIDLookupFormHTML.js.html
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
document.addEventListener('DOMContentLoaded', function() {
window.addEventListener('load', preventFormSubmit);
//google.script.run.withSuccessHandler(populateSuppliers).getSuppliers();
initialize();
google.script.run.withSuccessHandler(populateCompanyNames).getSupplierCompanyNames();
/*google.script.run.withSuccessHandler(populateEbayIDs).getSupplierebayIDs();
google.script.run.withSuccessHandler(populateAmazonSellerIDs).getSupplierAmazonSellerIDs();
google.script.run.withSuccessHandler(populateAliexpressSellerIDs).getSupplierAliexpressSellerIDs();*/
});
// REWRITE
function buildAutoCompleteDataObject() {
var customers = getDataFromHtml('customerObj_htmlservice');
const customer = customers[Object.keys(customers)[0]];
console.log(customer);
//console.log(customer.customerID);
//console.log(customer.firstName);
// fill in the form fields using the data from the customer object.
// loop through each entry of the customer object and match the entry with an element in the current document.
Object.entries(customer).forEach((entry) => {
const [key, value] = entry;
//console.log(`${key}: ${value}`);
//console.log(typeof `${value}`);
var element = document.getElementById(`${key}`);
if (element) {
console.log("element (" + `${key}` + ") exists");
document.getElementById(`${key}`).value = `${value}`;
} else {
console.log("Element (" + `${key}` + ") does not exist")
}
});
}
function getDataFromHtml(idData) {
if (!idData)
idData = "mydata_htmlservice";
var dataEncoded = document.getElementById(idData).innerHTML;
//console.log(dataEncoded);
var data = JSON.parse(dataEncoded);
return data;
}
//FIX THIS
function initialize() {
const suppliers = getDataFromHtml('suppliersObj_htmlservice');
const supplier = suppliers[Object.keys(suppliers)[0]];
//console.log("const suppliers: " + suppliers);
//console.log("const supplier: " + supplier);
_.forEach(suppliers, function(supplier) {
_.forEach(supplier, function(value, key) {
//console.log("lodash nested forEach():")
//console.log(`${key}: ${value}`);
});
console.log("");
});
//console.log(suppliers[0][supplierid]);
}
function populateCompanyNames(companyNames){
console.log("running: populateCompanyNames()");
console.log(companyNames);
var autocomplete = document.getElementById('companyName');
var instances = M.autocomplete.init(autocomplete, { data: companyNames });
}
function populateEbayIDs(ebayIDs){
let autocomplete = document.getElementById('ebayID');
let instances = M.autocomplete.init(autocomplete, {data: ebayIDs});
}
function populateAmazonSellerIDs(amazonSellerIDss){
let autocomplete = document.getElementById('amazonSellerID');
let instances = M.autocomplete.init(autocomplete, {data: amazonSellerIDs});
}
function populateAliexpressSellerIDs(aliexpressSellerID){
let autocomplete = document.getElementById('aliexpressSellerID');
let instances = M.autocomplete.init(autocomplete, {data: aliexpressSellerIDs});
}
function onListFailure(error) {
//alert(error.message);
console.log("onListFailure() triggered. Error message was: " + error.message);
}
//const dropdownIDs = ["companyName", "ebayID", "amazonSellerID", "aliexpressSellerID"];
function handleFormSubmit(formObject) {
google.script.run.processForm(formObject);
document.getElementById("myForm").reset();
}
function onClickSubmitBtnHander() {
var supplierID = $("#supplierID").val();
google.script.run.setCurrentCellSupplierID(supplierID);
}
</script>
show_sidebars.js
/**
* @function showSidebar_sellerID
* @description TODO
*/
function showSidebar_sellerID() {
var SIDEBAR_TITLE = 'SellerID Lookup';
var suppliersObj = JSON.stringify(getSuppliers());
//console.log("suppliersObj: " + suppliersObj)
const sidebar = HtmlService.createTemplateFromFile('supplierIDLookupFormHTML')
var htmlOutput = sidebar.evaluate();
var strAppend = "<div id='suppliersObj_htmlservice' style='display:none;'>" + suppliersObj + "</div>";
htmlOutput.append(strAppend);
htmlOutput.setTitle(SIDEBAR_TITLE);
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
error shown in developer console
Uncaught
TypeError: Cannot read properties of undefined (reading 'init')
at populateCompanyNames (userCodeAppPanel:81:36)
at Ph (695454968-mae_html_user_bin_i18n_mae_html_user__en_gb.js:149:334)
at 695454968-mae_html_user_bin_i18n_mae_html_user__en_gb.js:36:276
at mf.N (695454968-mae_html_user_bin_i18n_mae_html_user__en_gb.js:102:380)
at Ed (695454968-mae_html_user_bin_i18n_mae_html_user__en_gb.js:64:477)
at a (695454968-mae_html_user_bin_i18n_mae_html_user__en_gb.js:62:52)