Javascript doesn't generate email - javascript

I've coded some js into an Articulate Storyline file for a workshop. I'm trying to get the system to compile a number of variables and email the data to the user. When I click on the icon to generate the email I get nothing.
SET DATE CODE
var d = new Date();
var weekday=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var monthName = new Array("January","February","March","April","May","June","July","August","Septemeber","October","November","December");
var dateVal = d.getDate().toString();
var delimeter = ", ";
var delimeter1 = " ";
var txtPostdate = ""
var lDigit = dateVal.charAt( dateVal.length-1);
if (lDigit = = "1"){
txtPostdate = "st";
}else if(lDigit = = "2"){
txtPostdate = "nd";
}else if(lDigit = = "3"){
txtPostdate = "rd";
}else{
txtPostdate = "th";
}
var dateString = weekday[d.getDay()]+delimeter+monthName[(d.getMonth())]+delimeter1+dateVal+txtPostdate+delimeter+d.getFullYear();
var player = GetPlayer();
player.SetVar("SystemDate",dateString);
SEND EMAIL CODE
var player = GetPlayer();
var useremail = player.GetVar("email");
var subject ="My Fact Sheet - Optimizing Your Online Job Applications";
var firstname = player.GetVar("firstname");
var lastname = player.GetVar("lastname");
var street = player.GetVar("street1");
var address2 = player.GetVar("street2");
var city = player.GetVar("city");
var state = player.GetVar("state");
var zip = player.GetVar("zip");
var phone = player.GetVar("phone");
var cell = player.GetVar("cell");
var mymail = player.GetVar("mymail");
var phone = player.GetVar("phone");
var cell = player.GetVar("cell");
var school1 = player.GetVar("school1");
var s1city = player.GetVar("s1city");
var s1degree = player.GetVar("s1degree");
var s1date = player.GetVar("s1date");
var s1start = player.GetVar("s1start");
var school2 = player.GetVar("school2");
var s2city = player.GetVar("s2city");
var s2degree = player.GetVar("s2degree");
var s2start = player.GetVar("s2start");
var s2date = player.GetVar("s2date");
var school3 = player.GetVar("school3");
var s3city = player.GetVar("s3city");
var s3degree = player.GetVar("s3degree");
var s3date = player.GetVar("s3date");
var s3start = player.GetVar("s3start");
var e1title = player.GetVar("e1title");
var e1start = player.GetVar("e1start");
var e1end = player.GetVar("e1end");
var e1 = player.GetVar("e1");
var e1employer = player.GetVar("e1employer");
var e1city = player.GetVar("e1city");
var e1state = player.GetVar("e1state");
var e1zip = player.GetVar("e1zip");
var e1super = player.GetVar("e1super");
var e1phone = player.GetVar("e1phone");
var e1reason = player.GetVar("e1reason");
var e1startsalary = player.GetVar("e1startsalary");
var e1endsalary = player.GetVar("e1endsalary");
var e1accomplish = player.GetVar("e1accomplish");
var e2title = player.GetVar("e2title");
var e2start = player.GetVar("e2start");
var e2end = player.GetVar("e2end");
var e2 = player.GetVar("e2");
var e2employer = player.GetVar("e2employer");
var e2city = player.GetVar("e2city");
var e2state = player.GetVar("e2state");
var e2zip = player.GetVar("e2zip");
var e2super = player.GetVar("e2super");
var e2phone = player.GetVar("e2phone");
var e2reason = player.GetVar("e2reason");
var e2startsalary = player.GetVar("e2startsalary");
var e2endsalary = player.GetVar("e2endsalary");
var e2accomplish = player.GetVar("e2accomplish");
var e3title = player.GetVar("e3title");
var e3start = player.GetVar("e3start");
var e3end = player.GetVar("e3end");
var e3 = player.GetVar("e3");
var e3employer = player.GetVar("e3employer");
var e3city = player.GetVar("e3city");
var e3state = player.GetVar("e3state");
var e3zip = player.GetVar("e3zip");
var e3super = player.GetVar("e3super");
var e3phone = player.GetVar("e3phone");
var e3reason = player.GetVar("e3reason");
var e3startsalary = player.GetVar("e3startsalary");
var e3endsalary = player.GetVar("e3endsalary");
var e3accomplish = player.GetVar("e3accomplish");
var r1name = player.GetVar("r1name");
var r1company = player.GetVar("r1company");
var r1email = player.GetVar("r1email");
var r1phone = player.GetVar("r1phone");
var r2name = player.GetVar("r2name");
var r2company = player.GetVar("r2company");
var r2email = player.GetVar("r2email");
var r2phone = player.GetVar("r2phone");
var r3name = player.GetVar("r3name");
var r3company = player.GetVar("r3company");
var r3email = player.GetVar("r3email");
var r3phone = player.GetVar("r3phone");
var cover = player.GetVar("cover");
var resume = player.GetVar("resume");
var mail = player.GetVar("mail");
var mailto_link='mailto:'+useremail+'?subject='+subject+'&body='+"Activity Notes – Optimizing Your Online Job Applications %0d%0A %0d%0AMy Name:%0d%0A”+firstname+”%0d%0A”+lastname+”%0d%0A%0d%0AMy Address:%0d%0A”+street1+”%0d%0A”+street2+”%0d%0A”+city+”%0d%0A”+state+”%0d%0A”+zip+”%0d%0A%0d%0AMy Home Phone: %0d%0A"+phone+”%0d%0A%0d%0AMy Cell Phone: %0d%0A”+cell+”%0d%0A%0d%0AMy eMail: %0d%0A "+mymail+”%0d%0A%0d%0AMy Education:%0d%0A”+school1+”%0d%0A”+s1city+”+s1degree+”%0d%0A”+s1start+”%0d%0A”+s1date+”%0d%0A%0d%0A”+school2+”%0d%0A”+s2city+”%0d%0A”+s2degree+”%0d%0A“+s1start+”%0d%0A”+s2date+”%0d%0A%0d%0A”+school3+”%0d%0A“+s3city+”%0d%0A“+s3degree+”%0d%0A“+s1start+”%0d%0A“+s3date+”%0d%0A%0d%0AMy Employment History - Job 1: %0d%0A“+e1title+”%0d%0A%0d%0ADates: %0d%0A “+e1start+”%0d%0A“+e1end+”%0d%0A%0d%0AEmployer Information:%0d%0A“+e1+”%0d%0A“+e1employer+”%0d%0A“+e1city+”%0d%0A“+e1state+”%0d%0A“+e1zip+”%0d%0A%0d%0ACompany Contact: %0d%0A“+e1super+”%0d%0A“+e1phone+”%0d%0A%0d%0AReason for Leaving: %0d%0A“+e1reason+”%0d%0A%0d%0AStarting Salary: “+e1startsalary+”%0d%0AEnding Salary: ”+e1endsalary+”%0d%0A%0d%0AAccomplishments:%0d%0A“+e1accomplish+”%0d%0A%0d%0AMy Employment History - Job 2:%0d%0A“+e2title+”%0d%0A%0d%0ADates:%0d%0A“+e2start+”%0d%0A“+e2end+”%0d%0A%0d%0AEmployer Information: %0d%0A“+e2+”%0d%0A“+e2employer+”%0d%0A“+e2city+”%0d%0A“+e2state+”%0d%0A“+e2zip+”%0d%0A%0d%0ACompany Contact: %0d%0A“+e2super+”%0d%0A“+e2phone+”%0d%0A%0d%0AReason for Leaving:%0d%0A“+e2reason+”%0d%0A%0d%0AStarting Salary: “+e2startsalary+”%0d%0AEnding Salary: “+e2endsalary+”%0d%0A%0d%0AAccomplishments:%0d%0A“+e2accomplish+”%0d%0A%0d%0AMy Employment History - Job 3:%0d%0A“+e3title+”%0d%0A%0d%0ADates:%0d%0A“+e3start+”%0d%0A“+e3end+”%0d%0A%0d%0AEmployer Information:%0d%0A
“+e3+”%0d%0A“+e3employer+”%0d%0A“+e3city+”%0d%0A“+e3state+”%0d%0A“+e3zip+”%0d%0A%0d%0ACompany Contact:%0d%0A“+e3super+”%0d%0A“+e3phone+”%0d%0A%0d%0AReason for Leaving:%0d%0A“+e3reason+”%0d%0A%0d%0AStarting Salary: “+e3startsalary+”%0d%0AEnding Salary: “+e3endsalary+”%0d%0A%0d%0AAccomplishments:%0d%0A“+e3accomplish+”%0d%0A%0d%0AMy References:%0d%0A“+r1name+”%0d%0A“+r1company+”%0d%0A“+r1email+”%0d%0A“+r1phone+”%0d%0A%0d%0A“+r2name+”%0d%0A“+r2company+”%0d%0A“+r2email+”%0d%0A“+r2phone+”%0d%0A%0d%0A“+r3name+”%0d%0A“+r3company+”%0d%0A“+r3email+”%0d%0A“+r3phone+”%0d%0A%0d%0AMy Resume:%0d%0A“+resume+”%0d%0A%0d%0AMy Cover Letter:%0d%0A“+cover+”%0d%0A%0d%0A
win=window.open(mailto_link,'emailWin');

Try putting %20 in place of spaces. Text in the submitted URL has spaces "Activity Notes – Optimizing Your Online.........". I did not survey the entire URL, but be sure to encode wherever needed.

Related

How to check multiple arrays at once?

I have this code. It checks if auctions[0] exists and if it does, it gets the value and sends it and continues to the next number. If not it will move on to the next number and do the same thing. And I need it to check if it exists until it reaches number 30
Are there any alternatives to this that is less bulky and messy?
if (ahValue.auctions[0]){
var itemName = ahValue.auctions[0].item_name
var itemLore = ahValue.auctions[0].item_lore
var itemTier = ahValue.auctions[0].tier
var itemSeller = ahValue.auctions[0].auctioneer
var itemBids = ahValue.auctions[0].bids.length
console.log(`${itemName}${itemLore}${itemTier}${itemSeller}${itemBids}`)
}
if (ahValue.auctions[1]){
var itemName = ahValue.auctions[1].item_name
var itemLore = ahValue.auctions[1].item_lore
var itemTier = ahValue.auctions[1].tier
var itemSeller = ahValue.auctions[1].auctioneer
var itemBids = ahValue.auctions[1].bids.length
console.log(`${itemName}${itemLore}${itemTier}${itemSeller}${itemBids}`)
}
//copy and paste until it reaches 30
if (ahValue.auctions[30]){
var itemName = ahValue.auctions[30].item_name
var itemLore = ahValue.auctions[30].item_lore
var itemTier = ahValue.auctions[30].tier
var itemSeller = ahValue.auctions[30].auctioneer
var itemBids = ahValue.auctions[30].bids.length
console.log(`${itemName}${itemLore}${itemTier}${itemSeller}${itemBids}`)
}
Use a for loop:
for(let i = 0; i <= 30; i++) {
if (ahValue.auctions[i]){
var itemName = ahValue.auctions[i].item_name
var itemLore = ahValue.auctions[i].item_lore
var itemTier = ahValue.auctions[i].tier
var itemSeller = ahValue.auctions[i].auctioneer
var itemBids = ahValue.auctions[i].bids.length
console.log(`${itemName}${itemLore}${itemTier}${itemSeller}${itemBids}`)
}
}
try something like this.
auctions.length this will return the lenght of array, and this will help you to iterate over all the elements.
This is the running code snippet.
var auctions = [];
auctions[0] = { "item_name" : "item_name1", "item_lore" : "item_lore1", "tier" : "tier1", "auctioneer" : "auctioneer1" , "bids":"bids1"};
auctions[1] = { "item_name" : "item_name2", "item_lore" : "item_lore2", "tier" : "tier2", "auctioneer" : "auctioneer2" , "bids":"bids2"};
for(var i = 0; i < auctions.length; i++){
if(auctions[i]){
console.log(auctions[i].item_name);
}
}
And your full code will look like this:
for(let i = 0; i <= ahValue.auctions.length; i++) {
if (ahValue.auctions[i]){
var itemName = ahValue.auctions[i].item_name
var itemLore = ahValue.auctions[i].item_lore
var itemTier = ahValue.auctions[i].tier
var itemSeller = ahValue.auctions[i].auctioneer
var itemBids = ahValue.auctions[i].bids.length
console.log(`${itemName}${itemLore}${itemTier}${itemSeller}${itemBids}`)
}
}

Create a Sub sheet from Master Sheet, using import range, filter and match Google App Script

I want to fetch data from a google sheet data dump/master sheet. There is a sheet for each month. Import/match the data to columns that are in a different order in another sub spreadsheet and put all months on one sheet. Lastly, I want to filter the data by person, status and date, so only these items will show unless Cell H1 is populated. If cell H1 is populated and not null, all data that meets the criteria will be shown.
Master: https://docs.google.com/spreadsheets/d/1nIzCqQUL1K4HwYUGV0jxjJjLKSFaeqVn27f_pkoL9j0/edit?usp=sharing
Subsheet:https://docs.google.com/spreadsheets/d/1-V0F_pJTKFmP8jRBwpIzBe_sP7GbC-314oUB97N0K-0/edit#gid=0
function Importmatchfilter() {
// source sheet
var ss = ('1nIzCqQUL1K4HwYUGV0jxjJjLKSFaeqVn27f_pkoL9j0/edit#gid=1395833187');
var ssn1 = ss.getSheetByName('April'); ('A:Z')
var ssn2 = ss.getSheetByName('May'); ('A:Z')
var ssn3 = ss.getSheetByName('June'); ('A:Z')
var ssn4 = ss.getSheetByName('July'); ('A:Z')
var ssn5 = ss.getSheetByName('August'); ('A:Z')
var ssn6 = ss.getSheetByName('September'); ('A:Z')
var ssn7 = ss.getSheetByName('October'); ('A:Z')
var ssn8 = ss.getSheetByName('November'); ('A:Z')
var ssn9 = ss.getSheetByName('December'); ('A:Z')
// Get full range of data
var SRange1 = ssn1.getDataRange();
var SRange2 = ssn2.getDataRange();
var SRange3 = ssn3.getDataRange();
var SRange4 = ssn4.getDataRange();
var SRange5 = ssn5.getDataRange();
var SRange6 = ssn6.getDataRange();
var SRange7 = ssn7.getDataRange();
var SRange8 = ssn8.getDataRange();
var SRange9 = ssn9.getDataRange();
// get A1 notation identifying the range
var A1Range = SRange1.getA1Notation();
var A1Range1 = SRange1.getA1Notation();
var A1Range2 = SRange2.getA1Notation();
var A1Range3 = SRange3.getA1Notation();
var A1Range4 = SRange4.getA1Notation();
var A1Range5 = SRange5.getA1Notation();
var A1Range6 = SRange6.getA1Notation();
var A1Range7 = SRange7.getA1Notation();
var A1Range8 = SRange8.getA1Notation();
var A1Range9 = SRange9.getA1Notation();
// get the data values in range
var SData1 = SRange1.getValues();
var SData2 = SRange2.getValues();
var SData3 = SRange3.getValues();
var SData4 = SRange4.getValues();
var SData5 = SRange5.getValues();
var SData6 = SRange6.getValues();
var SData7 = SRange7.getValues();
var SData8 = SRange8.getValues();
var SData9 = SRange9.getValues();
// target sheet
var ts = tss.getSheetByName('Sheet1');
function listMajors() {
gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: '1-V0F_pJTKFmP8jRBwpIzBe_sP7GbC-314oUB97N0K-0',
range: A1
}).then(function(response) {
var range = response.result;
if (range.values.length > 0) {
appendPre('Due date, Status, Address:');
for (i = 0; i < range.values.length; i++) {
var row = range.values[i];
appendPre(row[0] + ', ' + row[4]);
function getheaderValues(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet2');
var range = sheet.getRange("A:Z");
var allOfColumnAz = range.getValues()
for (var i = 1; i < 10 ; i++){
var sData = eval("SData"+i);
var lastRow = ts.getLastRow();
var numRows = sData.length;
var numCols = sData[0].length;
ts.getRange(lastRow+(lastRow > 0 ? 2 : 1), 1, numRows, numCols).setValues(sData);
}}

Javascript refactoring similar variables into a forloop

I am trying to simplify code where I define a lot of variables which have a similar structure. i.e:
To be simplified:
var monthActual = document.createElement('input');
monthActual.name = "monthActual_" + showrooms[i];
monthActual.value = monthActualData;
fullForm.appendChild(monthActual);
var monthTarget = document.createElement('input');
monthTarget.name = "monthTarget_" + showrooms[i];
monthTarget.value = monthTargetData;
fullForm.appendChild(monthTarget);
var priorYear = document.createElement('input');
priorYear.name = "priorYear_" + showrooms[i];
priorYear.value = priorYearData;
fullForm.appendChild(priorYear);
var priorYearToDate = document.createElement('input');
priorYearToDate.name = "priorYearToDate_" + showrooms[i];
priorYearToDate.value = priorYearToDateData;
fullForm.appendChild(priorYearToDate);
var yearToDateTarget = document.createElement('input');
yearToDateTarget.name = "yearToDateTarget_" + showrooms[i];
yearToDateTarget.value = yearToDateTargetData;
fullForm.appendChild(yearToDateTarget);
var yearToDateActual = document.createElement('input');
yearToDateActual.name = "yearToDateActual_" + showrooms[i];
yearToDateActual.value = yearToDateActualData;
fullForm.appendChild(yearToDateActual);
var YTDVsPYTDSalesCurrency = document.createElement('input');
YTDVsPYTDSalesCurrency.name = "YTDVsPYTDSalesCurrency_" + showrooms[i];
YTDVsPYTDSalesCurrency.value = YTDVsPYTDSalesCurrencyData;
fullForm.appendChild(YTDVsPYTDSalesCurrency);
var YTDVsPYTDSalesinPercent = document.createElement('input');
YTDVsPYTDSalesinPercent.name = "YTDVsPYTDSalesinPercent_" + showrooms[i];
YTDVsPYTDSalesinPercent.value = YTDVsPYTDSalesinPercentData;
fullForm.appendChild(YTDVsPYTDSalesinPercent);
var YTDVsYTDTargetinSalesCurrency = document.createElement('input');
YTDVsYTDTargetinSalesCurrency.name = "YTDVsYTDTargetinSalesCurrency_" + showrooms[i];
YTDVsYTDTargetinSalesCurrency.value = YTDVsYTDTargetinSalesCurrencyData;
fullForm.appendChild(YTDVsYTDTargetinSalesCurrency);
var YTDVsYTDTargetinPercent = document.createElement('input');
YTDVsYTDTargetinPercent.name = "YTDVsYTDTargetinPercent_" + showrooms[i];
YTDVsYTDTargetinPercent.value = YTDVsYTDTargetinPercentData;
fullForm.appendChild(YTDVsYTDTargetinPercent);
I've tried to simplify it by putting the variables into an array then iterating through them like so:
Attempted simplify:
var tableColumnData = ['monthActual', 'monthTarget', 'priorYear', 'priorYearToDate', 'yearToDateTarget',
'yearToDateActual', 'YTDVsPYTDSalesCurrency', 'YTDVsPYTDSalesinPercent', 'YTDVsYTDTargetinSalesCurrency', 'YTDVsYTDTargetinPercent'];
for(var j=0; j<tableColumnData.length; j++){
var temp = document.createElement('input');
temp.name = tableColumnData[j]+ "_" + showrooms[i];
temp.value = (tableColumnData[j] +"Data");
fullForm.appendChild(temp);
}
This is however only giving me the string value of the literal string: tableColumnData[j] +"Data" when I am trying to point towards the variable of the same name. I am not sure how to use the variable of the same name.
Full code:
var fullForm = document.createElement('form');
fullForm.action = '/fpdf/requests/print_fullreport.php?year=' + requestYear + '&month=' + getMonth(requestMonth);
fullForm.id = 'fullForm';
fullForm.target = '_blank';
fullForm.method = 'post';
var showrooms = [1, 3, 4, 24, 27, 29, 34, 36, 37, 8, 21, 25, 26, 28, 31, 33, -1];
for (var i = 0; i <showrooms.length; i++){
var showroomData = allTargetsData.monthlyDetail[showrooms[i]];
var currencyData = showroomData.currency;
var showroomname = showroomData.showroom_name;
var monthActualData = showroomData.total;
var monthTargetData = Math.round(allTargetsData.originalTarget[requestYear][showrooms[i]][requestMonth]['amount']);
var priorYearData = allTargetsData.realFigure[requestYear - 1][showrooms[i]]['figures'][requestMonth];
var priorYearToDateData = showroomData.ly_ytd;
var yearToDateTargetData = Math.round(showroomData.ytd_target);
var yearToDateActualData = showroomData.ytd;
var calculation1 = (showroomData.ytd - showroomData.ly_ytd).toFixed(2);
var YTDVsPYTDSalesCurrencyData = calculation1;
var calculation2 = (parseFloat(showroomData.ytd - showroomData.ly_ytd)/showroomData.ly_ytd).toFixed(2);
var YTDVsPYTDSalesinPercentData = (calculation2*100);
if (isNaN(YTDVsPYTDSalesinPercentData) || YTDVsPYTDSalesinPercentData == "Infinity"){
YTDVsPYTDSalesinPercentData = 0;
}
var calculation3 = (showroomData.ytd - showroomData.ytd_target).toFixed(2);
var YTDVsYTDTargetinSalesCurrencyData = (calculation3*100)/100;
var calculation4 = (parseFloat(showroomData.ytd - showroomData.ytd_target)/parseFloat(showroomData.ytd_target)).toFixed(2);
var YTDVsYTDTargetinPercentData = calculation4*100;
if (isNaN(YTDVsYTDTargetinPercentData) || YTDVsYTDTargetinPercentData == "Infinity"){
YTDVsYTDTargetinPercentData = 0;
}
var showroomCurrency = document.createElement('input');
showroomCurrency.name = "showroomCurrency_" + showrooms[i];
showroomCurrency.value = currencyData;
fullForm.appendChild(showroomCurrency);
var showroomNameField = document.createElement('input');
showroomNameField.name = "showroomname_" + showrooms[i];
showroomNameField.value = showroomname;
fullForm.appendChild(showroomNameField);
var tableColumnData = ['monthActual', 'monthTarget', 'priorYear', 'priorYearToDate', 'yearToDateTarget',
'yearToDateActual', 'YTDVsPYTDSalesCurrency', 'YTDVsPYTDSalesinPercent', 'YTDVsYTDTargetinSalesCurrency', 'YTDVsYTDTargetinPercent'];
for(var j=0; j<tableColumnData.length; j++){
var temp = document.createElement('input');
temp.name = tableColumnData[j]+ "_" + showrooms[i];
temp.value = (tableColumnData[j] +"Data");
fullForm.appendChild(temp);
}
}
You were really close, but just needed to take the next step. You need to store your variables in an array or an object so that you can dynamically reference them, rather than through literals.
In this example, I took your code and put all of the extra data into the otherData object. That allows you to give them human readable names, but also be able to use the square bracket notation to look up the property. i.e. otherData.monthActualData == otherData["monthActualData"].
No promises on whether or not I did this perfectly, but the concept is still there.
var fullForm = document.createElement('form');
fullForm.action = '/fpdf/requests/print_fullreport.php?year=' + requestYear + '&month=' + getMonth(requestMonth);
fullForm.id = 'fullForm';
fullForm.target = '_blank';
fullForm.method = 'post';
var showrooms = [1, 3, 4, 24, 27, 29, 34, 36, 37, 8, 21, 25, 26, 28, 31, 33, -1];
for (var i = 0; i <showrooms.length; i++){
var showroomData = allTargetsData.monthlyDetail[showrooms[i]];
var currencyData = showroomData.currency;
var showroomname = showroomData.showroom_name;
var otherData = {};
otherData.monthActualData = showroomData.total;
otherData.monthTargetData = Math.round(allTargetsData.originalTarget[requestYear][showrooms[i]][requestMonth]['amount']);
otherData.priorYearData = allTargetsData.realFigure[requestYear - 1][showrooms[i]]['figures'][requestMonth];
otherData.priorYearToDateData = showroomData.ly_ytd;
otherData.yearToDateTargetData = Math.round(showroomData.ytd_target);
otherData.yearToDateActualData = showroomData.ytd;
var calculation1 = (showroomData.ytd - showroomData.ly_ytd).toFixed(2);
otherData.YTDVsPYTDSalesCurrencyData = calculation1;
var calculation2 = (parseFloat(showroomData.ytd - showroomData.ly_ytd)/showroomData.ly_ytd).toFixed(2);
otherData.YTDVsPYTDSalesinPercentData = (calculation2*100);
if (isNaN(otherData.YTDVsPYTDSalesinPercentData) || otherData.YTDVsPYTDSalesinPercentData == "Infinity"){
otherData.YTDVsPYTDSalesinPercentData = 0;
}
var calculation3 = (showroomData.ytd - showroomData.ytd_target).toFixed(2);
otherData.YTDVsYTDTargetinSalesCurrencyData = (calculation3*100)/100;
var calculation4 = (parseFloat(showroomData.ytd - showroomData.ytd_target)/parseFloat(showroomData.ytd_target)).toFixed(2);
otherData.YTDVsYTDTargetinPercentData = calculation4*100;
if (isNaN(otherData.YTDVsYTDTargetinPercentData) || otherData.YTDVsYTDTargetinPercentData == "Infinity"){
otherData.YTDVsYTDTargetinPercentData = 0;
}
var showroomCurrency = document.createElement('input');
showroomCurrency.name = "showroomCurrency_" + showrooms[i];
showroomCurrency.value = currencyData;
fullForm.appendChild(showroomCurrency);
var showroomNameField = document.createElement('input');
showroomNameField.name = "showroomname_" + showrooms[i];
showroomNameField.value = showroomname;
fullForm.appendChild(showroomNameField);
var tableColumnData = ['monthActual', 'monthTarget', 'priorYear', 'priorYearToDate', 'yearToDateTarget',
'yearToDateActual', 'YTDVsPYTDSalesCurrency', 'YTDVsPYTDSalesinPercent', 'YTDVsYTDTargetinSalesCurrency', 'YTDVsYTDTargetinPercent'];
for(var j=0; j<tableColumnData.length; j++){
var temp = document.createElement('input');
temp.name = tableColumnData[j]+ "_" + showrooms[i];
temp.value = otherData[tableColumnData[j] +"Data"];
fullForm.appendChild(temp);
}
}

Karatsuba Algorithm implemented in JavaScript not accurate

I am trying to implement the Karatsuba Algorithm in JavaScript. Below is my Implementation:
var bigInt = require("big-integer");
function bigKaratsuba(num1, num2) {
if (Number(num1) < 10 || Number(num2) < 10) {
return (Number(num1)*Number(num2)).toString();
}
var len1 = String(num1).length;
var len2 = String(num2).length;
var m = Math.max(len1, len2);
var m2 = Math.floor(m/2);
var high1 = String(num1).substring(0, m-m2);
var low1 = String(num1).substring(m-m2, len1);
var high2 = String(num2).substring(0, m-m2);
var low2 = String(num2).substring(m-m2, len2);
var high1 = bigInt(String(num1).substring(0, m-m2));
var low1 = bigInt(String(num1).substring(m-m2, len1));
var high2 = bigInt(String(num2).substring(0, m-m2));
var low2 = bigInt(String(num2).substring(m-m2, len2));
var low1AndHigh1 = low1.add(high1).toString();
var low2AndHigh2 = low2.add(high2).toString();
var high1 = String(high1);
var low1 = String(low1);
var high2 = String(high2);
var low2 = String(low2);
var z0 = bigKaratsuba(low1, low2);
var z1 = bigKaratsuba(low1AndHigh1, low2AndHigh2);
var z2 = bigKaratsuba(high1, high2);
var z0_int = bigInt(z0);
var z1_int = bigInt(z1);
var z2_int = bigInt(z2);
var product = z2_int.times(Math.pow(10, m2*2)).add(z1_int.minus(z2_int).minus(z0_int).times(Math.pow(10, m2))).add(z0_int);
return String(product);
}
bigKaratsuba(15, 15);
<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
This implementation works perfectly for small value, however while I am trying to calculate
3141592653589793238462643383279502884197169399375105820974944592 times
2718281828459045235360287471352662497757247093699959574966967627, the answer gose wrong, what I got is
8541020071716445382689180042569347598344699394502900911882868254737925119641226981222291225174629534283004908305569988292269254, which is not correct. The correct answer is 8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184 which I got it from here.
I have tried search on the stackoverflow but I haven't find any solution to my problem. There is no error or anything when I run my code. Any help or pointer will be highly appreciated. Thanks in advance for all the people who are being helpful.
With the great help of #Spektre and #greybeard, I managed to solve this problem. Below is the correct code:
var bigInt = require("big-integer");
function bigKaratsuba(num1, num2) {
if (Number(num1) < 10 || Number(num2) < 10) {
return (Number(num1)*Number(num2)).toString();
}
var len1 = String(num1).length;
var len2 = String(num2).length;
var m = Math.max(len1, len2);
var m2 = Math.floor(m/2);
var high1 = bigInt(String(num1).substring(0, len1-m2));
var low1 = bigInt(String(num1).substring(len1-m2, len1));
var high2 = bigInt(String(num2).substring(0, len2-m2));
var low2 = bigInt(String(num2).substring(len2-m2, len2));
var low1AndHigh1 = low1.add(high1).toString();
var low2AndHigh2 = low2.add(high2).toString();
var high1 = String(high1);
var low1 = String(low1);
var high2 = String(high2);
var low2 = String(low2);
var z0 = bigKaratsuba(low1, low2);
var z1 = bigKaratsuba(low1AndHigh1, low2AndHigh2);
var z2 = bigKaratsuba(high1, high2);
var z0_int = bigInt(z0);
var z1_int = bigInt(z1);
var z2_int = bigInt(z2);
var z1MinusZ2MinusZ0 = z1_int.minus(z2_int).minus(z0_int).toString();
var product = bigInt(addTrailingZero(z2, m2*2)).add(bigInt(addTrailingZero(z1MinusZ2MinusZ0, m2))).add(z0);
return String(product);
}
function addTrailingZero (numericString, numberOfZeroAdded) {
for (var i = 0; i < numberOfZeroAdded; i++) {
numericString = numericString + "0";
}
return numericString;
}
<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
As #Spektre pointed out, my original solution does truncate the mantissa since the biggest safe integer is 2^53-1. So one should add zero instead of doing the multiplication, besides it's also faster to add zero I believe.(Let me know if I am wrong).
Besides after trying the number suggested by #greybeard, I found that my original code snippet doesn't provide the correct solution so I changed it to
var high1 = bigInt(String(num1).substring(0, len1-m2));
var low1 = bigInt(String(num1).substring(len1-m2, len1));
var high2 = bigInt(String(num2).substring(0, len2-m2));
var low2 = bigInt(String(num2).substring(len2-m2, len2));

Google Apps Script validation issue in Google UiApp

I have been trying to figure out Google Apps Script validation in Google Sites and have yet to make the validation part work correctly.
I need to validate 2 things:
That there is at least 5 characters in the "location" textbox (up to 100)
That a date has been selected from the dropdown
If both conditions are not met, then it should make visible 2 things:
warnException
warnExceptionMes
That's it.
The rest of my logic is working great. I am just starting out.
The full logic is listed below. I have replaced our domain info with xxxxxxxxx.
So far, it either never shows the messages and does nothing or just getting one of the items right allows it to move forward. They should both meet the requirements or the warnExceptions should be thrown. This would also be the same if a user loaded the page and did not fill either/or area out and just pushed the button.
How can I validate the Location textbox and the dateBox?
var templateIDToCopy = 'xxxxxxxxxx';
var folderIDtoCopyTo = 'xxxxxxxxxx';
var councilMembers = ['Unknown','Name 1','Name 2'];
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
// Setup error message
var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false);
// handlers
var handler1 = app.createClientHandler()
.validateLength(location, 0, 50).validateMatches(dateBox, '2', 'g')
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler2 = app.createServerHandler('handlerFunction')
.validateLength(location, 1, 100).validateNotMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler1).addClickHandler(handler2);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);//.add(warnException).add(warnExceptionMes);
hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
.setWidget(1,2,warnExceptionMes)
// .setWidget(1,2,nextSteps)
app.add(hpanelException);
return app;
}
function handlerFunction(e) {
var app = UiApp.getActiveApplication();
app.getElementById('submit').setText('Building, please wait...').setEnabled(false);
var location = e.parameter.location;
var determineName = e.parameter.minuteTaker;
var date = e.parameter.dateBox;
var timeZone = date.toString().substr(25,6)+":00";
var dateMilli = date.getTime();
var hour = parseInt(e.parameter.hour);
var amPm = e.parameter.amPm;
if (amPm == 'PM' && hour != 12) hour = hour + 12;
if (hour == 12 && amPm == 'AM') hour = 0;
var hourMilli = hour * 3600000;
var minMilli = parseInt(e.parameter.minute) * 60000;
var milliTotal = dateMilli + hourMilli + minMilli;
// create custom format
var newDate = Utilities.formatDate(new Date(milliTotal), timeZone, 'MM/dd/yy hh:mm aaa');
app.getElementById('dateTimeLabel').setText(newDate);
// make a copy of the minutes template to use
var duplicateID = DriveApp.getFileById(templateIDToCopy)
.makeCopy('Simply Minutes v1.0 - Stage 1: Building new minutes...')
.getId();
// get the id of the annual folder where minutes will be stored
var getFolderID = DriveApp.getFolderById(folderIDtoCopyTo);
// copy new minutes sheet to the annual folder where minutes are stored
var moveIT = DriveApp.getFileById(duplicateID).makeCopy('Simply Minutes v1.0 - Stage 2: Building new minutes...', getFolderID).getId();
// get the new minutes doc that was created
var template = DocumentApp.openById(moveIT);
var templateHeader = template.getHeader();
var templateBody = template.getActiveSection();
// fill in the values
templateHeader.replaceText("<date>", newDate);
templateBody.replaceText("<date>", newDate);
templateHeader.replaceText("<location>", location);
templateBody.replaceText("<location>", 'N/A');
var email = Session.getEffectiveUser().getEmail();
var eUser = Session.getEffectiveUser().getUsername();
var createdBy = '';
if(ContactsApp.getContact(email)){
var fullName = ContactsApp.getContact(email).getFullName();
createdBy = fullName;
}
else {
createdBy = 'N/A';
};
var determineName = e.parameter.minuteTaker;
templateHeader.replaceText("<minutetaker>", determineName);
templateHeader.replaceText("<createdby>", createdBy)
templateBody.replaceText("<minutetaker>", determineName);
templateBody.replaceText("<createdby>", createdBy);
template.setName(newDate + ' TAC Minutes Recorded By ' + determineName);
// close out the doc
template.saveAndClose();
// remove the copy that was left in the root directory
// DriveApp.getFileById(duplicateID).isTrashed();
DriveApp.getFileById(duplicateID).setTrashed(true);
app = UiApp.getActiveApplication();
app.getElementById('submit').setText('Completed!').setEnabled(false);
app.getElementById('nextSteps').setVisible(true);
return app;
}
Try like this (see below) I changed a bit the validations and separated in 2 handlers + added a "clear" handler to be able to click-to-delete the warnings... test code here
You have also to add something to clear the warnings in the server handler and, why not combine the image and text warning in a single widget ? (easier to clean)
code below :
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var clearHandler = app.createClientHandler().forEventSource().setVisible(false)
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
// Setup error message
var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false).addClickHandler(clearHandler);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false).addClickHandler(clearHandler);
// handlers
var handler0 = app.createClientHandler()
.validateLength(location, 0, 5)
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler1 = app.createClientHandler()
.validateNotMatches(dateBox, '2', 'g')
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler2 = app.createServerHandler('handlerFunction')
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);//.add(warnException).add(warnExceptionMes);
hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
.setWidget(1,2,warnExceptionMes)
// .setWidget(1,2,nextSteps)
app.add(hpanelException);
return app;
}
EDIT second version following your comment.
I simulated a server function that takes some time so you see all the steps. + I combined the warning as suggested. (demo code updated with version 2)
var templateIDToCopy = 'xxxxxxxxxx';
var folderIDtoCopyTo = 'xxxxxxxxxx';
var councilMembers = ['Unknown','Name 1','Name 2'];
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(195, 65);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
var clearHandler = app.createClientHandler();
// Setup error message
var warnException =app.createImage('https://dl.dropboxusercontent.com/u/211279/clock_e0.gif').addClickHandler(clearHandler);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').addClickHandler(clearHandler);
var warnPanel = app.createHorizontalPanel().add(warnException).add(warnExceptionMes).setId('warning').setVisible(false);
clearHandler.forTargets(warnPanel).setVisible(false);
// handlers
var handler0 = app.createClientHandler()
.validateLength(location, 0, 5)
.forTargets(warnPanel).setVisible(true)
var handler1 = app.createClientHandler()
.validateNotMatches(dateBox, '2', 'g')
.forTargets(warnPanel).setVisible(true)
var handler2 = app.createClientHandler()
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.forEventSource().setText('Server Handler is running...').setEnabled(false)
.forTargets(warnPanel).setVisible(false);
var handlerS = app.createServerHandler('handlerFunction')
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2).addClickHandler(handlerS);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);
hpanelException.setWidget(1,1,warnPanel).setStyleAttribute("text-align", "right")
app.add(hpanelException);
return app;
}
function handlerFunction(e) {
var app = UiApp.getActiveApplication();
Utilities.sleep(1000);
app.getElementById('submit').setText('SERVER HANDLER is DONE');
// app.getElementById('warning').setVisible(false);// not necassary anymore, see clientHandler2
return app;
}

Categories

Resources