I'm attempting to send emails using an HTML template.
I've looked at this post:
(https://stackoverflow.com/questions/33178702/passing-variables-into-html-code)
Would either of the two code examples be close to something that could work to pass the variables from the Javascript to the HTML template?
My javascript variables are named detail2, detail3, detail4, detail5 and detail6.
1st attempt:
<html>
<head>
<script>
{
var detail2 = document.getElementById("detail2").innerHTML;
var detail3 = document.getElementById("detail3").innerHTML;
var detail4 = document.getElementById("detail4").innerHTML;
var detail5 = document.getElementById("detail5").innerHTML;
var detail6 = document.getElementById("detail6").innerHTML;
}
}
</script>
</head>
<body>
<p>
<br>"Punctual? " document.getElementById('detail2').value<br>
<br>"Attention to detail? " document.getElementById('detail3').value<br>
<br>"Overall Professionalism? " document.getElementById('detail4').value<br>
<br>"Date of Service: " document.getElementById('detail5').value<br>
<br>"Notes/Details: " document.getElementById('detail6').value<br>
</p>
</body>
</html>
2nd attempt:
<html>
<head>
<script>
{
<input type="hidden" id="Detail2" value="detail2" />
<input type="hidden" id="Detail3" value="detail3" />
<input type="hidden" id="Detail4" value="detail4" />
<input type="hidden" id="Detail5" value="detail5" />
<input type="hidden" id="Detail6" value="detail6" />
}
}
</script>
</head>
<body>
<p>
<br>"Punctual? " document.getElementById('detail2').value<br>
<br>"Attention to detail? " document.getElementById('detail3').value<br>
<br>"Overall Professionalism? " document.getElementById('detail4').value<br>
<br>"Date of Service: " document.getElementById('detail5').value<br>
<br>"Notes/Details: " document.getElementById('detail6').value<br>
</p>
</body>
</html>
Finally, the method given on GAS Dev is below, but this only confuses me more. I am sure I've been at this too long and I'm burned out, I just can't seem to see the answer on this one.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<table>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</body>
</html>
If anyone can help it's much appreciated!
Below is the Javascript from the .gs script file.
function SendEmail() {
// initialize data
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var values = range.getValues();
// iteration loop
for (var i = 1; i<values.length; i++) {
// current times for comparator
var month = new Date().getMonth(); // returns today as 0-11 -- Jan is 0
var day = new Date().getDate(); // returns today as 1-31
var hour = new Date().getHours(); // returns today as 0-23
var minute = new Date().getMinutes(); // returns today as 0-59
// pull data from spreadsheet rows
var company = values[i][0];
var rating = values[i][1];
var detail1 = values[i][2];
var detail2 = values[i][3];
var detail3 = values[i][4];
var detail4 = values[i][5];
var detail5 = values[i][6];
var sendTime = values[i][7];
// character send times for comparator
var cSendMonth = sendTime.getMonth(); // returns sendMonth as 0-11 -- Jan is 0
var cSendDay = sendTime.getDate(); // returns sendDay as 1-31
var cSendHour = sendTime.getHours(); // returns sendHour as 0-23
var cSendMinute = sendTime.getMinutes(); // returns sendMinute as 0-59
// comparator
if(cSendMonth == month) {
if(cSendDay == day) {
if(cSendHour == hour) {
if(cSendMinute == minute) {
var htmlBody = HtmlService.createHtmlOutputFromFile('mail_template').getContent();
MailApp.sendEmail({
to: Session.getActiveUser().getEmail(),
subject: 'Test Email markup2 - ' + new Date(),
htmlBody: htmlBody,
});
} // end if minute test
}// end if hour test
}// end if day test
}// end if month test
}// end for loop
}
Can you try:
<html>
<head>
<script>
(function() {
var detail2 = document.getElementById("detail2").innerHTML;
document.getElementById("detail2_val").innerHTML = detail2;
})();
</script>
</head>
<body>
<p>
<br>"Punctual?" <span id="detail2_val"></span><br>
</p>
</body>
</html>
Currently, this line:
var htmlBody = HtmlService.createHtmlOutputFromFile('mail_template').getContent();
will not evaluate a template.
The method being used is:
createHtmlOutputFromFile('mail_template')
HtmlService has quite a few methods for creating html content. You need to use:
HtmlService.createTemplateFromFile(filename).evaluate()
There are some possible things that could go wrong in your overall work flow. If the situation is one in which you are writing data, and then immediately trying to read that same data that was just written, there could be a problem with the new data not being available to be read in such a short time span.
I would use:
SpreadsheetApp.flush();
immediately after writing the new data, and before creating the template.
Only your third html example has code for a template. To retrieve data and put it into a template, a scriptlet must either run a function, that then retrieves the data, or the data must be in global variables. The situation with global variable makes no sense, because you are using dynamic data, so a function would need to run to first put the data into a global variable. The function might as well just return the data directly. So, your scriptlet will probably need to run a server side function and return text or HTML to the html template. You probably need to use a printing scriptlet.
Apps Script documentation - force printing scriptlets
Related
{$userinfo.create_account_date}
This returns me date in the following format: Oct-3-2017
I want to parse it to: DD/MM/YYY (03/10/2017)
The source code is encrypted. Is there a way to parse it through front-end only?
Front-end, assuming JavaScript. In most simple style.
function reformatDate(datumStr) {
var monthsArr = [];
monthsArr['Jan'] = '01';
// add missing months here
monthsArr['Oct'] = '10';
var dArr = datumStr.split('-');
return [dArr[1], monthsArr[dArr[0]], dArr[2]].join('/');
}
console.log(reformatDate('Oct-3-2017'));
Output:
3/10/2017
Addition to Karen's comment below.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function reformatDate(datumStr) {
var monthsArr = [];
monthsArr['Jan'] = '01';
// add missing months here
monthsArr['Oct'] = '10';
var dArr = datumStr.split('-');
return [dArr[1], monthsArr[dArr[0]], dArr[2]].join('/');
}
function elRfr(idName, datumStr) {
var id = document.getElementById(idName);
id.innerHTML = reformatDate(datumStr);
}
</script>
</head>
<body>
<div id="ourDate"><script type="text/javascript">elRfr('ourDate', 'Oct-3-2017');</script></div>
</body>
</html>
Karen, this is simplified example with just one DIV. In your case you should replace 'Oct-3-2017' with {$userinfo.create_account_date}, I guess.
If I assume correctly that your code is Salesforce Apex code.
Create a new var, initialize the date string as a new Date:
var d = new Date('Oct-3-2017');
Then manipulate it however you want with Date methods.
The website is supposed to display a message counting down to the tax day. I can't seem to get anything to display on the page. The scrollbar doesn't even show up with the color even though I put in the write code. Some advice please.
<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8">
<title>TaxDay</title>
<script type="text/javascript">
<!-- Hide from old browsers
function scrollColor() {
styleObject=document.getElementsByTagName('html')[0].style
styleObject.scrollbarFaceColor="#857040"
styleObject.scrollbarTrackColor="#f4efe9"
}
function countDown() {
var today = new Date()
var day of week = today.toLocaleString()
dayLocate = dayofweek.indexOf(" ")
weekDay = dayofweek.substring(0, dayLocate)
newDay = dayofweek.substring(dayLocate)
dateLocate = newday.indexOf(",")
monthDate = newDay.substring(0, dateLocate+1)}
yearLocate = dayofweek.indexOf("2016")
year = dayofweek.substr(yearLocate, 4)
var taxDate = new Date ("April 16, 2017")
var daysToGo = taxDate.getTime()-today.getTime()
var daysToTaxDate = Math.ceil(daysToGo/(1000*60*60*24))
function taxmessage() {
var lastModDate = document.lastModified
var lastModDate = lastModDate.substring(0,10)
taxDay.innerHTML = "<p style='font-size:12pt; font-
family:helvetica;'>Today is "+weekDay+" "+monthDate+" "+year+".
You have "+daysToTaxDate+" days to file your taxes.</p>"
}
}
//-->
</script>
The <div> id is taxDay if it's relevant. The body onLoad event handlers are scrollColor(); countDown(); and taxmessage().
you are not closing the countdown() function before the taxmessage() function - meaning that taxmessage is nested within countdown(). Also you do not have semicolons ";" after each line of the js. You should rewrite the code to either include the function of taxmessage() or close out countdown() first and call taxmessage with arguments passed to get the date variables.
check your console for errors
i have a code that is supposed to read from a html file, split it into an array and display parts of that array, but when going though with alert, i found that $.get is not actually getting the file
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
</head>
<body>
<button onclick="myfunction()">update</button>
<div id="div1"></div>
<script>
function myfunction() {
var info = "";
$.get("../Read_Test/text.html", function(data) {
SomeFunction(data);
});
alert(info);
var array = info.split("§n");
var people = array[1].split(",");
for (var i = 0; i < people.length; i++) {
document.getElementById("div1").innerHTML = people[i] + "<br>";
}
}
function SomeFunction(data) {
var info = data;
}
</script>
</body>
</html>
the directories are on a server and go like so:
Sublinks->Read_Test->This_File.html,text.html
The objective of this is that a file would have something along the lines of "a§nb1,b2,b3,§n" and the script would split it via "§n" then get "array[1]" and split that via ",". lastly it displays each part of that newly created array on a new line, so a file with "a§nb1,b2,b3,§n" would result in:
b1
b2
b3
Please help
Ajax is asynchronous, it make request and immediately call the next instruction and not wait for the response from the ajax request. so you will need to process inside of $.get. success event.
I have changed delimiter character to ¥. change same in text.html. problem was you have not mentioned character set to utf8 and due to this it could not recognized the special character and subsequently not able to split the string. i have aldo document type to HTML5.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<button onclick="myfunction()">update</button>
<div id="div1"></div>
<script>
function myfunction() {
$.get("../Read_Test/text.html", function(data) {
var info = data;
var array = info.split("¥");
var people = array[1].split(",");
for (var i = 0; i < people.length; i++) {
document.getElementById("div1").innerHTML += people[i] + "<br>";
}
});
}
</script>
</body>
</html>
I need some help because my callback function, parseMovie() is only being called once! Despite being in a for loop which iterates it twice. I am using a free Rottentomatoes API
The output only returns one ID, and not two ID's!
And runs parseMovie() only once and returns the movie ID with the last movie.
Does anyone have a fix for this script running problem?
HTML CODE
<!doctype html>
<html class="no-js">
<head>
<title>Movies</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/main.js"></script>
</head>
<body>
<form name="input">
<p> Actor/Actress Name: <input type="text" name="fullName"> </p>
<p> Movie 1 <input type="text" name="movie"> </p>
<p> Movie 2 <input type="text" name="movie"> </p>
<p><input type="button" value="Search movies" onclick="getMovies()"></p>
<p><textarea name="output" readonly> </textarea> </p>
</form>
</body>
</html>
JAVASCRIPT
//api key
var APIKEY = "qf54ubt95fea9n7jytr5xh6h";
var movieID = new Array();
var actor = new Array();
var actorName = "Jennifer Lawrence";
var movieTitle;
var output;
function callScript(call) {
var script = document.createElement('script');
script.setAttribute("src", call);
document.body.appendChild(script);
}
function getMovies() {
for (var x=0; x<2; x++) {
movieTitle = document.getElementsByName('movie')[x].value;
movieTitle= cleanMovieTitle(movieTitle);
var movieURL = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=";
callScript(movieURL + movieTitle + "&page_limit=10&page=1&apikey=" + APIKEY + "&callback=parseMovie");
}
}
function cleanMovieTitle(movie) {
movie = movie.trim();
movie = movie.replace(/ /g, "+");
return movie;
}
function parseMovie(data) {
var titleData = data.movies;
for (var t=0; t<titleData.length; t++) {
movieID[movieID.length] = titleData[t].id;
aCast = titleData[t].abridged_cast;
sample = [];
for (var person = 0; person < aCast.length; person++) {
sample[sample.length] = aCast[person].name;
}
actor[actor.length] = sample;
}
for (var arry = 0; arry < actor.length; arry++) {
if (actor[arry].indexOf(actorName) >= 0) {
output = movieID[arry];
break;
} else {
alert("spelling error of some sort! Error 404");
}
}
document.input.output.value = output;
}
Your statement var titleData = data.movies; is wrong, because the data returned by the API contains an array of movies.
You have to iterate through data.movies to get the data for the other movies (and not only the first one).
See the raw JS code and JSON data returned by the API: api.rottentomatoes.com
Three things that strike me as odd that might be causing the problem.
Using for…in for an array is considered bad practice, especially when there's a native forEach method and a polyfill for ie8-
cleanMovieTitle isn't doing anything because it doesn't return a value. If you were passing it an array or object, it would pass by reference and it would be altered, but that is considered bad practice for the exact reason that it's not working. You're passing a value, the function modifies that value within the function's scope, then does nothing with it. You need to return the string and set movieTitle = cleanMovieTitle(movieTitle); So maybe the API isn't returning for one of the titles because it hasn't been cleaned. See Passing by Reference or by Value.
The callback may be is getting called again before it finishes running. Not sure on this one, but you could check by flooding the loop with console.logs and seeing whether it's the case.
Edit
So I just ran your script on this page and I'm getting an error on document.input.output.value = output; As expected, parseMovies runs twice when I remove this line. What's document.input?
Hi I am new to Javascript and am trying to create a function that checks two dates. I have read it is useful to put the JS in the head part of the document, but this is not returning anything. I am also new to stackoverflow so I hope I did this correctly. :) Does anyone see the error?
<!DOCTYPE html>
<html>
<head>
var myDate = new Date(); // Your timezone!
var myEpoch = myDate.getTime()/1000;
var deadline = '1341596750.000';
document.write(myEpoch);
document.write("<br>",deadline);
if (myEpoch < deadline) {
document.write("<p>Just in time!</p>");
} else {
document.write("<p>Too late!</p>");
}
</head>
<body>
<br><br><br><br>http://www.epochconverter.com/
</body>
</html>
You have to mention it's a script using <script>. Also you shouldn't output DOM in the <head> like you are doing with document.write. Manipulate the DOM like this instead:
<head>
<script type="text/javascript">
var myDate = new Date(); // Your timezone!
var myEpoch = myDate.getTime()/1000;
var deadline = '1341596750.000';
document.write(myEpoch);
document.write("<br>",deadline);
if (myEpoch < deadline) {
document.getElementById("useme").innerHTML("Just in time!");
} else {
document.getElementById("useme").innerHTML("Too late!");
}
</script>
</head>
<body>
<p id="useme"></p>