I am creating a web app using Google Apps Script. So this app basically is meant to send quotations to user by collecting various parameters. The deployment has 3 views. The first asks for Email and Plant Type. The second view asks for 4 parameters. The third view shows recommendation after some processing on server side along with other 2 inputs.
The problem is that I have to append a row after the submit button is clicked on the third view. So that a new row is created in my linked google sheets as a database with all the inputs from user. The script was running fine when there was 1 view. But as I made 3 views, it's now not appending a new row in google sheets.
The Object "Info" is where I am storing inputs from user.
Here's the script:
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
var Info = {};
document.getElementById("btn1").addEventListener("click",dothis);
function dothis(){
Info.email = document.getElementById("email").value;
Info.ptype = document.getElementById("ptype").value;
}
document.getElementById("btn2").addEventListener("click",thenthis);
function thenthis(){
Info.quantity = document.getElementById("quantity").value;
Info.hotwt = document.getElementById("hotwt").value;
Info.coldwt = document.getElementById("coldwt").value;
Info.wetbt = document.getElementById("wetbt").value;
}
document.getElementById("submit").addEventListener("click",andthenthis);
function andthenthis(){
Info.recomcell = document.getElementById("recomcell").value;
Info.prefercells = document.getElementById("prefercells").value;
Info.coc = document.getElementById("coc").value;
google.script.run.UserClicked(Info);
document.getElementById("recomcell").value = "";
M.updateTextFields();
var mycoc = document.getElementById("coc");
mycoc.selectedIndex = 0;
M.FormSelect.init(mycoc);
var myprefercells = document.getElementById("prefercells");
myprefercells.selectedIndex = 0;
M.FormSelect.init(myprefercells);
}
</script>
Here's the other part of the code:
function UserClicked(Info){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Database");
ws.appendRow([Info.email,Info.ptype,Info.quantity,Info.hotwt,Info.coldwt,Info.wetbt,Info.recomcell,Info.prefercells,Info.coc,new Date()]);
}
Related
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.
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)
I have created a Html form with file input field and multiple attribute activated
<input type="file" name="documents" multiple size="11">
This is the function that submits the form object to client side function
<script>
function handleFormSubmit(formObject) {
var div = document.getElementById('output');
var docs = document.getElementById('myFile');
var firstName = document.getElementById('first').value;
var lastName = document.getElementById('last').value;
var hid = document.getElementById("hidden");
for(i=0;i< docs.files.length ; i++){
div.innerHTML = hid+hid.file+"<h3>Please do not refresh or close the page. Your files are uploading...</h3>";
google.script.run.withSuccessHandler(update).uploadFile(formObject);
docs
}
</script>
This is the client side function implemented
function uploadFile(formObject) {
Logger.log("called");
var firstName=formObject.firstName;
var lastName=formObject.lastName;
var file = formObject.documents;
Logger.log(file);
var root = DriveApp.getRootFolder();
var folder,url;
if(root.getFoldersByName("Application Documents - Clients").hasNext()){
folder = root.getFoldersByName("Application Documents - Clients").next();
} else{
folder = root.createFolder("Application Documents - Clients");
}
if(folder.getFoldersByName(firstName+" "+lastName).hasNext()){
url = folder.getFoldersByName(firstName+" "+lastName).next().createFile(file).getUrl();
} else {
url = folder.createFolder(firstName+" "+lastName).createFile(file).getUrl();
}
return url;
}
The output is, I am getting only the first file uploaded thrice if the total file uploads are 3.
Means its just uploading the first file selected at the time of form submission.
I want to get all selected files uploaded to my drive on the same folder.
Thanks in advance
Using Google Apps Script, I have the following code that automatically sorts a table whenever I edit information in the table.
function onEdit(event){
var sheet = event.source.getActiveSheet();
var columnToSortBy = 3;
var tableRange = "A3:AQ11";
var range = sheet.getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: false } );
}
However, my entire table is populated by formulas that reference different sheets, and if I change a value in a different sheet, the tables values on the first sheet change, but it does not get sorted b/c the event did not occur on that sheet.
Is there a way to add functionality to sort the table whenever information in the table changes, rather than a manual edit to the table? I have looked into the onChange() event, but not sure how exactly it could be used.
onChange docs has an example:
From : https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("myFunction")
.forSpreadsheet(sheet)
.onChange()
.create();
how to add triggers: From http://www.labnol.org/internet/google-docs-email-form/20884/
/* Send Google Form Data by Email v3.0 */
/* Source: http://labnol.org/?p=20884 */
/**
* #OnlyCurrentDoc
*/
function Initialize() {
var triggers = ScriptApp.getProjectTriggers();
for (var i in triggers)
ScriptApp.deleteTrigger(triggers[i]);
ScriptApp.newTrigger("SendGoogleForm")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit().create();
}
function SendGoogleForm(e) {
if (MailApp.getRemainingDailyQuota() < 1) return;
// You may replace this with another email address
var email = "hello#ctrlq.org";
// Enter your subject for Google Form email notifications
var subject = "Google Form Submitted";
var s = SpreadsheetApp.getActiveSheet();
var columns = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0];
var message = "";
// Only include form fields that are not blank
for (var keys in columns) {
var key = columns[keys];
if (e.namedValues[key] && (e.namedValues[key] !== "")) {
message += key + ' :: ' + e.namedValues[key] + "\n\n";
}
}
MailApp.sendEmail(email, subject, message);
}
/* For support, contact the develop at www.ctrlq.org */
Go to the Run menu and choose Initialize. The Google Script will now require you to authorize the script – just click the Accept button and you’re done.
Or you can use an onOpen function to auto add, I think "FormEmailer" includes and example of how.
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);
});