Google Script ui.button calling prompt from other function - javascript

I have two separate scripts that are activated by buttons in a sheet. One sends an email (CALemail.js), and the other clears cells (clear.js). Both scripts prompt for confirmation before running. While the first one executes perfectly, my clear.js script first asks the prompt from CALemail and then asks the clear.js prompt before running. How can I separate them?
CALemail.js:
var ehtml =
'<body>' +
'<h2>Calendar Updated</h2>' +
'<p>You can access it by clicking here </p>' +
'</body>'
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',
ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) function CALemail() {
MailApp.sendEmail(
'example#gmail.com', // recipient
' Calendar Updated', // subject
'test', { // body
htmlBody: ehtml // advanced options
} );
} else {
}
clear.js:
function clearRange() {
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?',
ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES)
{
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}

Whether you put them in separate files or in the same file, they need to be separate functions. Unless you want the to run every time you access a function.
function testEmail(){
var ehtml = '<body><h2>Calendar Updated</h2><p>You can access it by clicking here </p></body>';
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',ui.ButtonSet.YES_NO);
if(response == ui.Button.YES) function CALemail() {
MailApp.sendEmail('example#gmail.com',' Calendar Updated','test',{htmlBody: ehtml});
}
}
function clearRange(){
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?', ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES){
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}
Note: I didn't test them nor do I care too. That's upto you.

Related

Trapping a Cancel in a JavaScript Confirm Prompt?

Something's not working this morning and I'm pretty sure it's my brain. I've got a form that tracks changes to a field under certain conditions:
-If the status = Draft, do nothing.
-If the status = Approved, prompt user to ask if they are sure they want to make the change.
-If they click 'OK', it should call the process that records the change.
-If they click 'Cancel' it should do nothing.
-If the status is anything other than draft or Approved, don't prompt but call the process that records the change.
I had the code recording changes in non-draft status, but after I added the ==true to the end of the confirm statement, everything stopped working.
var stat = $('#status').text();
var parms = just a bunch of parameters i'm passing to the url below;
if (stat=='(Draft)'){
//do nothing
}
else if (stat !== 'Approved' && stat!== '(Draft)'){
var url = webDbName + '/(CreateOTChangeRecordOnChange)?OpenAgent' + parms;
$.get(url, function(data) {
$('#tableBodyChanges').html(data);
});
}
}
else if (stat == 'Approved' && confirm('You are changing the hours on a request that has already been approved. This will send a notification to the department director. Proceed?')==true) {
var url = webDbName + '/(CreateOTChangeRecordOnChange)?OpenAgent' + parms;
$.get(url, function(data) {
$('#tableBodyChanges').html(data);
});
} else {
//do nothing });
}
It is working, but you could just ommit the == true because it already is a "if-able boolean"
if(confirm("test?")){
console.log("confirmed1");
}else {
console.log("notconfirmed1");
}
<!-- or the other way arround -->
if(!confirm("test?")){
console.log("notconfirmed2");
}else {
console.log("confirmed2");
}
<!-- it should also work the way you posted as well -->
if("foo" == "foo" && confirm("test?") == true){
console.log("confirmed3");
}else {
console.log("notconfirmed3");
}

Accessing HTML script variable from google script

I'm trying to put together a picker in google sheets.
Once a file has been uploaded to google drive, I want the url to be posted in the current cell in the spreadsheet.
This is my pickerCallback located in an html file:
var message;
function pickerCallback(data) {
var action = data[google.picker.Response.ACTION];
if (action == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var id = 'https://drive.google.com/open?id=' + doc[google.picker.Document.ID];
google.script.run.accessSpreadsheet();
} message = id;
document.getElementById('result').innerHTML = message;
}
This returns the url in the picker dialog box.
My accessSpreadsheet function looks like this and is located in a google script file:
function accessSpreadsheet() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var currentCell = sheet.getCurrentCell();
currentCell.setValue(message);
return spreadsheet;
}
The function runs but it cannot define message. Is there a way to access the variable defined in the function in the html file from the google scripts function? Or is there another better way to do this?
Solution:
Pass the string id from client side to server.
Snippets:
google.script.run.accessSpreadsheet(id);
function accessSpreadsheet(id) {
currentCell.setValue(id);
Reference:
Client-Server communication

problems displaying page, deleting contents and repopulating - could this be multiple binding?

I have a mobile app.
It consists of 2 screens. The first is for capturing user
credentials and the 2nd is for displaying data.
The idea is to collect the credentials on screen 1.
Then make an ajax call with the credentials to get data and present it on
screen 2 as a series of links.
Then allow the user to touch a link on screen 2. This will return the link data to the javascript and pass it to the ajax call and get more data - THEN delete all the data on screen 2 and repopulate it with the new data.
First thing I want to find out: is showing a page with mobile.changePage(), populating it, deleting the contents and then repopulating it (without another call to mobile.changePage()) a reasonable thing to do?
I'm having a problem and I think its related to how I'm using onclick in the <a>
Each time I display the most recently received data, I want to display it in an <a>. I write each onclick to call the getData routine passing it information to determine the next ajax AND whatever is being displayed in the <a>. The only way I could figure out to access that was in onclick.
Is there a better way?
I'm able to display the results of the first ajax call just fine. But things get weird with the 2nd, 3rd etc.
Sometimes I'll touch a link and I'll progress thru the screens as I expect.
Sometimes I'll touch an <a> on the 1st result screen, the 2nd result screen will display and then (without me selecting data from the 2nd screen) the 3rd screen will display.
I've looked at the logs and the getData() routine is being executed.
What could be causing this? Am I somehow not destroying all the <a> properly? Am I using onclick in a fashion its not designed for? Should I be using buttons styled to look like links instead of <a>
Here's my code:
"use strict";
var app = {
onDeviceReady: function() {
$('#startButton').click(function(){
app.getDeptsForUser();
});
},
getDeptsForUser: function(){
var parms = new Object();
parms.userName = assignedUser;
app.getData(JSON.stringify(parms),"ENDPOINT1", "Departments");
$.mobile.changePage("#index", { transition: 'slide' });
},
getData: function(paramStr, endpoint, displayHeader){
var paramStrObj = JSON.parse(paramStr);
var serverName = server + ":" + port;
var encoded = Base64().encode(paramStrObj.userName + ':' + pass);
var authType = 'Basic ' + encoded;
var option = endpoint+"?action=start&params=" + paramStr;
var URL = serverName + "/rest/bpm/wle/v1/service/"+option;
$.ajax({
url: URL,
type: "POST",
crossDomain: true,
jsonp: "callback",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authType);
},
success: function (result) {
console.log("MobileMockUp getData() ajax success result="+JSON.stringify(result));
if (endpoint === "ENDPOINT1"){
app.displayData(paramStr, endpoint,"Departments", result.data.data.depts.items);
}
else if (endpoint === "ENDPOINT2"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checklists.items);
}
else if (endpoint === "ENDPOINT3"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checks.items);
}
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Unable to retrieve '+displayHeader);
},
});
},
displayData: function(currParms,currEndPt, headerText, list){
var nextEndpt;
var nextHeaderText;
var currParmsObj = JSON.parse(currParms);
if (currEndPt === "MD#getDeptsForUser"){
nextEndpt = "MD#getCheckLists";
nextHeaderText = "Check Lists";
}
else if (currEndPt === "MD#getCheckLists"){
nextEndpt = "MD#getChecks";
}
var htmlListString="";
var parmObj;
var newLink;
$('#headerText').text(headerText);
for (var i = 0; i < list.length; i++){
parmObj = new Object();
if (currEndPt === "ENDPOINT1"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=list[i];
}
else if (currEndPt === "ENDPOINT2"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=currParmsObj.dept;
parmObj.checklist=list[i];
}
else if (currEndPt === "ENDPOINT3"){
nextHeaderText = list[i];
}
var str = JSON.stringify(parmObj);
str = str.toString().replace(/"/g, '\\"');
newLink = "<a style='background:#ffffff;padding-top:5%;border-top: thin solid black; display:block;font-size:12px;font-weight:normal;color:#000000;text-decoration: none;' href='#' onclick='app.getData(\""+str+"\",\""+nextEndpt+"\",\""+nextHeaderText+"\")'><pre>" + list[i] + " </pre></a><br>";
htmlListString=htmlListString+newLink;
}
$('#taskListUL').empty();
$('#taskListUL').append(htmlListString);
}
};
Could this be multiple binding?
i figured out it was multiple bindings

google apps script - form not automatically mailing spreadsheet response

I am new to Google Scripts but am getting the gist of it pretty quickly. I am trying to automate ordering of toner for our commercial printer. I set up a Google Form with 4 scale questions, one for each color (CMYK), with multiple choices from 1 through 5 toner cartridges.
Then, in the Google Spreadsheet that records responses, I created a script (mainly from internet examples) that gets the last entry of the spreadsheet (bottom row) and sends an email with the amount of toner cartridges needed, with a trigger onFormSubmit().
When I use the form and hit the submit button, nothing happens. There seems to be a disconnect between the form and the spreadsheet? Maybe some triggers are not working? I tried using the triggers from the script editor and also the programmable triggers and it still does not work from the form submission.
The "ScriptApp" part of the script's trigger doesn't seem to be recognized by the Google Scripts editor, as it's not in a particular color, different from the other code, which makes me wonder if I have to write some form of #include statement or something? All the internet examples show ScriptApp in color.
No bugs are found when "compiling"...
function sendFormByEmail(e)
{
ScriptApp.newTrigger("sendFormByEmail").forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()).onFormSubmit().create();
var email = "example#email.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,2,1,s.getLastColumn()-1).getValues()[0];
var colors = s.getRange(s.getLastRow(),2,s.getLastRow(),s.getLastColumn()-1).getValues()[0];
var message = "";
var subject = "Toner order";
for(var i in headers)
message += headers[i] + ': ' + colors[i] + "\n\n";
MailApp.sendEmail(email, subject, message);
}
This is the answer that definitely works. Had to clear past triggers first, else it would send multiple emails because it was creating a new trigger with each submission:
var triggers = ScriptApp.getProjectTriggers();
for(var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("sendFormByEmail").forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()).onFormSubmit().create();
function sendFormByEmail(e)
{
var email = "example#email.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,2,1,s.getLastColumn()-1).getValues()[0];
var colors = s.getRange(s.getLastRow(),2,s.getLastRow(),s.getLastColumn()-1).getValues()[0];
var message = "";
var subject = "toner order";
for(var i in headers) {
message += headers[i] + ': ' + colors[i] + "\n\n";
}
MailApp.sendEmail(email, subject, message);
}

Issues With Pop-Up Blocking (this shouldn't be happening?)

First to clarify, I am trying to open a pop-up in response to a user event.
I am developing an application on Facebook that involves e-commerce transactions, and for reasons related to my EV SSL certificates, I have to open our billing terminal in a new, fully-secure window. As such, the process goes as follows:
User selects "new card" as payment method and enter's the recipient's shipping address
User clicks "Place Order," which uses an AJAX call to validate the address, and IF valid, syncs it with the database.
IF address is valid (AJAX success: function()), and the user selected "new card," then the secure billing terminal is supposed to open using a window.open call.
As I understand it, most modern browsers including Chrome, Firefox, and Safari are supposed to traverse up the chain to determine if the source event was user-initiated (in this case, it was--a click event), however despite this I cannot seem to prevent this pop-up from getting blocked and my users are having a great deal of trouble figuring out what's going on.
Unfortunately Chrome doesn't make it all that noticeable when a pop-up is blocked, so most users will not notice this and will assume that the app is simply "broken."
Any ideas? We're a week from launch and I'm getting desperate...
[EDIT] Here is the code for reference:
/* -- Step 3: Complete Checkout Click -- */
$('div.finishGroupOrder').live('click', function() {
/* User is Click-Happy? */
if ( $('div#billing-contents div#loader').length ) {
alert('Your order is processing. We know it\'s hard, but please be patient.');
return false;
}
var paymentMethod = $('input[name="method"]:checked').val(); // Payment Method Selected ( Card on File / New / PayPal )
var secureSession = $(this).attr('secure'); // Secure Session ID
var orderData = { addressSelection: $('input[name="address"]:checked').val(),
price: $('div.price').attr('value') };
/* Form Validation */
switch( orderData.addressSelection ) {
case 'new': // User chose to enter address manually
var allInputs = $('div#new-address').find('input:not(#address2), select');
var validInputs = $('div#new-address').find('input[value!=""]:not(#address2), select[value!=""]');
if ( allInputs.length === validInputs.length ) { // All inputs are valid, capture their contents
allInputs.removeClass('bad-value');
var address = { phone: $('input#phone').val(),
address1: $('input#address1').val(),
address2: $('input#address2').val(),
city: $('input#city').val(),
state: $('select#state').val(),
zip: $('input#zipcode').val() };
var validatedAddress = validation.validateAddress(address);
if (validatedAddress) {
address.address1 = validatedAddress.address1;
address.address2 = validatedAddress.address2;
address.city = validatedAddress.city;
address.state = validatedAddress.state;
address.timeOffset = validatedAddress.timeOffset; // Time offset from EST (PST = -3, EST = 0, etc.)
$('input#timezone').val(address.timeOffset);
} else {
allInputs.addClass('bad-value');
return false;
}
} else { // Some inputs are invalid, prompt the user to fix them
allInputs.filter(function() { return ($.inArray( this, validInputs ) > -1) ? false : true; }).addClass('bad-value');
return false;
}
break;
case 'verified': // User chose to ship to verified address
var address = { address1: 'verified' };
break;
default:
alert('Please choose an address where you want the flowers to be delivered.');
return false;
break;
}
/* Sync Order With Updated Address Information */
$.ajax({ type: 'POST',
url: location.protocol + '//' + location.host + '/_ajax/order.ajax.php',
data: 'action=update_order&' + $.param( address ),
success: function() {
/* Load Selected Payment Method */
switch( paymentMethod ) {
//case 'paypal': paypal(); break;
case 'member':
newGroupOrderDialogActions.payAsMember();
break;
case 'newCard':
newGroupOrderDialogActions.payWithCard( secureSession );
//$('div.group-secure-terminal').trigger('click');
break;
}
}
});
And the newGroupOrderActions.payWithCard()...
/* -- Pay With a New Credit Card -- */
payWithCard: function( session ) {
var windowHeight = 769; // Terminal Height
var windowWidth = 638; // Terminal Width
var w = screen.availWidth; // Available Screen (W)
var h = screen.availHeight; // Available Screen (H)
var top = (h-windowHeight)/2; // Center Positioning
var left = (w-windowWidth)/2; // Center Positioning
/* Open Secure Order Terminal */
var secureTerminal = window.open('https://secure.mydomain.ly/contribute?id=' + session, 'myCompany: Secure Checkout', 'menubar=0,toolbar=0,location=1,resizable=0,scrollbars=1,height='+windowHeight+',width='+windowWidth+',top='+top+',left='+left);
/* Check for Secure Order Terminal Close Event */
var onFinish = setInterval(function() {
try {
if (secureTerminal.closed) { // Window has been unloaded, check the order to see if it has been approved
clearTimeout(onFinish);
$.ajax({ type: 'POST',
url: location.protocol + '//' + location.host + '/_ajax/redirect.ajax.php',
data: 'action=group_order_status_redirect',
success: function(redirect) { newGroupOrderDialogActions.publishOrder( redirect ) } // If redirect is not null, order was successful. Redirect to order page
});
}
} catch (e) {}
}, 200);
},

Categories