问题描述
首先,如果这是一个愚蠢的问题,我深表歉意,因为我是编码和编程的新手。
我正在尝试使用 Google Apps 脚本为我的公司创建一个 CRM Web 应用程序,该应用程序将所有数据存储在 Google 表格中。工作仍在进行中。
这个 CRM Web 应用程序基本上有一个主页选项卡(用于搜索和编辑数据)、销售选项卡(用于输入销售条目)、采购选项卡、(输入采购条目)和联系人选项卡(用于添加联系人详细信息)。
>这个想法是,用户首先在“联系人”选项卡中添加新客户/供应商的详细联系信息,然后该数据将存储在 Google 表格中。
现在要进行销售或采购条目,用户现在必须首先在相应的选项卡中选择已输入的联系人(只有姓名、电话号码和电子邮件 ID 可见)。
为此,我尝试从 Bootstrap 添加数据列表,这将帮助用户搜索和选择已存储的联系人详细信息,并且需要根据选定的姓名/电子邮件/电话自动填写依赖的联系人字段。
我厌倦了很多方法并参考了几篇文章,但我无法从 Google 表格中填充搜索数据。我尝试使用下拉逻辑,但即使这样也不起作用。
以下是我的代码。我只粘贴看起来与你们相关的部分,因为整个事情非常无组织。任何帮助将不胜感激。
Loadform.gs:
function loadForm() {
const htmlServ = HtmlService.createTemplateFromFile("uform");
const html = htmlServ.evaluate();
html.setWidth(850).setHeight(600);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(html,"VKSPCPL CRM");
}
function createMenu_(){
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("CRM");
menu.addItem("Open APP","loadForm");
menu.addToUi();
}
function onopen(){
createMenu_();
}
Functions.gs:
//Sales Functions---------------------------
function salesEntry(rowDataSales) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Sales Contact Details");
const currentDate = new Date();
const uniqueIDs = ws.getRange(2,1,ws.getLastRow()-1,1).getValues();
var maxnum = 0;
uniqueIDs.forEach(r => {
maxnum = r[0] > maxnum ? r[0] : maxnum
});
var caseNo = maxnum + 1;
ws.appendRow([
caseNo,rowDataSales.inputSalesCxName,"Sales",rowDataSales.inputSalesCaSEOwner,currentDate,rowDataSales.inputSalesCoName,rowDataSales.inputSalesEmail,rowDataSales.inputSalesPhone,rowDataSales.inputSalesGST,rowDataSales.inputSalesCoAdd,rowDataSales.inputSalesstate]);
return true;
}
function getSalesCaSEOwnerDropdown(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("CaSEOwners");
return ws.getRange(2,1).getValues();
}
function salesstateList(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("States");
return ws.getRange(2,1).getValues();
}
function salesContactName(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Contact Details");
return ws.getRange(2,1).getValues();
}
//-------------------------------------------------------------------------------------------
//Contact Functions--------------------------------------------------------------------------
function getContactDropdown(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Customer Type");
return ws.getRange(2,2).getValues();
}
function contactEntry(rowDataContact) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Contact Details");
const currentDate = new Date();
ws.appendRow([
rowDataContact.inputContactName,rowDataContact.inputContactCoName,rowDataContact.inputContactPhone,rowDataContact.inputContactEmail,rowDataContact.inputContactGST,rowDataContact.inputContactCoAdd,rowDataContact.inputContactState,rowDataContact.inputContactCategory,rowDataContact.inputContactType,currentDate]);
return true;
}
function contactStateList(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("States");
return ws.getRange(2,1).getValues();
}
uform.html:
<!doctype html>
<html lang="en">
<head>
<!-- required Meta tags -->
<Meta charset="utf-8">
<Meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
</head>
<body>
<div class="container">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="sales-tab" data-bs-toggle="tab" data-bs-target="#sales" type="button" role="tab" aria-controls="sales" aria-selected="false">Sales</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="purchase-tab" data-bs-toggle="tab" data-bs-target="#purchase" type="button" role="tab" aria-controls="purchase" aria-selected="false">Purchase</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Contact Details</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">1</div>
<div class="tab-pane fade" id="sales" role="tabpanel" aria-labelledby="sales-tab">
<br><h3 class="display-6">New Sales Case</h3>
<div class="col-md-4">
<select class="form-select form-select-sm" aria-label=".form-select-sm example" id="inputSales-CaSEOwner">
</select>
</div>
<br><h5>Contact Details</h5>
<form class="row g-3">
<div class="col-md-4">
<label for="exampleDataList" class="form-label">Datalist example</label>
<input class="form-control" list="datalistOptions" id="exampleDataList" placeholder="Type to search...">
<datalist id="inputSales-CxName">
</datalist>
...
...
...
<script>
//JS Script Here
</script>
</body>
</html>
如果你们需要更多脚本或细节,请告诉我。任何帮助将不胜感激。非常感谢提前!
解决方法
根据您的问题,我了解到您希望执行搜索,如果它与您已存储在工作表中的名称之一匹配,则 select HTML 元素选项应填充与该名称对应的信息并且应该被禁用。
为了做到这一点,我首先遵循了 Apps Script 指南中的 this detailed and well explained example,了解如何处理表单并将表单输入信息传递到您的 code.gs
文件。然后,根据使用 getValues 获得的电子表格列 A
检查输入数据后,我返回了与输入名称对应的选定行中的匹配数据。最后,我只是使用 innerHtml 和 getElementById 来修改选择字段。
我已经构建了一个简单抽象的示例,说明如何实现您的目标,以便其他有类似疑问的用户可以从中学习。请修改您的代码以包含此示例。下面我插入了有关工作表数据结构和 Web 应用程序工作方式的图像:
代码中有不言自明的注释,但如果您有任何疑问,请随时提出:
HTML 文件、代码文件
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate().setTitle('Web App Window Title');
}
// name is an object like this {name : "your inputed name"}
function getData(name) {
// Get the sheet where you have all your data
var sheet = SpreadsheetApp.openById('1Ifqk1LukwzjeZHc7DulMmoZPl34zbHNnLIzFanFAsqI').getSheetByName('Sheet1');
// Get a list of all your stored names. As getValues returns a 2D array,if
// you use flat() it will convert it into a 1D array which is of easier manipullation
var names = sheet.getRange(2,1,sheet.getLastRow(),1).getValues().flat();
// variable to store matching name data
var populateElements;
// if the array of names has the name entered in the input
if(names.includes(name.name)){
// get the index of the matching name in the names array
var index = names.indexOf(name.name);
// get an array of corresponding values of the name
// i.e age and field in this example
populateElements = sheet.getRange(index+2,2,2).getValues().flat();
// return the array of matching fields for that name
return populateElements;
}else{
// if there was no name match just return whatever you want that is not an array
return "popcorn"
}
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<!-- STYLES -->
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<script>
// This function is used so that the form submission
// does not refresh the web app
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);
// Function that gets the data returned getData if everything worked fine
function onSuccess(data) {
// data is the array of the elements to be populated.
// In this example [age,field]
// Select the HTML select elements
var selectAge = document.getElementById('age');
var selectField = document.getElementById('field');
// create the variables that will store the options
var optionAge;
var optionField;
// if data is an array and thus the name searched was successful and
// there were matches
if(data.length){
// create an option HTML element for each element in the array
optionAge = "<option value='" + data[0] + " disabled'>" + data[0] + "</option>";
// and set it to the corresponding select element
selectAge.innerHTML = optionAge;
optionField = "<option value='" + data[1] + " disabled'>" + data[1] + "</option>";
selectField.innerHTML = optionField;
}
}
// This function will run when the form is submitted
// formObject is that data submitted. In this case this is equals to {name:name}
function handleFormSubmit(formObject) {
// set to run getData passing the inputed name and if successful run the function
// ablove onSuccess
google.script.run.withSuccessHandler(onSuccess).getData(formObject);
}
</script>
</head>
<body>
<h1>
Select Name
</h1>
<!-- On this form submission this will call the function handleFormSubmit -->
<!-- and it will pass the input value -->
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input name="name" type="text" />
<input type="submit" value="Submit" />
</form>
<!-- The select inputs that will be modified on the name search -->
<select name="age" id="age">
<option value="Selection 1">Selection 1</option>
<option value="Selection 2">Selection 2</option>
</select>
<select name="field" id="field">
<option value="Selection 1">Selection 1</option>
<option value="Selection 2">Selection 2</option>
</select>
</body>
</html>