Get user input in Webapp and display some rows in HTML - javascript

I have a sheet with ticket number, call date, customer mobile no, customer name
I want to take the user input (Ticket number) in a Webapp.
From that, I will find the customer mobile number in the table.
From the customer mobile number, I want to display all the matching rows (in the same table) to the user in HTML. I want to display all the calls made by the customer (he could have made many calls before)
I referred to
How to search and filter a Google Sheet based on two parameters in two different columns
and Tried
code.gs
function doGet() {
return HtmlService.createTemplateFromFile('index').evaluate();
}
//
function getValuesFromSS(search) {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1zObr0he1SYJkOXMMyFrOWk-0OtV6w/edit#gid=926906658")//service calls
var calsht=ss.getSheetByName('Calls');
//var lastRow = calsht.getLastRow();
var arange = calsht.getRange("A:D").getValues();
for (m= arange.length-1; m>0; m--){
if (arange[m][0]==search.name){//search.name
var cusmob=arange[m][3];
//Logger.log(m);
//Logger.log(cusmob);
}
}
var names = '';
var techs = '';
var eqips = '';
var urls = '';
var lastCol = calsht.getLastColumn();
for (m= arange.length-1; m>0; m--){
if (arange[m][3]==cusmob){
var values = calsht.getRange("A"+(m+1)+":AL"+(m+1)).getValues(); //get all values for the row
var name = values[0][4]; //column E
var tech = values[0][5]; //column F
var eqip = values[0][14]; //column O
var url = values[0][37]; // AL
//Logger.log(url);
names+=Utilities.formatString("<td>" + name + "</td>");
techs+=Utilities.formatString("<td>" + tech + "</td>");
eqips+=Utilities.formatString("<td>" + eqip + "</td>");
urls+=Utilities.formatString('<td>' + 'Inv' + '</td>');
}//if
}//for
return {
first: names,
second: techs,
third: eqips,
fourth: urls
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
function setPageValues () {
var search = document.getElementsByName('searchtext')[0].value;
var obj = {};
if (!search) alert("Ticket No is required");
if (search) {
obj.name = search;
}
google.script.run.withSuccessHandler(disp).getValuesFromSS(obj);
}
function disp(values){
document.getElementById("results1").innerHTML = values.first;
document.getElementById("results2").innerHTML = values.second;
document.getElementById("results3").innerHTML = values.third;
document.getElementById("results4").innerHTML = values.fourth;
}
</script>
</head>
<style>
table {
border-collapse: collapse;
}
tr {
display: block;
float: left;
}
td {
border: 1px solid Black;
display: block;
}
</style>
<body>
<input type="text" name="searchtext">
<input type="button" value="Search" onclick="setPageValues();">
<br>
<div name="resultbox">
<table>
<tr id="results1">
</tr>
<tr id="results2">
</tr>
<tr id="results3">
</tr>
<tr id="results4">
</tr>
</table>
</div>
</body>
<script>
</script>
</html>
Now it seems to be working.
I changed from findall to for loop.

Take a look at google.script.run
you can display your results with the withSuccessHandler

Related

Trying to add data from a sheet in a table in html using app script [duplicate]

This question already has answers here:
Google script - using template to build table
(1 answer)
Passing variable to HTML output and then into a scriptlet
(1 answer)
Closed 2 years ago.
I have data in a sheet in this format which has to be presented in a tabular form inside an HTML Page
I am using Google App Script for achieving the same. The below code is for trying out this option and if this works, I will fit the code into my original HTML Page.
All other things are working fine except the excel data is not coming into the HTML page. I am able to form the table equal to the length of the data but the information inside it is not coming. I have checked the javascript code independently and the data is being fetched to the code, but it is not appearing in the HTML Code.
I have written the following HTML code
<!DOCTYPE HTML>
<HTML>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
</head>
<body>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
<? for (var i=0; i<defintion_s_no.length;i++) {?>
<tr>
<th><?defintion_s_no[i]; ?></th>
<th> 1 </th>
</tr>
<? }?>
</table>
</body>
</html>
and the following javascript code for the same
var url = 'https://docs.google.com/spreadsheets/d/1CGZVG6NGAy325wgCz-dS6ZjJ_it5ShzLshIdD-CCpqs/edit';
function doGet(e){
return definition();
}
function defintion() {
var ss = SpreadsheetApp.openByUrl(url);
var webAppSheet = ss.getSheetByName("Datafeed");
var defintion_s_no = data_till_lastrow_coulmn("Description");
var tmp = HtmlService.createTemplateFromFile('try');
tmp.defintion_s_no = defintion_s_no.map(function(r){ return r[0]; });
return tmp.evaluate().setTitle('Daily Task Updater');
}
function data_till_lastrow_coulmn(key) {
//get the data till the last row of a specified column using the key to find the header of the column
var ss = SpreadsheetApp.openByUrl(url);
var webAppSheet = ss.getSheetByName("Datafeed");
var last_row = webAppSheet.getLastRow();
var header_values = webAppSheet.getRange(1,1,1,15).getValues()[0];
var dropdown_column = 0;
//find the column of the "key" in the header row
for (var i=0; i<15; i++){
if(header_values[i]==key){
dropdown_column = i+1;
}
}
//finding the last row in the column containing key as the header
var workstream_Values = webAppSheet.getRange(2,dropdown_column,last_row,1).getValues();
var dropdown_lastrow = 0;
var blank = false;
for (var i=0;i<last_row;i++){
if(workstream_Values[i+1]==""&& !blank){
dropdown_lastrow = i+1;
blank = true;
break;
}
else if(workstream_Values[i] != ""){
blank = false;
}
}
return webAppSheet.getRange(2,dropdown_column,dropdown_lastrow,1).getValues();
}
I am unable to see the data here

csv does not seem to appear due to reference error

I am quite new to this all, so i am pretty sure this is a simple oversight on my part, but i cant get it to run.
When i deploy the code below and click on the button, it does not do anything. When i inspect the html in my browser, it says "userCodeAppPanel:1 Uncaught ReferenceError: csvHTML is not defined
at HTMLInputElement.onclick"
When i run the function csvHTML from Code.gs, I can see the expected results in my Logger.log, so it seems the problem does not lie in my code.gs
What i am trying to achieve is showing the csv results in html. When all works fine, i will want to work with the data in some other way.
Attached below is my code.
Index.html:
<!DOCTYPE html>
<!-- styles -->
<?!= HtmlService.createHtmlOutputFromFile("styles.css").getContent(); ?>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<?!= HtmlService.createHtmlOutputFromFile("chart.js").getContent() ?>
<?!= HtmlService.createHtmlOutputFromFile("main.js").getContent() ?>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
and Code.gs:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fecth Data and make a csv output.
function csvHTML()
{
var query = "{ 'query': 'SELECT * FROM `<some table>` limit 1000;', 'useLegacySql': false }";
var job = BigQuery.Jobs.query(query, <projectName>);
var json = JSON.parse(job);
var tabel = json2csv(json);
Logger.log(tabel)
return tabel;
}
function json2csv(json, classes) {
var headerRow = '';
var bodyRows = '';
classes = classes || '';
json.schema.fields.forEach(function(col){
headerRow +=col.name+",";
})
json.rows.forEach(function(row){
row.f.forEach(function(cell){
bodyRows +=cell.v+",";
})
})
return headerRow + bodyRows }
So thanks to the suggestions by TheMaster, i rewritten it into the following:
index.html:
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
<!DOCTYPE html>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
Code.gs has not been modified.
It appears that the <?!= htmlService.createHtmlOutputFromFile("styles.css").getContent(); ?> and other createHtmlOutputFromFile were getting in the way. Eventually i need these, but I will figure out how to incorporate that at a later stage.
Thanks for all the advice and help!
Disclaimer: I have zero experience with Google Apps Script, so take this with a grain of salt.
Looking at their documentation for BigQuery, it seems you are not querying the database correctly. I am surprised by your claim that Logger.log() shows the correct output. It does not appear that it should work.
In case I am right, here is what I propose you change your Code.gs file to:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fetch Data and make a csv output.
function csvHTML() {
var results = runQuery('SELECT * FROM `<some table>` limit 1000;');
var tabel = toCSV(results);
Logger.log(tabel);
return tabel;
}
/**
* Runs a BigQuery query and logs the results in a spreadsheet.
*/
function runQuery(sql) {
// Replace this value with the project ID listed in the Google
// Cloud Platform project.
var projectId = 'XXXXXXXX';
var request = {
query: sql,
useLegacySQL: false
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
var fields = queryResults.schema.fields.map(function(field) {
return field.name;
});
var data = [];
if (rows) {
data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
}
return {
fields: fields,
rows: rows
};
}
function toCSV(results) {
var headerRow = results.fields.join(',');
var bodyRows = results.rows.map(function(rowData) {
return rowData.map(function(value) {
// for proper CSV format, if the value contains a ",
// we need to escape it and surround it with double quotes.
if (typeof value === 'string' && value.indexOf('"') > -1) {
return '"' + value.replace(/"/g, '\\"') + '"';
}
return value;
});
})
.join('\n'); // join the lines together with newline characters
return headerRow + '\n' + bodyRows;
}
Reminder: I have not tested this, I'm purely writing this based on my knowledge of Javascript and their documentation and sample code.

Can I make a button that will add a column to my table with the sales commission calculated

I am working on a school project, and I need to create a program that will calculate the commission of our companies employees. So far I have a place where I can upload a data file and put it into a table. I want to add a button that will calculate the sales commission for each employee and add a new column to the table with the calculated sales commission.
data file:
Name,Sales,Commission,Region
Billy Bradshaw,$33611,20%,North
Twanna Beagle,$44250,20%,East
Gloria Saling,$49278,20%,West
Theola Spargo,$75021,20%,South
Giovanni Armas,$59821,20%,East
Cristal Smith,$44597,20%,West
Ashley Morris,$55597,20%,North
Tiffaney Kreps,$40728,20%,South
Arnold Fultz,$49674,20%,East
Sherman Sallee,$23780,20%,North
Shawana Johnson,$58365,20%,West
Kathrine Mosca,$67489,20%,North
Karren Mahmoud,$53382,20%,East
Venus Grasser,$33572,20%,West
Rickey Jones,$28522,20%,East
Verona Strauch,$41865,20%,North
Elvis Yearta,$25314,20%,South
Jonathan Lee,$22823,20%,West
Sommer Cottle,$45660,20%,East
Elsa Laverty,$49386,20%,North
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sales Commission Calculator</title>
<h1>Sales Commission Calculator</h1>
<p>Please select the Employee Sales Database</p>
<style type="text/css">
body
{
font-family: Arial;
font-size: 10pt;
}
table
{
border: 1px solid rgb(155, 155, 155);
border-collapse: collapse;
}
tr:nth-child(even) {
background: #4ac5fd;
}
table td
{
padding: 5px;
}
</style>
</head>
<body>
<script>
function Upload() {
var fileUpload = document.getElementById("fileUpload");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].split(",");
if (cells.length > 1) {
var row = table.insertRow(-1);
for (var j = 0; j < cells.length; j++) {
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
}
}
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
}
reader.readAsText(fileUpload.files[0]);
} else {
alert("This browser does not support HTML5.");
}
} else {
alert("Please upload a valid CSV file.");
}
}
</script>
<input type="file" id="fileUpload" />
<input type="button" id="upload" value="Upload" onclick="Upload()" />
<input type="button" id="Calculate Commission" value="Calculate Commission" oneclick=""/>
<hr />
<div id="dvCSV">
</div>
</body>
</html>
Make a button that will add a column to my table with the calculates sales commission numbers.
Thanks for being up-front about it being for a school project. We've all been there, so let me walk you through it a little bit.
You need to have the button you have call a function, which you already have. Fix your typo and then assign a new function to the onclick attribute:
<input type="button" id="Calculate Commission" value="Calculate Commission" onclick="calculateCommissions()" />
Then you'll need to create that function... Ultimately, overall idea, is we want that function to look at each row (so, we'll probably want a loop, to loop over the rows in the table)... pull out that row's "sales" and "commission %" and multiply them together... then, before we let the loop move on to the next row, add that final commission score to the end of the current row.
function calculateCommissions() {
// Get an array full of the rows
// Note the use of the spread operator, we need to convert the NodeList type to an Array type
var allRows = [...document.getElementsByTagName('tr')];
// Now let's loop over that array and look at each row individually
allRows.forEach( eachRow => {
// For the current row, we need to pull out the "sales" and "commission %" values
var sales = Number(eachRow.childNodes[1].innerText.slice(1));
var percentCommission = Number(eachRow.childNodes[2].innerText.substr(0, eachRow.childNodes[2].innerText.indexOf('%')));
// Do the math...
var commission = Math.round(sales * percentCommission / 100)
// And now, we want to add that commission as an additional column
// Note that since we're also going to be looping over the header...
// ... let's add a column header "Commission"
var tableCellToAppend = document.createElement('td')
tableCellToAppend.innerText = commission ? `$${commission}` : 'Commission';
eachRow.appendChild(tableCellToAppend)
})
}
Of course in the real world project, you would need to have error handling galore. Real users never upload perfect csv files. Welcome to SO.

Javascript filter on html table does not work if it is injected to div. if table is loaded with page it works

I want to filter out table before loading it to reduce it's size that it would load faster, when its loaded i would like to let user to filter it. I am using public CDN script for filter part, but it does not work on content which is injected to . It only works if whole table is loaded together with page.. what i'am doing wrong?
Jsfilter: <script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tablefilter/2.5.0/tablefilter.js"></script>
DetailedRport.html
//this function called on button click it gets user and date to resize data set
<script type="text/javascript">
function myFunction() {
var y = document.getElementById("month-input").value;
var z = document.getElementById("email2").value;
//here is called server side script
google.script.run.withSuccessHandler(onSuccess).functionToRunOnFormSubmit(y, z);
}
//Resized data set gets injected to tbody
function onSuccess(c){
var table=toHTMLTable(c);
document.getElementById('myOutput1').innerHTML = table;
}
//Array to HTML table
function toHTMLTable(a) {
var content = a.map(function(row, i) {
var rowHTML = row.map(function (col) {
return "<td>" + col + "</td>";
}).join("");
return "<tr>" + rowHTML + "</tr>";
}).join("");
return content;
}
</script>
//user selects criteria for data table
<b> Report for:</b>
<select value="" name="email2" id="email2" width="300" autofocus="autofocus" autocorrect="off" autocomplete="off">
<?!= myEmails(); ?>
</select>
<b>Pick Period :</b>
<select name="Student" id="month-input" autofocus="autofocus" autocorrect="off" autocomplete="off">
<?!= myDates(); ?>
</select>
//On click table is loaded based on selection
<input type="button" value="Load Data" class="loadbutton" onclick="myFunction();" >
<br><br>
//Js tablefilter which should work but does not if table is injected
<table id="table1"class="mytable TF" cellspacing="0" cellpadding="0">
<thead>
<tr class="header">
<th style="width:5%;">TASK</th>
<th style="width:20%;">PROJECT</th>
<th style="width:30%;">DATE</th>
<th style="width:10%;">TIME SPENT</th>
<th style="width:10%;">WORDCOUNT</th>
<th style="width:10%;">SPEED</th>
</tr>
</thead>
//Where data table is injected
<tbody id="myOutput1">
</tbody>
</table>
//Setting Js tablefilter source http://tablefilter.free.fr/
<script language="javascript" type="text/javascript">
var tf = setFilterGrid("table1");
</script>
server.gs
// here data set gets filtered based on users selection and is sent back
// Using ArrayLib library
function functionToRunOnFormSubmit(y,z) {
var ss = SpreadsheetApp.openById(id);
var ActiveSheet = ss.getSheetByName("TogglMap");
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var EMWholeRange = ActiveSheet.getRange(StartRow,2,RowRange,13);
var AllValues = EMWholeRange.getDisplayValues();
var dat = y +'-01'
var removeCol = function(arr, colIndex, colIndex2) {
for (var i = 0; i < arr.length; i++) {
var row = arr[i];
row.splice(colIndex, colIndex2);
}
}
removeCol(AllValues, 5 , 6);
var filteredArr1 = ArrayLib.filterByText(AllValues, 1, z)
var filteredArr2 = ArrayLib.filterByText(filteredArr1, 3, dat)
removeCol(filteredArr2, 1 ,1);
Logger.log(AllValues)
return filteredArr2
};
My goal is working JS filter

How to Search Spreadsheet Using Google Visualization Query

I've got this simple webpage which uses google.visualization.Query to pull the values of three specific cells from this spreadsheet, and then sets the values of three corresponding input fields based on their unique id attributes.
google.load('visualization', '1', {'packages':['corechart']});
google.setOnLoadCallback(work);
function work() {
var queryWORK = new google.visualization.Query('https://docs.google.com/spreadsheet/ccc?key=1HpHMfoEnPgESb2XPVCgb7XyGwRAvrq3EoQj4WHj4vhA&sheet=QUERY');
queryWORK.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in ID Validation Query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var datatable = response.getDataTable();
var name = datatable.getValue(1,0);
var job = datatable.getValue(1,1);
var hours = datatable.getValue(1,2);
document.getElementById('name_out').value = name;
document.getElementById('job_out').value = job;
document.getElementById('hours_out').value = hours;
}
As it is currently, I have to "hard code" the row and column indexes for each cell I want to pull data from. How can I can get this to search through and retrieve data from the spreadsheet? What, for example, if I had a simple input field where I could enter a name and the "job" and "hours" would be returned. Is this even possible?
Thanks.
you can use Query.setQuery to set a SQL-like statement,
which can be used to select certain columns and rows
the following will select the Job & Hours columns where Name = Bill
'select B, C where A = "Bill"'
you can also search for partial text, this will select both Bill and Kim
'select B, C where A like "%i%"'
following is a working snippet, the inputs are given the same names as the Columns
enter a full or partial name and click Search to see the results...
google.charts.load('current', {
callback: function () {
document.getElementById('Search').addEventListener('click', searchSheet, false);
searchSheet();
function searchSheet() {
searchText = document.getElementById('Name').value;
var queryWORK = new google.visualization.Query('https://docs.google.com/spreadsheet/ccc?key=1HpHMfoEnPgESb2XPVCgb7XyGwRAvrq3EoQj4WHj4vhA&sheet=QUERY');
if (searchText !== '') {
queryWORK.setQuery('select B, C where A like "%' + searchText + '%"');
}
queryWORK.send(function (response) {
if (response.isError()) {
console.log('Error in ID Validation Query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var datatable = response.getDataTable();
for (var i = 0; i < datatable.getNumberOfColumns(); i++) {
document.getElementById(datatable.getColumnLabel(i)).value =
(datatable.getNumberOfRows() > 0) ? datatable.getValue(0, i) : '';
}
var chart = new google.visualization.Table(document.getElementById('table_div'));
chart.draw(datatable);
});
}
},
packages:['table']
});
div {
padding: 6px 6px 6px 6px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div><label for="Name">Enter Name: </label><input id="Name" type="text" value="Bill" /></div>
<div><input id="Search" type="button" value="Search" /></div>
<div><label for="Name">Job: </label><input id="Job" type="text" /></div>
<div><label for="Name">Hours: </label><input id="Hours" type="text" /></div>
<div id="table_div"></div>

Categories

Resources