Search match to autofill text inputs google sheets - google-apps-script

i'm trying to do a match and return function: search barcode and a size value in a sheet, and add it to a textbox in a sidebar
something went wrong - script do not return any values
var barcodeBox = document.getElementById("bcdn");
var typeBox = document.getElementById("stype");
var sizeBox = document.getElementById("size");
document.getElementById("butn").addEventListener("click",addRecord);
document.getElementById("bcdn").addEventListener("input",getStype);
function getStype(){
var bCode = document.getElementById("bcdn").value;
if(bCode.length === 10){
google.script.run.withSuccessHandler(updateSize).getSize(bCode);
}else{
document.getElementById("size").value = "-";
M.updateTextFields();
} // end Else
} // end getStype
function updateSize(size){
document.getElementById("size").value = size;
M.updateTextFields();
}
this is gs code
function getSize(bCode){
var ws = SpreadsheetApp.getSheetByName("Barcode List");
var data = ws.getRange(1,1,ws.getLastRow(),2).getValues();
var bCodeList = data.map(function(r){return[0];});
var sizeList = data.map(function(r){return[1];});
var position = bCodeList.indexOf(bCode);
if(position > -1){
return sizeList[position].toFixed(2);
}else{
return "";
}

bCode seems to be just a value but bCodeList is an array of arrays so bCodeList.indexOf(bCode) is probably always going to be -1
Maybe change this var bCodeList = data.map(function(r){return[0];});
to this var bCodeList = data.map(r => 0);
Of course sizeList has the same problem

Missing get spreadsheet
Wrong return of map
Not converting [][] into [] for indexOf
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Barcode List");
var data = ws.getRange(1,1,ws.getLastRow(),2).getValues();
var bCodeList = data.map(function(r){return r[0];}).flat();
var sizeList = data.map(function(r){return r[1];}).flat();

Related

Unable to get my script to return ContentService

Let me just preface this with I know this script could probably be better but I'm very new to scripting in any language and I'm just playing around with an idea for work. This is essentially just a frankensteined combination of google results for what I want to accomplish but I've hit a deadend.
I'm using an aspect from another script to return contentservice in JSON format for a webapp except it's not working in this case
As far as I can tell it should work perfectly fine and if I replace the return contentservice with the browser.msgbox below I get the values returned that I want but when using contentservice and going to my scripts Web App URL with the action pointing to range I get the error The script completed but did not return anything.
var mysheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1sPuqdg0Va9LLQudl2ta23b-CGEF_-FFSTeggRw3J4L4/edit").getSheetByName('Sheet3');
var sheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1sPuqdg0Va9LLQudl2ta23b-CGEF_-FFSTeggRw3J4L4/edit").getSheetByName('Sheet1');
function doGet(e){
var action = e.parameter.action;
if(action == 'Range'){
return Range(e);
}
}
function Range(e) {
let term = 'Customer 6';
var sdata = mysheet.getRange("A:A").getValues();
sdata.forEach((val, index) => {
if(val == term){
var msgr = "B" + (index+1)
var msgc = "D" + (index+1)
var rrow = mysheet.getRange(msgr).getValue();
var ccol = mysheet.getRange(msgc).getValue();
var data = sheet.getRange("E" + rrow + ":I"+ccol);
var records={};
var rows = sheet.getRange("E" + rrow + ":I"+ccol).getValues();
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
record['Product'] = row[0];
record['Case']=row[2];
record['Order QTY']=row[3];
record['Packed']=row[4];
data.push(record);
}
records.items = data;
var result=JSON.stringify(records);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
// Browser.msgBox(result);
}})}
I can't figure out why I'm getting the correct returned values for the msgBox, but no results for the ContentService.
Any help would be greatly appreciated. Thanks in advance.
Edit: I have been publishing new webapp versions every revision
This breaks because you're returning from within a forEach() loop. Check out the MDN web docs:
There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.
The simplest fix is to use a for loop instead.
function Range(e) {
let term = 'Customer 6';
var sdata = mysheet.getRange("A:A").getValues();
for (var index = 0; index < sdata.length; index++) {
var val = sdata[index];
if(val == term){
var msgr = "B" + (index+1)
var msgc = "D" + (index+1)
var rrow = mysheet.getRange(msgr).getValue();
var ccol = mysheet.getRange(msgc).getValue();
var data = sheet.getRange("E" + rrow + ":I"+ccol);
var records={};
var rows = sheet.getRange("E" + rrow + ":I"+ccol).getValues();
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
record['Product'] = row[0];
record['Case']=row[2];
record['Order QTY']=row[3];
record['Packed']=row[4];
data.push(record);
}
records.items = data;
var result=JSON.stringify(records);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
}
}

Creating a list of formID's to be included in one code

I have 18 google forms I am working with.
I have written a code that does exactly what I want it to do for the very first form.
How can I make a formID List within my code that will update all 18 google forms without copy and pasting the code 18 times and changing the form ID for each?
In the code below, X is always going to be the same spreadsheet, while Y is where I would like to have a list of multiple forms.
var ssID = "X";
var formID = "Y";
var wsTeamNames = SpreadsheetApp.openById(ssID).getSheetByName("Team Names");
var form = FormApp.openById(formID);
function main(){
var labels = wsTeamNames.getRange(1,2, 28,1).getValues()[0];
labels.forEach(function(label,i){
var options = wsTeamNames
.getRange(4,2,28,1)
.getValues()
.map(function(o){return o[0] })
.filter(function(o){ return o !== "" });
updateDropDownUsingTitle(label,options)
});
}
function updateDropDownUsingTitle(title,values) {
var items = form.getItems();
var titles = items.map(function(item){
return item.getTitle();
});
var pos = titles.indexOf(title);
var item = items[pos];
var itemID = item.getId();
updateDropdown(itemID,values);
}
function updateDropdown(id,values) {
var item = form.getItemById(id);
item.asListItem().setChoiceValues(values);
}
You can use FormApp.openById to update all forms, e.g.
function updateForms() {
var formIds = ['id1','id2','id3'];
formIds.map(function(formId)){
var form = FormApp.openById(formId);
/* Here comes the code to update form */
})
}
For your particular case after edit, it should be like
var ssID = "X";
var formIDS = ['id1','id2','id3'];
var wsTeamNames = SpreadsheetApp.openById(ssID).getSheetByName("Team Names");
formIds.map(function(formId)){
var form = FormApp.openById(formId);
main()
})

How to get e.parameter.array() in doGet(e) funtion in Google app script while submitting an array via HTML Form

I am trying to submit Html form with an array to google app script webapp but unable to retrieve array into the app.
here the html form code
function onOpen(){
SpreadsheetApp.getUi().createMenu("Send Mail").addItem("Insurance Mail", "insuranceMail").addToUi();
}
function insuranceMail(){
var webApp = "https://script.google.com/macros/s/AKfycbwsAlL2GWySwmkGooucVmDXTJK60TLAcAgQWYAdxGumgdI2Kjs/exec";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var row = sh.getActiveRange().getRow();
var clientName = sh.getRange("A"+row).getDisplayValue();
var senderID = Session.getActiveUser().getEmail();
var clientID = sh.getRange("B"+row).getDisplayValue();
var senderName = sh.getRange("C"+row).getDisplayValue();
var namesOfIns = sh.getRange("D"+row).getDisplayValue().replace(/,/g,"<br>"); //Next Line Formatting
var sub= "Additional Credentialing Options";
var message = "";
var date = new Date();
var iSheet = ss.getSheetByName("Insurances");
var iLastRow = iSheet.getLastRow();
var insurances = [];
var plan = [];
var values = [];
var tableRows = [];
var j,count = 1,tableRow;
for(var i = 0;i<=iLastRow;i++){
j=i+2;
insurances[i] = iSheet.getRange("A"+j).getDisplayValue(); //Get Insurance Names
}
for(var i = 0;i<=iLastRow;i++){
j=i+2;
plan[i] = iSheet.getRange("B"+j).getDisplayValue(); //Get Plan Names
}
for(var i = 0;i<=iLastRow;i++){
j=i+2;
values[i] = iSheet.getRange("C"+j).getDisplayValue(); // Get Yes/No values
}
var messageHtmlTop = "<!DOCTYPE html><html><head>"
+"<style> table{font-size:11px;font-family:sans-serif;} tr,td {padding: 0px 0px 0px 0px;text-align:center;}</style></head>"
+"<body>"
+"Hello "+clientName+",<br><br>"
+"<br><br>"
+"Some Html"
+"<b>"+namesOfIns+"</b><br><br>";
var messageHtmlTop2 = "<form action ='"+webApp+"'method='GET'><input type='email' name='clientID' value='"+clientID+"' style='display: none'><input type='text' name='clientName' value='"+clientName+"' style='display: none'>"
+"<table><tr><th>Sr. No.</th><th>Select</th><th>Insurance</th><th>Plane</th></tr>";
var messageHtmlMid = "";
for(n in insurances){
if(values[n] == "Yes" || values[n] == "yes"){
tableRow ="<tr>"
+"<td>"+count+"</td>"
+"<td><input type='checkbox' name='insurances[]' value='"+insurances[n]+"'></td>"
+"<td>"+insurances[n]+"</td>"
+"<td>"+plan[n]+"</td>"
+"</tr>";
tableRows[n] = tableRow;
count++;
} // Creat table rows array
} //Add Form top to the HTML on if atleast 1 Yes is present
for(n in tableRows){
messageHtmlMid = messageHtmlMid.concat(tableRows[n]); //Compose HTML Form Mid Part
};
var messageHtmlBottom1 ="<tr></tr><tr><td></td><td></td><td><input type='submit' value='Send' width=100% hieght=40px></td></tr></table>"
+"</form><br><br>"
+"some sentence<br><br>"
var messageHtmlBottom ="some HTML"
+"</body>"
+"</html>";
for(n in values){
if (values[n] == 'Yes'){
messageHtmlTop = messageHtmlTop.concat(messageHtmlTop2);
messageHtmlBottom = messageHtmlBottom1.concat(messageHtmlBottom);
break;
}
} ////Add Form bottom to the HTML on if atleast 1 Yes is present
var messageHtml = messageHtmlTop.concat(messageHtmlMid).concat(messageHtmlBottom); //Compose Full HTML with Form
Logger.log(messageHtml);
try{
MailApp.sendEmail(clientID,sub,message,{'htmlBody':messageHtml});
sh.getRange("E"+row).setValue("Sent");
} catch(e){
sh.getRange("E"+row).setValue("Error");
}
sh.getRange("F"+row).setValue(date);
}
Here my webapp code i am trying to work which is giving me empty result.
function doGet(e) {
var name = e.parameter.clientName;
var id = e.parameter.clientID;
var date = new Date();
var iSheet = SpreadsheetApp.openById("ID").getSheetByName("Responses");
var lastRow = iSheet.getLastRow();
var getIns =[];
var insurances = "";
for(n in e.parameter.insurances){
getIns[n] = e.parameter.insurances[n];
}
for(n in getIns){
insurances = insurances.concat(getIns[n]+"\n");
}
lastRow++;
iSheet.getRange("A"+lastRow).setValue(name);
iSheet.getRange("B"+lastRow).setValue(id);
iSheet.getRange("C"+lastRow).setValue(insurances);
iSheet.getRange("D"+lastRow).setValue(date);
return ContentService.createTextOutput('Some Sentence').setMimeType(ContentService.MimeType.TEXT)
}
I am getting client name,client ID,date printed into the sheet but the Column C is coming empty
There are two reasons you get an empty entry into the spreadsheet.
In the form, checkboxes are named as insurances[]. However, in the web app you refer to them as just insurances. So, please modify your Html so that the checkboxes are named 'insurances'
+"<td><input type='checkbox' name='insurances' value='"+insurances[n]+"'></td>"
As mentioned in the documentation here . The e.parameter only retrieves the first key:value pair
An object of key/value pairs that correspond to the request parameters. Only the first value is returned for parameters that have multiple values.
Instead, use e.parameters. Note the 's' at the end, it will return an array of checkbox values that were checked. As mentioned in the documentation above.
So instead of the following:
for(n in e.parameter.insurances){
getIns[n] = e.parameter.insurances[n];
}
for(n in getIns){
insurances = insurances.concat(getIns[n]+"\n");
}
you can just do this
var insurances = e.parameters.insurances.join("\n")
Your final web app would be the following:
function doGet(e) {
var name = e.parameter.clientName;
var id = e.parameter.clientID;
var date = new Date();
var iSheet = SpreadsheetApp.openById("ID").getSheetByName("Responses");
var lastRow = iSheet.getLastRow();
var getIns =[];
var insurances = e.parameters.insurances.join("\n")
lastRow++;
iSheet.getRange("A"+lastRow).setValue(name);
iSheet.getRange("B"+lastRow).setValue(id);
iSheet.getRange("C"+lastRow).setValue(insurances);
iSheet.getRange("D"+lastRow).setValue(date);
return ContentService.createTextOutput('We have received your request').setMimeType(ContentService.MimeType.TEXT)
}
Final note: Make sure to update your web app and redeploy.
References:
join()

optimizing code and how to take selected region of active spreadsheet as input-google docs

I have written script for changing a format like 12.4/12/12.03 into 12:40:00/12:00:00/12:03:00
Here's the code:
function myFunction() {
var sheet=SpreadsheetApp.getActiveSheet();
var rows= sheet.getDataRange();
var numRows=rows.getNumRows();
var values=rows.getValues()
var column = [];
var p = 0;
var k = "H";
for (var i=0;i<numRows;i++) {
// var cell =
//Split the string a the .
var string = values[i][7].split(".");
string[0] = string[0].toString();
p = i+1;
k = "H"+p;
var cell = sheet.getRange(k);
if(string[1]){
string[1] = string[1].toString();
// if the second part is like 4 in 12.4 you set it to 40
if(string[1]!=0) {
if (string[1].length == 1 )
{ string[1] += "0";}
}
// Set the row value to the format you like, here : 12:40:00/12:40
var changed_format = string[0] + ":" + string[1] + ":00";
values[i][7]=changed_format;
p = i+1;
k = "H"+p;
cell.setValue(changed_format);
}
else {
var changed_format = values[i][7]+":00:00";
cell.setValue(changed_format);
}
}
In the above code, I have mentioned columns...i.e., I have to run this script for each column...every time... ex: values[i][7] k="H"+p for 8th column. So, can anyone plz tell me how to do...all at a time...and if possible reduce my code..(optimize)..and also..if is it possible to do like this : if I select the column in the spreadsheet and the changes done by the script applies to that selected region...I mean I want my script to take the selected region as input...is it possible to do..if how.?
One key to optimize your code is to reduce the number of calls to Google services and try getting them done using JavaScript. Here is an optimized version that you could use.
Note that I havent tested it - so if you come across minor syntax errors, feel free to fix them or give a shout if you cannot fix them.
function myFunction() {
var sheet=SpreadsheetApp.getActiveSheet();
var rows= sheet.getDataRange();
var values=rows.getValues();
var COL_H = 8;
var numRows=values.length ; // Length of array = nuymRows. rows.getNumRows();
var column = [];
//var p = 0;
//var k = "H";
var destArray = new Array();
for (var i=0;i<numRows;i++) {
// var cell =
//Split the string a the .
var string = values[i][7].split(".");
string[0] = string[0].toString();
//p = i+1;
//k = "H"+p;
//var cell = sheet.getRange(k);
if(string[1]){
string[1] = string[1].toString();
// if the second part is like 4 in 12.4 you set it to 40
if(string[1]!=0) {
if (string[1].length == 1 )
{ string[1] += "0";}
}
// Set the row value to the format you like, here : 12:40:00/12:40
var changed_format = string[0] + ":" + string[1] + ":00";
//values[i][7]=changed_format;
//p = i+1;
//k = "H"+p;
//cell.setValue(changed_format);
destArray.push([changed_format]);
}
else {
var changed_format = values[i][7]+":00:00";
//values [i][7] = changed_format;
//cell.setValue(changed_format);
destArray.push([changed_format]);
}
}
var destRange = sheet.getRange(1, COL_H, destArray.length, 1);
destRange.setValues(values);
}
TIP: Putting formatted code in the question helps readability

I need to get the input value (True/False) of a checkbox when a button is pressed

I want to get the input value (true/false) of a checkbox with .setName(chk_id), when id is the id of the row which i have introduced in flexTable cell bycell.
But i always get "e.parameter_"undefined"" becouse e.parameter.chk_i is "undefined"
var flexTableReg = app.createFlexTable().setId("flexTableReg").setBorderWidth(1);
var check = new Array(lastRow);
for(var r = 0; r < lastRow; r++){
for(var c = 0; c < lastCol; c++){
var text = rowsToConfirm[r][c].toString();//HERE IS THE CELL
flexTableReg.setText(r+1, c, text);
}
var id = rowsToConfirm[r][0];
check[r] = app.createCheckBox().setName("chk_"+id).setId("chk_"+id);
flexTableReg.setWidget(r+1, lastCol, check[r]);
}//end fors
}//end if
var botMod = app.createButton().setText("Activar").setId("botStatus");
var botHandle = app.createServerHandler("changeStatus").addCallbackElement(verticalPanelAdmin);
botMod.addClickHandler(botHandle);
mainPanelAdmin.add(flexTableReg);
mainPanelAdmin.add(botMod);
verticalPanelAdmin.add(mainPanelAdmin);
absolutePanelAdmin.add(verticalPanelAdmin);
app.add(absolutePanelAdmin);
return app;
}
function changeStatus(e){
var ss = SpreadsheetApp.openById(LOGS_SHEET_ID);
var app = UiApp.getActiveApplication();
var datarray = getDataArray();
var lastRow = ss.getLastRow();
for(var i =0; i<=lastRow;i++ ){
try{
var par = e.parameter["chk_"+i];
if(true){
stop_if_true
var row = getRowByID(0,lastRow,i);
ss.getRange("E"+i).setValue("1");
}//end if
}catch(e){e.parameter_"undefined" //if e.parameter "undefined"
return app;}
}//end for
return app;
};
I don't know what var id = rowsToConfirm[r][0]; is returning, but that is what you're using as the original id parameter when setting the .setName() and .setId() properties.
When you try to get the values in the callback function you use a numeric i param so that could clash.
Second, the return value of a checkbox is always a string so check for 'true' or 'false' instead of true or false.
hope this helps,
Greets.