How to add options to an HTML Table using Apps Script? - html

I was wondering how I could add these options to an HTML table within Apps Script Editor.
Here's the script:
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate();
}
/* 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) {
//const searchtext = 'test#email.com'
const ss = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = ss.getId();
var dataRage = 'Approval Tracker!A2:J';
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
var ar = [];
data.forEach(function (f) {
if (f[9] == searchtext) {
ar.push([f[3], f[4], f[5], f[6], f[2]]);
}
});
return ar;
}
<!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 table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Change table headings to match witht he Google Sheet
"<th scope='col'>Date Assigned</th>"+
"<th scope='col'>Item</th>"+
"<th scope='col'>Link To File</th>"+
"<th scope='col'>Notes</th>"+
"<th scope='col'>Approval Status</th>"+
"<td><select name='D1'>" +
"<option value='volvo'>Volvo</option>" +
"<option value='saab'>Saab</option>" +
"<option value='mercedes'>Mercedes</option>" +
"<option value='audi'>Audi</option>" +
"</select>"+
"</td>" +
"</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>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Enter your email</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Enter your email">
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
This is the file's link:
This is the Web App URL
It's now appending one koption list to the header.
Appreciate any help!

From I've tried it above but the page is empty., if your are using your showing script, I think that your script is incomplete. So, please modify as follows and test it again.
From:
"<option value='audi'>Audi</option>" +
"</select></td>
"</tr>" +
"</thead>";
To:
"<option value='audi'>Audi</option>" +
"</select></td></tr></thead>";

Related

How to fill a multiple string to filter a data in Google Apps Script

I'm going to build web to be used in search for label information
My database is in Google Sheets, so I went looking for a Google Sheets fetch and gave it a try. I have no experience with Google App Scripts so I want to fill all and search data form database but it can run just one of them how to do it all (first is .gs second is Index.html) this is my reference.
https://gist.github.com/neno-tech/15d9c3fe32a2d8896c1875b7a827a6e5
https://docs.google.com/document/d/1EhzxSy-L5kBt5E-BA1B446G0OjQAuKqEgLUPpiZh3Pw/edit
This is my database : https://docs.google.com/spreadsheets/d/1j-r4gD1zV3e0yrNJTnHezXRlv1w-aOf6UqQs_P2jsRY/edit?usp=sharing
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate()
.setTitle('System Search Lable')
.addMetaTag('viewport', 'width=device-width, inital-scale=1')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function processForm(formObject){
var concat = formObject.searchtext+formObject.searchtext2+formObject.searchtext3+formObject.searchtext4+formObject.searchtext5;
var result = "";
if(concat){
result = search(concat);
}
return result;
}
function search(searchtext){
var spreadsheetId = '1j-r4gD1zV3e0yrNJTnHezXRlv1w-aOf6UqQs_P2jsRY';
var dataRange = 'Master Barcode!A2:O10';
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRange).values;
var ar = [];
data.forEach(function(f) {
if (~f.toString().toLowerCase().indexOf(searchtext.toString().toLowerCase())) {
ar.push(f);
}
});
return ar;
}
!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<center><form id="search-form" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Search a Label</label>
</div><p>
<div class="col-md-6 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Category">
<br>
<input type="text" class="form-control" id="searchtext2" name="searchtext2" placeholder="Size">
<br>
<input type="text" class="form-control" id="searchtext3" name="searchtext3" placeholder="Brand">
<br>
<input type="text" class="form-control" id="searchtext4" name="searchtext4" placeholder="Color">
<br>
<input type="text" class="form-control" id="searchtext5" name="searchtext5" placeholder="Lenght">
<br>
</div><p>
<button id="search" type="submit" class="btn btn-success mb-2">Search</button>
<span id="spinner" class="spinner-border spinner-border-sm d-none" role="status" aria-hidden="true"></span>
</form>
</center>
</div>
</div>
<div class="row">
<div class="col">
<div id="search-results" class="table-responsive">
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.5.4/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
<script>
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);
function handleFormSubmit(formObject) {
document.getElementById('search').innerHTML = "Loading";
document.getElementById('spinner').classList.remove("d-none");
google.script.run.withSuccessHandler(createTable).processForm(formObject);
document.getElementById("search-form").reset();
}
function createTable(dataArray) {
document.getElementById('search').innerHTML = "Search";
document.getElementById('spinner').classList.add("d-none");
if(dataArray && dataArray !== undefined && dataArray.length != 0){
var result = "<table class='table table-sm table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+
"<th scope='col'>Barcode</th>"+
"<th scope='col'>Brand</th>"+
"<th scope='col'>Standard</th>"+
"<th scope='col'>Year</th>"+
"<th scope='col'>Table</th>"+
"<th scope='col'>Type</th>"+
"<th scope='col'>Category</th>"+
"<th scope='col'>Coil</th>"+
"<th scope='col'>X</th>"+
"<th scope='col'>Size</th>"+
"<th scope='col'>Lenght</th>"+
"<th scope='col'>Weight</th>"+
"<th scope='col'>Color</th>"+
"<th scope='col'>Voltage</th>"+
"<th scope='col'>Size lable</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.innerHTML = "Data not found!";
}
}
</script>
</body>
</html>
The results are here is that I fill in only one field. What I mean is I filled out the required information into each field, however I would like to know a way to fill in all fields in order to make it easier to filter.
To filter results based on the values you enter in the web form, pass all search elements to your search function and then check that that they are all either blank or match. This assumes that the search terms and the columns in your sheet are in the same order. Example:
const MAPPING = [7, 10, 2, 13, 11];
function processForm({ searchtext, searchtext2, searchtext3, searchtext4, searchtext5 }){
let searchTerms = [searchtext, searchtext2, searchtext3, searchtext4, searchtext5];
var result = "";
if(searchTerms.find(Boolean)){
result = search(searchTerms);
}
return result;
}
function search(searchTerms){
var spreadsheetId = '1B0hcELJcoLxiYXNCDx9iRl8JxijwgdFBkte90oPfCnY';
var dataRange = 'Master Barcode!A46:O1346';
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRange).values;
var ar = [];
data.forEach(function(f) {
if (searchTerms.every((e, i) => !e || e === f[MAPPING[i]-1])) {
ar.push(f);
}
});
return ar;
}

Google Web App - Search box to filter the data from Google Spread sheet

Thanks in advance. Just to start with, I am not a coder, but I keep on researching. I made a search Web App to filter the data from Google spreadsheet which has more than 2000+ rows, which keeps on increasing day by day and around 135 columns for different Institutes. So, it was messy to search in that Google sheet, and hence I created this web app.
Everything is working smoothly until the records were around 1200 rows but now I am facing an issue to display more than 2000 records. The Web App Search box displays the list based on the key we pressed. Like if we enter "A", it will display the names starting from the alphabet "A". So, what I do is, I keep on adding the new tags (Institute names) and it works well but now suddenly after adding few records, it says unable to open the file.
Request you to please look into this and let me know any alternative or correct this code to work smoothly regardless of the numbers of tags or rows. Thank you so much.
<!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>
<!-- <link href="path/to/select2.min.css" rel="stylesheet" />
<script src="path/to/select2.min.js"></script> -->
<!-- <link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script> -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Autocomplete using Jquery</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.
css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!--##JAVASCRIPT FUNCTIONS ---------------------------------------------------- -->
<script type="text/javascript">
$( function() {
var searchtext = [
"Australian Catholic University",
"Australian National University (ANU)",
"Central Queensland University",
"Royal Melbourne Institute of Technology (RMIT)",
/*Like this we have more that 2000 names of Institutes*/
];
$( "#searchtext" ).autocomplete({
source: searchtext
/* #the tags is the id of the input element
source: tags is the list of available tags*/
});
} );
//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);
// $(document).ready(function() {
// $('.js-example-basic-single').select2();
// });
function myFunction() {
document.getElementById("searchtext").size = "70";
}
//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 table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Table headings
"<th scope='col'>Institution</th>"+
"<th scope='col'>Agreement with</th>"+
"<th scope='col'>Type of institution</th>"+
"<th scope='col'>Country</th>"+
/*Around 100+ Columns are there*/
"</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>
<body style="background-color:#cdffcd;">
<h1 align="center"><img src="https://drive.google.com/uc?export=download&id=16SqA92JMCD3AVWH07BeyPPLlEBaO_4Ae" alt="logo" width="120" height="100"/> The SoT Search Form</h1>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)" action="/action_page.php" method="get">
<div class="form-group mb-2">
<label for="searchtext" align="center"><strong>Search for the provider</strong></label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input id="searchtext" name="searchtext" class="form-control" onclick="myFunction()" placeholder="Enter the name.." align="center">
<!-- On keyup calls the function everytime a key is released -->
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
<input type="reset" class="btn btn-primary mb-2" id="resetbutton" style='margin-left:16px' value="Reset">
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
============= Code File===========================================
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate();
}
/* 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 = 'xxxxxxx';
var dataRage = 'ABC!A2:DV1500';
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
var ar = [];
data.forEach(function(f) {
if (~f.indexOf(searchtext)) {
ar.push(f);
}
});
return ar;
}

Google Spread Sheet Search any part of the cell and display

I have a code to search and display the exact field in any column.
I would like to get the code of partial search, such that the input value if we entre is partial, should display all the possible fields.
Eg. Search "Evaluation" in the search field should display all the possible results.
enter image description here
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate();
}
/* 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 = '1iG30kufq5MQpd0xmoPhPir5iA3hlz8s7vI_0EWQfg7Q'; //** CHANGE !!!
var dataRage = 'Data!A2:Y'; //** 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;
}
HTML CODE
<!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 table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Change table headings to match witht he Google Sheet
"<th scope='col'>MS No</th>"+
"<th scope='col'>Title</th>"+
"<th scope='col'>Status</th>"+
"<th scope='col'>Date</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>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Search MS No</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Enter MS No">
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Search Title</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Enter Title">
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
This will highlight partial substring matches in red:
function searchhilight() {
let hilite = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('red').build();
let normal = SpreadsheetApp.newTextStyle().setBold(false).setForegroundColor('black').build();
const ui = SpreadsheetApp.getUi();
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const sr = 2;//data start row
const rg = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, sh.getLastColumn());
rg.setFontColor('black').setFontWeight('normal');//set all data to black text with no bold
const dvs = rg.getDisplayValues();
const resp = ui.prompt('Search Text', 'Enter Search String', ui.ButtonSet.OK_CANCEL);
if (resp.getSelectedButton() == ui.Button.OK) {
const st = resp.getResponseText();
dvs.forEach((r, i) => {
r.forEach((c, j) => {
let idx = '';
fidx = '';//from index
iA = [];//index array of matches
do {
idx = c.indexOf(st, fidx);
if (~idx) {
fidx = idx + st.length;
iA.push({ idxs: idx, idxe: idx + st.length })
}
} while (~idx);
let rtv = SpreadsheetApp.newRichTextValue().setText(c);
iA.forEach(obj => rtv.setTextStyle(obj.idxs, obj.idxe, hilite));
sh.getRange(i + sr, j + 1).setNumberFormat('#STRING#');
sh.getRange(i + sr, j + 1).setRichTextValue(rtv.build());
});
});
}
}
This function will also reformat every cell in the data range to plain text.
RichTextValueBuilder
RichTextValue
function search(searchtext){
var spreadsheetId = '1do6G8pScBAz0Z7GOCjbBcXPKJkhbOwlSx5BZyt6S7H8'; //** CHANGE !!!
var dataRage = 'Data!A2:Y'; //** CHANGE !!!
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
var ar = [];
data.forEach(function(f) {
if (~f.toString().toLowerCase().indexOf(searchtext.toString().toLowerCase())) {
ar.push(f);
}
});
return ar;
}

Google sheet + Web app search multiple google workbook and return all matching rows

Anybody knows how can I amend the code below to search from 2 separate google workbooks? Currently, this only works to search from 1 google sheet in 1 workbook.
Both these sheets have the exact same headers.
When the user searches for a specific text, it should display the matching rows from both workbooks.
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 = '1443X5UzzRfpYachZZLFrmYFq821ioioqwFAnASY'; //** CHANGE !!!
var dataRage = 'TEST!A2:F'; //** 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 table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Change table headings to match witht he Google Sheet
"<th scope='col'>Group</th>"+
"<th scope='col'>QO Number</th>"+
"<th scope='col'>Patient NRIC</th>"+
"<th scope='col'>Swab Date</th>"+
"<th scope='col'>Lab ID</th>"+
"<th scope='col'>SERO Lab ID</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>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Swab Search</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="QO or NRIC (last 4 digits)">
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
Have an array with the ID of the different spreadsheets you want to retrieve data from, and iterate through that:
function search(searchtext){
var spreadsheetIds = ['1443X5UzzRfpYachZZLFrmYFq821ioioqwFAnASY'];
var dataRage = 'TEST!A2:F';
var ar = [];
spreadsheetIds.forEach(spreadsheetId => {
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
data.forEach(function(f) {
if (~f.indexOf(searchtext)) {
ar.push(f);
}
});
});
return ar;
}
If the range notation of the different spreadsheets should also change, then have an array with those ranges too, and access each element in the array using the forEach index parameter:
function search(searchtext){
var spreadsheetIds = ['SPREADSHEET_ID_1', 'SPREADSHEET_ID_2'];
var dataRages = ['RANGE_1', 'RANGE_2'];
var ar = [];
spreadsheetIds.forEach((spreadsheetId, i) => {
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRages[i]).values;
data.forEach(function(f) {
if (~f.indexOf(searchtext)) {
ar.push(f);
}
});
});
return ar;
}
Not sure if you want to retrieve more information than just the row index, but if that's the case, just push that information to ar, not just f.
Alternatively, use reduce:
function search(searchtext) {
const spreadsheetIds = ['SPREADSHEET_ID_1', 'SPREADSHEET_ID_2'];
const dataRages = ['RANGE_1', 'RANGE_2'];
const ar = spreadsheetIds.reduce((acc, spreadsheetId, i) => {
const data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRages[i]).values;
return acc.concat(data.filter(f => f.includes(searchText)));
}, []);
return ar;
}
Reference:
Array.prototype.reduce()

Code to show locally stored CSV file in a webpage using HTML & AJAX jquery NOT Working

Here is my index.html for the code. The following code is showing up in the browser only till the button extent. After that, it's not working the way it should be.
It should load the whole CSV file which is stored in the same folder as index.html and show it in the webpage. I can't identify the issue with it. Need help with this. Thank you.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="table-responsive">
<h1 align="center">CSV File to HTML Table</h1><br />
<div align="center">
<button type="button" name="load_data" id="load_data" class="btn btn-info">Load Data</button>
</div><br />
<div id="employee_table"></div>
</div>
</div>
$(document).ready(function() {
$('#load_data').click(function() {
$.ajax({
url: "FGExport - LEVI.csv",
dataType: "text",
success: function(data) {
var employee_data = data.split(/\r?\n|\r/);
var table_data = '<table class="table table-bordered table-striped">';
for (var count = 0; count < employee_data.length; count++) {
var cell_data = employee_data[count].split(",");
table_data += '<tr>';
for (var cell_count = 0; cell_count < cell_data.length; cell_count++) {
if (count === 0) {
table_data += '<th>' + cell_data[cell_count] + '</th>';
} else {
table_data += '<td>' + cell_data[cell_count] + '</td>';
}
}
table_data += '</tr>';
}
table_data += '</table>';
$('#employee_table').html(table_data);
}
});
});
});