如何在使用 Bootstrap 和 HTML5 从 Google Sheet 填充数据的 Google Sheet Apps 脚本中添加“数据列表”

问题描述

首先,如果这是一个愚蠢的问题,我深表歉意,因为我是编码和编程的新手。

我正在尝试使用 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 检查输入数据后,我返回了与输入名称对应的选定行中的匹配数据。最后,我只是使用 innerHtmlgetElementById 来修改选择字段。

我已经构建了一个简单抽象的示例,说明如何实现您的目标,以便其他有类似疑问的用户可以从中学习。请修改您的代码以包含此示例。下面我插入了有关工作表数据结构和 Web 应用程序工作方式的图像:

enter image description here

enter image description here

代码中有不言自明的注释,但如果您有任何疑问,请随时提出:

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>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...