Script google sheets form autocomplete and fill cell - javascript

I have a form with an input type "text" which has an autofill function from a list that is fed from a spreadsheet in google drive (this works fine); by selecting the desired option from the list; I want another field in the form to be filled automatically with the cell next to the right, that is, if I select the data (character string) of cell I5 with the auto-complete option, the new text field should be filled automatically with the contents of cell J5 (this does not work). The event I use does not capture the entire string of cell I5, but only the typed characters, can anyone help me?
I have this code:
//page-js.html
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("redIps").addEventListener("blur",getRegimenIps);
google.script.run.withSuccessHandler(populateRed).getRed();
});
//page-js.html
function getRegimenIps(){
var redIpsStr = document.getElementById("redIps").value;//****not capture the entire string***
google.script.run.withSuccessHandler(updateIpsReg).getIpsReg(redIpsStr);
}
//page-js.html
function updateIpsReg(regimen){
document.getElementById("redIpsReg").value = regimen;
M.updateTextFields();
}
//funcs.gs
function getRed(){ //****This works fine ****
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("listas");
var data = ws.getRange(1,9).getDataRegion().getValues();
var options = {};
data.forEach(function(v){
options[v[0]]=null;
});
return options
}
//funcs.gs
function getIpsReg(redIpsStr){ //****This does not work****
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("listas");
var data = ws.getRange(1,9,ws.getLastRow(),2).getValues();
var redIpsList = data.map(function(r){ return r[0]; });
var regList = data.map(function(r){ return r[1]; });
console.log(redIpsStr);
var position = redIpsList.indexOf(redIpsStr);
if (position > -1){
return regList[position].toFixed(2);
}else{
return 'Unavailable';
}
}//end getIpsReg(redIpsStr)

Related

Preview Email Template based on drop down, Send email once your satisfuied

in my Google Sheets app script, I currently have three template.html files and a few scripts; I'd like to create a preview email and send it to the user once he or she is satisfied; however, the event listeners that (openAI) built for me do not work; when I change the Drop Down Menu or click send Button, nothing happens and the preview does not load. When I ask the AI for help, it keeps modifying my code; My code no longer looks like the original; after a week of trying, I've realized that I need assistance with this. Here's my most recent code as of today. The AI also insisted on using Google Drive, which I declined because I have the HTML files in the app scrip sheet itself and used to obtain it with this.
This code is not used anymore, But use to work when I used it in GmailApp to get the template File Name.
var html = HtmlService.createTemplateFromFile('Proposal Template.html');
var html = HtmlService.createTemplateFromFile('Marketing Template.html');
var html = HtmlService.createTemplateFromFile('Trusted Partner Template.html');
Keep in mind that while I am not an expert in Jave or JS, I am familiar with them.
My code
function showEmailPreview() {
// Get values from the active sheet and active row
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var userEmail = sheet.getRange(row, getColIndexByName("Primary Email")).getValue();
var userFullName = sheet.getRange(row, getColIndexByName("Contact Full Name")).getValue();
var userCompanyName = sheet.getRange(row, getColIndexByName("Company Name")).getValue();
var title = sheet.getRange(row, getColIndexByName("Title")).getValue();
var company_location = sheet.getRange(row, getColIndexByName("Company Location")).getValue();
var company_phone1 = sheet.getRange(row, getColIndexByName("Company Phone 1")).getValue();
var subjectLine = "Company Proposal - " + userCompanyName;
// Create the select element
const select = `
<select id="template-select">
<option value="Proposal Template.html">Proposal Template</option>
<option value="Marketing Template.html">Marketing Template</option>
<option value="Trusted Partner Template.html">Trusted Partner Template</option>
</select>
`;
// Create the button element
const button = `<button id="send-button">Send Email</button>
<div id="preview"></div>`; //This could be a issue? The ai did not know where to place this or cut down before giving me a proper answer.
// Create an HTML output page that displays the email template, the select element, and a button to send the email
var output = HtmlService.createHtmlOutput(`
<script>
var buttonElement;
function getElementById(id) {
return document.getElementById(id);
}
function init() {
// Add a change event listener to the select element
document.getElementById('template-select').addEventListener('change', function() {
// Get the selected template file name
var templateFile = this.value;
// Read the contents of the selected file
var template = readFile(templateFile);
// Set values in the template
var html = HtmlService.createTemplate(template);
html.userFullName = userFullName;
html.userCompanyName = userCompanyName;
html.title = title;
html.company_location = company_location;
html.company_phone1 = company_phone1;
// Get the filled-in email template as a string
var emailTemplate = html.evaluate().getContent();
// Update the preview window with the selected template
document.getElementById('preview').innerHTML = emailTemplate;
});
// Add a click event listener to the button element
buttonElement = getElementById('send-button');
buttonElement.addEventListener('click', function() {
// Get the selected template file name
var templateFile = document.getElementById('template-select').value;
// Pass the selected template file name as an argument to the sendEmail function
sendEmail(templateFile);
});
}
window.onload = init;
function sendEmail(templateFile) {
// Read the contents of the selected file
var template = readFile(templateFile);
// Set values in the template
var html = HtmlService.createTemplate(template);
html.userFullName = userFullName;
html.userCompanyName = userCompanyName;
html.title = title;
html.company_location = company_location;
html.company_phone1 = company_phone1;
// Get the filled-in email template as a string
var emailTemplate = html.evaluate().getContent();
// Send the email
GmailApp.sendEmail(userEmail, subjectLine, '', {htmlBody: emailTemplate});
}
</script>
<script>
init();
</script>
${select}
${button}
`)
.setWidth(950)
.setHeight(750)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
// Display the output page in a modal dialog box
SpreadsheetApp.getUi().showModalDialog(output, 'Email Preview');
//output.evaluate();
//window.onload = init;
};
function readFile(templateFile) {
// Get the contents of the selected file
var file = DriveApp.getFilesByName(templateFile);
var contents = file.next().getBlob().getDataAsString();
return contents;
}//window.onload = init;
Results.
Here is a link for testing.
https://docs.google.com/spreadsheets/d/1gXDbtjCYfZw8kOaOMorbJ54dXyl7bh6MFM1LopTrNww/edit?usp=sharing
Its always like this when you struggle for a week and give up, And you finally post something and then you find yourself a solution. So here is the correct way of doing it.
Let's first talk about the menu. I created a file template-select-menu.gs
<form>
<label for="template">Select a template:</label><br>
<select id="template" name="template">
<option value="Proposal Template.html">Proposal Template</option>
<option value="Markting Template">Marketing Template</option>
</select>
<br><br>
<input type="button" value="Preview" onclick="google.script.run.onTemplateSelected(document.forms[0].template.value)">
</form>
then I have my preview_email.gs
function showEmailPreview() {
// Get values from the active sheet and active row
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var rate = sheet.getLastRow();
var userEmail = sheet.getRange(row, getColIndexByName("Primary Email")).getValue();
var userFullName = sheet.getRange(row, getColIndexByName("Contact Full Name")).getValue();
var userCompanyName = sheet.getRange(row, getColIndexByName("Company Name")).getValue();
var subjectLine = "Company Proposal - " + userCompanyName ;
var aliases = GmailApp.getAliases()
// Create the email template selection menu
var proposalTemplate = HtmlService.createTemplateFromFile('Proposal Template.html');
var marktingTemplate = HtmlService.createTemplateFromFile('Markting Template.html');
var selectMenu = HtmlService.createTemplateFromFile('template-select-menu.html');
var selectMenuHtml = selectMenu.evaluate().getContent();
// Create an HTML output page that displays the email template selection menu and a button to send the email
var output = HtmlService.createHtmlOutput(selectMenuHtml)
.setWidth(600)
.setHeight(450);
// Display the output page in a modal dialog box
SpreadsheetApp.getUi().showModalDialog(output, 'Email Preview');
}
/**
* This function is called when the user selects a template from the drop-down menu.
* It creates an email preview using the selected template and displays it in the modal dialog box.
*/
//var html = HtmlService.createTemplateFromFile(templateFileName);
function onTemplateSelected(templateFileName) {
// Get values from the active sheet and active row
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var rate = sheet.getLastRow();
var userEmail = sheet.getRange(row, getColIndexByName("Primary Email")).getValue();
var userFullName = sheet.getRange(row, getColIndexByName("Contact Full Name")).getValue();
var userCompanyName = sheet.getRange(row, getColIndexByName("Company Name")).getValue();
var subjectLine = "Company Proposal - " + userCompanyName ;
var aliases = GmailApp.getAliases();
// Create the email template and set values in the template
if (templateFileName == 'Proposal Template.html') {
var proposalTemplate = HtmlService.createTemplateFromFile('Proposal Template.html');
proposalTemplate.userFullName = userFullName;
proposalTemplate.userCompanyName = userCompanyName;
var template = proposalTemplate.evaluate().getContent();
} else if (templateFileName == 'Markting Template') {
var marktingTemplate = HtmlService.createTemplateFromFile('Markting Template.html');
marktingTemplate.userFullName = userFullName;
marktingTemplate.userCompanyName = userCompanyName;
var template = marktingTemplate.evaluate().getContent();
} else {
var template = selectMenuHtml;
}
// Create an HTML output page that displays the email template and a button to send the email
var selectMenu = HtmlService.createTemplateFromFile("template-select-menu.html");
var selectMenuHtml = selectMenu.evaluate().getContent();
var output = HtmlService.createHtmlOutput(template)
.setWidth(600)
.setHeight(450)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setContent(selectMenuHtml + '<br><br>' + template);
// Update the modal dialog box with the new email template
SpreadsheetApp.getUi().showModalDialog(output, 'Email Preview');
}
Now create the the 2 files "Proposal Template.html" and "Markting Template.html". When you switch and click preview the content will change.
Please note that I still need to update the email buttons. but this is a great start for me.

How to get email alerts when a cell value changes (based on Formula) on Google sheets?

I want a notification/email when a cell value in column 5 of the spreasheet changes to 'Buy' which is based on formula =IF(AND(B2>D2),"Buy","Skip"). Attachment Link provided below. The Sheet autorefreshes based on Googlefinance data.
I have tried the below script, but it triggers notification/Email only when I change the cell manually. I am not a code writer, but have managed to find below script and added some tweaks of my own.
Can somebody please help me in resolving this or provide an alternate solution?
Also script written on third Party apps will be appreciated.
function triggerOnEdit(e)
{
showMessageOnUpdate(e);
}
function showMessageOnUpdate(e)
{
var range = e.range;
SpreadsheetApp.getUi().alert("range updated " + range.getA1Notation());
}
function checkStatusIsBuy(e)
{
var range = e.range;
if(range.getColumn() <= 5 &&
range.getLastColumn() >=5 )
{
var edited_row = range.getRow();
var strongBuy = SpreadsheetApp.getActiveSheet().getRange(edited_row,5).getValue();
if(strongBuy == 'Buy')
{
return edited_row;
}
}
return 0;
}
function triggerOnEdit(e)
{
showMessageOnBuy(e);
}
function showMessageOnBuy(e)
{
var edited_row = checkStatusIsBuy(e);
if(edited_row > 0)
{
SpreadsheetApp.getUi().alert("Row # "+edited_row+"Buy!");
}
}
function sendEmailOnBuy(e)
{
var buy_row = checkStatusIsBuy(e);
if(buy_row <= 0)
{
return;
}
sendEmailByRow(buy_row);
}
function sendEmailByRow(row)
{
var values = SpreadsheetApp.getActiveSheet().getRange(row,1,row,5).getValues();
var row_values = values[0];
var mail = composeBuyEmail(row_values);
SpreadsheetApp.getUi().alert(" subject is "+mail.subject+"\n message "+mail.message);
}
function composeBuyEmail(row_values)
{
var stock_name = row_values[0];
var cmp = row_values[1];
var volume = row_values[2];
var message = "The Status has changed: "+stock_name+" "+cmp+
" Volume "+volume;
var subject = "Strong Buy "+stock_name+" "+cmp
return({message:message,subject:subject});
}
function triggerOnEdit(e)
{
sendEmailOnBuy(e);
}
var admin_email='sendemail#gmail.com';
function sendEmailByRow(row)
{
var values = SpreadsheetApp.getActiveSheet().getRange(row,1,row,5).getValues();
var row_values = values[0];
var mail = composeBuyEmail(row_values);
SpreadsheetApp.getUi().alert(" subject is "+mail.subject+"\n message "+mail.message);
[https://docs.google.com/spreadsheets/d/12k5DF8rvuKex77B8uRWpx1FoMmSNaMdGvhNEEbXKCFc/edit?usp=sharing][1]
Apps script triggers cannot be trigerred by non manual input as specified in the documentation:
Script executions and API requests do not cause triggers to run. For example, calling Range.setValue() to edit a cell does not cause the spreadsheet's onEdit trigger to run.
What you can do instead is to set up a time-based trigger that scans your column 5 at regular interval and sends you an email if a cell contains 'Buy':
function sendEmailOnUpdate() {
var range = SpreadsheetApp.getActive().getRange('E2:E').getValues();
for (i = 0; i < range.length; i++) {
var cell = range[i];
if (cell == 'Buy') {
// Send email using Gmail
}
}
}
To set the trigger, head to Triggers and select time-based:
If you don't want to receive more emails for a cell you receive an alert for, make sure to make apps script change its value once the email has been sent.

Get second, third and so on values

I have this problem here
The problem has been solved, but my question is how can I get the second value from that, or the third one. The sheet will have many tables and at some point I will need a total for each table. Also, is there any solution to automatically find the the array number which contain date row for each table (instead defining this manually). Hope my explanation make sense.
Thank you!
Kind regards,
L.E. Test file
If I understood your question correctly, instead of breaking the loop when a match to "Total" is found do whatever is needed to be done within the loop like so...
var today = toDateFormat(new Date());
var todaysColumn =
values[5].map(toDateFormat).map(Number).indexOf(+today);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1",
"dd/MM/yyyy");
for (var i=0; i<values.length; i++){
if (values[i][0]=='Total'){
nr = i;
Logger.log(nr);
var output = values[nr][todaysColumn];
// Do something with the output here I"m assuming you email it
}
}
The loop will keep going and find every "Total" and do the same thing. This answer assumes that the "Totals" are in the same column. You can get fancier with this if you only want certain tables to send and not others, but this should get you started.
I didn't quite understand the second part of your question...
"Also, is there any solution to automatically find the the array
number which contain date row for each table (instead defining this
manually). Hope my explanation make sense."
I'm guessing you want all the rows that contain "Total" in the specific column. You could instantiate a variable as an empty array like so, var totals = [];. Then instead of sending the email or whatever in the first loop you would push the row values to the array like so, totals.push(nr+1) . //adding 1 gives you the actual row number (rows count from 1 but arrays count from 0). You could then simply loop through the totals array and do whatever you wanted to do. Alternatively you could create an array of all the values instead of row numbers like totals.push(values[nr][todaysColumn]) and loop through that array. Lots of ways to solve this problem!
Ok based on our conversation below I've edited the "test" sheet and updated the code. Below are my edits
All edits have been made in your test sheet and verified working in Logger. Let me know if you have any questions.
Spreadsheet:
Added "Validation" Tab
Edited "Table" tab so the row with "Email Address" in Column A lines up with the desired lookup values (dates or categories)...this was only for the first two tables as all the others already had this criteria.
Code:
Create table/category selector...
In the editor go to File >> New >> HTMLfile
Name the file "inputHTML"
Copy and paste the following code into that file
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form class="notice_form" autocomplete="off" onsubmit="formSubmit(this)" target="hidden_iframe">
<select id="tables" onchange="hideunhideCatagory(this.value)" required></select>
<p></p>
<select id="categories" style="display:none"></select>
<hr/>
<button class="submit" type="submit">Get Total</button>
</form>
<script>
window.addEventListener('load', function() {
console.log('Page is loaded');
});
</script>
<script
src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
// The code in this function runs when the page is loaded.
$(function() {
var tableRunner = google.script.run.withSuccessHandler(buildTableList);
var catagoryRunner = google.script.run.withSuccessHandler(buildCatagoryList);
tableRunner.getTables();
catagoryRunner.getCategories();
});
function buildTableList(tables) {
var list = $('#tables');
list.empty();
list.append('<option></option>');
for (var i = 0; i < tables.length; i++) {
if(tables[i]==''){break;}
list.append('<option>' + tables[i] + '</option>');
}
}
function buildCatagoryList(categories) {
var list = $('#categories');
list.empty();
list.append('<option></option>');
for (var i = 0; i < categories.length; i++) {
if(categories[i]==''){break;}
list.append('<option>' + categories[i] + '</option>');
}
}
function hideunhideCatagory(tableValue){
var catElem = document.getElementById("categories");
if(tableValue == "Total Calls By Date" || tableValue == "Total Appointments by Date"){
catElem.style.display = "none"
document.required = false;
}else{
catElem.style.display = "block"
document.required = true;
}
}
function formSubmit(argTheFormElement) {
var table = $("select[id=tables]").val(),
catagory = $("select[id=categories]").val();
console.log(table)
google.script.run
.withSuccessHandler(google.script.host.close)
.getTotal(table,catagory);
}
</script>
</body>
<div id="hiframe" style="display:block; visibility:hidden; float:right">
<iframe name="hidden_iframe" height="0px" width="0px" ></iframe>
</div>
</html>
Edits to Code.gs file
Replace code in Code.gs with this...
//This is a simple trigger that creates the menu item in your sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Run Scripts Manually')
.addItem('Get Total','fncOpenMyDialog')
.addToUi();
}
//This function launches the dialog and is launched by the menu item
function fncOpenMyDialog() {
//Open a dialog
var htmlDlg = HtmlService.createHtmlOutputFromFile('inputHTML')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(200)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'Select table to get total for');
};
//main function called by clicking "Get Total" on the dialogue...variables are passed to this function from the formSubmit in the inputHTML javascript
function getTotal(table,catagory) {
function toDateFormat(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}
//get all values
var values = SpreadsheetApp
.openById("10pB0jDPG8HYolECQ3eg1lrOFjXQ6JRFwQ-llvdE2yuM")
.getSheetByName("Tables")
.getDataRange()
.getValues();
//declare/instantiate your variables
var tableHeaderRow, totalRow, tableFound = false;
//begin loop through column A in Tables Sheet
for (var i = 0; i<values.length; i++){
//test to see if values have already been found if so break the loop
if(tableFound == true){break;}
//check to see if value matches selected table
if (values[i][0]==table){
//start another loop immediately after the match row
for(var x=i+1; x<values.length; x++){
if(values[x][0] == "Email Address"){ //This header needs to consistantly denote the row that contains the headers
tableHeaderRow = x;
tableFound = true;
}else if(values[x][0] == "Total"){
totalRow = x;
break;
}
}
}
}
Logger.log("Header Row = "+tableHeaderRow)
Logger.log("Total Row = "+ totalRow)
var today = toDateFormat(new Date())
var columnToTotal;
if(catagory==''){
columnToTotal = values[tableHeaderRow].map(toDateFormat).map(Number).indexOf(+today);
}else{
columnToTotal = values[tableHeaderRow].indexOf(catagory);
}
var output = values[totalRow][columnToTotal];
Logger.log(output);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1", "dd/MM/yyyy");
//here is where you would put your code to do something with the output
}
/** The functions below are used by the form to populate the selects **/
function getTables(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var tabelCol = (cSheetHeader.indexOf("Tables")+1);
var tables = cSheet.getRange(2,tabelCol,cSheet.getLastRow(),1).getValues();
return tables.filter(function (elem){
return elem != "";
});
}
function getCatagories(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var catagoriesCol = (cSheetHeader.indexOf("Catagory")+1);
var catagories = cSheet.getRange(2,catagoriesCol,cSheet.getLastRow(),1).getValues();
return catagories.filter(function (elem){
return elem != "";
});
}

Using javascript Not able to disable textbox.It Immediatly enable after disabled. Can anyone give me solution?

I have One simple registration Form which is developed in C#.Net. This form also contain one Grid view which display data from database.In this,I want to disable Insert button when i select particular raw data. and i had develop this code in jquery. I used below code.
function DoStuff(lnk) {
debugger;
var grid = document.getElementById('GridView1');
var cell, row, rowIndex, cellIndex;
cell = lnk.parentNode;
row = cell.parentNode;
rowIndex = row.rowIndex;
cellIndex = cell.cellIndex;
var rowId = grid.rows[rowIndex].cells[0].textContent;
var rowname = grid.rows[rowIndex].cells[1].textContent;
var rowcontact = grid.rows[rowIndex].cells[2].innerHTML;
var rowaddress = grid.rows[rowIndex].cells[3].innerHTML;
var rowemail = grid.rows[rowIndex].cells[4].innerHTML;
var Id = document.getElementById('txt_Id');
var name = document.getElementById('txt_Name');
var contact = document.getElementById('txt_PhoneNumber');
var address = document.getElementById('txt_Address');
var email = document.getElementById('txt_EmailId');
Id.value = rowId;
name.value = rowname;
contact.value = rowcontact;
address.value = rowaddress;
email.value = rowemail;
document.getElementById('Button1').disabled = true;
};
But when i run that page it becomes disable and immediately enable automatically.....:(
Can anyone give me solution ???
You have to call this function after form is completely loaded.
Use below code to make it that happen if you are using jQuery.
$( document ).ready(function() {
DoStuff(lnk);
});

Jquery doesnt update in forms

I made the following code to replace form fields in a page that I can't edit but only manipulate. However, the code does nothing. In chrome console when I print a variable it works fine. The code is below:
//GET val from drop DROP DOWN
var office_id = FieldIDs["OfficeName"];//Gets the input id
var offices;//gets the value from the drop down
$("#FIELD_"+office_id).change(function(){
offices = $(this).val();
}).change();
//The below gets the id's of all the input fields
var address_id = FieldIDs["Address"];
var address2_id = FieldIDs["Address2"];
var city_id = FieldIDs["City"];
var state_id = FieldIDs["State"];
var zip_id = FieldIDs["Zip"];
var phone_4id = FieldIDs["Number4"];//phone
var phone_id = FieldIDs["Number1"];//fax
var pdfm4 = FieldIDs["pdfm4"];
var pdfm = FieldIDs["pdfm"];
if(offices == "SoCal Accounting"){
$('#FIELD_'+address_id).val("7421 Orangewood Avenue");
$('#FIELD_'+address2_id).val("");
$('#FIELD_'+city_id).val("Garden Grove");
$('#FIELD_'+state_id).val("CA");
$('#FIELD_'+zip_id).val("92841");
$('#FIELD_'+phone_4id).val("+1 714.901.5800");//phone
$('#FIELD_'+phone_id).val("+1 714.901.5811");//fax
}

Categories

Resources