How can I add line feeds into the messageBody of an emailDialog? I've tried "\n" and "<br />", setHtml(true), nothing seems to work, I still get an emailDialog with all the text running together.
Example:
var strBody="";
for (i=0, len=tabledata.length; i< len; i++) {
strBody+=tabledata[i].children[0].children[1].text + "<br />";
}
var emailDialog = Ti.UI.createEmailDialog();
emailDialog.Subject = "Test";
emailDialog.setHtml(true);
emailDialog.messageBody = strBody;
emailDialog.Open
Related
I'm working on some cloud code right now where I have an id I query against which returns all the data for that row.
I then need to iterate over all the fields (columns) of data and make some changes to the values then update that row.
Im able to get the data from parse but im not sure how to pull out the PFObject keys to iterate over the data in a for loop , make changes then save.
Here is some sample code where I hardcoded a field value in but I'm not sure how to get the fields, then iterate over them in a for loop..
Also excuse the JS code, I its been years since I wrote any JS.
<script type="text/javascript">
Parse.initialize("xxxx", "xxxx");
var LocationTag = Parse.Object.extend("LocationTags");
var query = new Parse.Query(LocationTag);
query.equalTo("SomeId", "302d87f2-0188-4cbe-bc2c-e6dcbf822539");
query.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var data = object.get('T0fYiV9PeeU'); <--- hardcoded field key.. i need to iterate over all fields returned from the row..
count = data.length;
for (var c = 0; c < count; c++) {
var res = Number(data[c].split(":")[0]);
text += "Value: " + res + "<br>";
sum += parseInt(res);
}
document.getElementById("main").innerHTML = text + ' sum: ' + sum + ' average: ' + sum/100 + results
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
Any ideas.. sorry again if its just a simple JS issue.. but I need to iterate over all fields, returned in the PFObject
If I understand correctly, you want a list of properties from a Parse.Object. The easiest way to to this is to call .toJSON() on the Parse.Object and then extract the keys from the json.
Example:
for (var i = 0; i < results.length; i++) {
var pfObject = results[i];
var jsonObject = pfObject.toJSON();
var pfKeys = [];
for(var key in pfKeys){
if(jsonObject.hasOwnProperty(key)){
pfKeys.push(key);
}
}
//Now we have a list of the pfObject keys in pfKeys
}
I wrote a mail merge script that works great, but execution transcripts revealed that the .makeCopy task alone consumed 60% of the 6 minute run time. I am trying to re-write the script in a way that enables me to:
Open a document template
populate the body of the template with spreadsheet data
create a new document
copy the body of the populated template to the new document
save the new document as a PDF, attach it to an email and send it
delete the new document (I don't need to retain a copy)
At present, I am receiving a "TypeError" appendtoDoc is not a function, it is undefined." Error in line 72.
//Creates the custom menu in the spreadsheet "Run Script"
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Run Script')
.addItem('Create Certs', 'menuItem1')
.addToUi();
}
//Nest the createDocument function within the menuItem1 function for execution
function menuItem1() {
function createDocFromSheet() {
}
//Defines the start row and calculates the number of rows to be processed
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = Browser.inputBox("Enter Start Row");
var endRow = Browser.inputBox("Enter End Row");
var numRows = (endRow - startRow) + 1;
var dataRange = sheet.getRange(startRow, 1, numRows, 7);
//defines the variables and the email body
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var date = row[0];
var nic = row[1];
var course = row[2];
var lastname = row[3];
var firstname = row[4];
var middle = row[5]
var email = row[6];
var docname = lastname+" "+nic+" PME Cert";
var subjectTxt = "NWC "+ course +" Online PME Course Certificate";
var fullBody = "PME COURSE COMPLETION CERTIFICATE" + "\n\n";
fullBody += "Your " + course + " course completion certificate is attached." + "\n\n";
fullBody += "Regards," + "\n\n";
fullBody += "Professor Steve Pierce" + "\n";
fullBody += "U.S. Naval War College "+ "\n";
fullBody += "Online PME Program Team" + "\n\n";
fullBody += "Learn more about NWC's Online PME Program at the link below:" + "\n";
fullBody += "http://www.usnwc.edu/Academics/College-of-Distance-Education/PME-(1).aspx" + "\n";
// The old makeCopy code
// var docId = DriveApp
// .getFileById("1CjdoldpJmPskkqStpmBk3dRznFyURgY5mMsfVHfIGz4")
// .makeCopy(docname).getId();
// Open the document template
//function createDocFromSheet(){
var templateid = "1CjdoldpJmPskkqStpmBk3dRznFyURgY5mMsfVHfIGz4"
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
//create the new document
var newDoc = DocumentApp.create(lastname+" "+nic+" PME Cert");
var newDocId = newDoc.getId()
var file = DriveApp.getFileById(newDocId)
// fill in the template with data
for (var i in data){
var row = data[i];
// opens the template and populates it with data from the sheet
var docid = DriveApp.getFileById(templateid).getId();
var doc = DocumentApp.openById(docid);
var body = doc.getActiveSection();
body.replaceText('fname', firstname);
body.replaceText('lname', lastname);
body.replaceText('midname', middle);
body.replaceText('course', course);
body.replaceText('date', date);
doc.saveAndClose();
// appends data from the template to the new document
var body = doc.getActiveSection();
var newBody = newDoc.getActiveSection();
appendToDoc(body, newBody);
DocsList.getFileById(docid).setTrashed(true); //deletes the temp file
}
}
function appendToDoc(src, dst) {
for (var i = 0; i < src.getNumChildren(); i++) {
appendElementToDoc (dst, src.getChild(i));
}
}
function appendElementToDoc (doc, object) {
var type = object.getType();
var element = object.copy();
if (type == DocumentApp.ElementType.PARAGRAPH) {
if (element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
var blob = element.asParagraph().getChild(0).asInlineImage().getBlob();
doc.appendImage(blob);
}
else doc.appendParagraph(element.asParagraph());
}
MailApp.sendEmail(email, subjectTxt, fullBody, {attachments: Newdoc.getAs("application/pdf")});
SpreadsheetApp.flush ();
DriveApp.getFileById(docId).setTrashed(true);
}}}
I modified your script to do it differently: I took a template, did replaceText then created a pdf from the changed template and sent the email; then I did replaceText again, pdf, email etc etc. I could email 10 certs in 15 secs this way. I didn't try a bigger number, and didn't check for errors.
function creatCertPdfAndEmail() {
var sheet = SpreadsheetApp.openById('1fDe0ju0zkDr0cdA5hWBC4RsxZgFv6mIFn6W1WU-0S0w').getSheets()[0]; //I created a separate spreadsheet for testing purposes.
var startRow =2;
var endRow =10 ;
var numRows = (endRow - startRow) + 1;
var dataRange = sheet.getRange(startRow, 1, numRows, 7);
var counter =0;
var data = dataRange.getValues();
var templateid = "1DizlNa2ENpEMTUGhM78J0ozgh8A8Sc9fI1q1XmhvuLk"
var docid = DriveApp.getFileById(templateid).getId();
var dateOld;
var courseOld;
var allTheNameOld;
for (var i = 0; i < data.length; ++i) {
var doc = DocumentApp.openById(docid);
var body = doc.getActiveSection();
var row = data[i];
var date = new Date().getTime() - new Date(row[0]).getTime(); //like this for testing to get a different value on each pdf
var nic = row[1];
var course = row[2];
var lastname = row[3];
var firstname = row[4];
var middle = row[5]
var email = row[6];
// var docname = lastname+" "+nic+" PME Cert"; //not used in this version
var subjectTxt = "NWC "+ course +" Online PME Course Certificate";
var fullBody = "PME COURSE COMPLETION CERTIFICATE" + "\n\n";
fullBody += "Your " + course + " course completion certificate is attached." + "\n\n";
fullBody += "Regards," + "\n\n";
fullBody += "Professor Steve Pierce" + "\n";
fullBody += "U.S. Naval War College "+ "\n";
fullBody += "Online PME Program Team" + "\n\n";
fullBody += "Learn more about NWC's Online PME Program at the link below:" + "\n";
fullBody += "http://www.usnwc.edu/Academics/College-of-Distance-Education/PME-(1).aspx"
+ "\n";
var row = data[i];
var allTheName = firstname+' '+middle+' '+lastname
if(counter ==0){
body.replaceText('allTheName',allTheName); // body.replaceText('Congratulations .*?\.',allTheName);
body.replaceText('coursex', course);
body.replaceText('datex', date);
}
else {
body.replaceText(allTheNameOld,allTheName);
body.replaceText(courseOld, course);
body.replaceText(dateOld, date);
}
dateOld = date;
courseOld = course;
allTheNameOld = allTheName
counter ++
doc.saveAndClose()
var attachment = doc.getAs("application/pdf")
MailApp.sendEmail(email, subjectTxt, fullBody, {attachments: attachment});
}
}
I tried to re-create your basic code structure in a simpler format, trying to reproduce the error.
//Nest the createDocument function within the menuItem1 function for execution
function menuItem1() {
function createDocFromSheet() {}
for (var i = 0; i < 2; ++i) {
//create the new document
Logger.log("First Loop ran i = " + i);
for (var i = 0; i < 2; ++i) {
Logger.log(' Inner For loop: i = ' + i)
appendToDoc();
}
}
function appendToDoc() {
Logger.log('appendToDoc ran!');
for (var i = 0; i < 2; ++i) {
Logger.log('appendToDoc For Loop i=' + i);
appendElementToDoc();
}
}
function appendElementToDoc() {
Logger.log('appendElementToDoc ran!');
Logger.log('');
}
}
That code actually runs for me, and is able to access the appendToDoc function when I run the menuItem1() function.
It looks like you have a function function createDocFromSheet() {} with nothing in it. I don't understand that.
I have the next code:
var exeWindow = document.getElementById("exeWindow");
var errorWindow = document.getElementById("errorWindow");
var annot = editor.getSession().getAnnotations();
editor.getSession().on("changeAnnotation", execute);
function execute(){
exeWindow.innerHTML = eval(editor.getValue());
errorWindow.innerHTML = "";
annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key))
console.log(annot[key].text + "on line " + " " + (parseInt(annot[key].row)+1));
errorWindow.innerHTML = annot[key].text + " Line " + " " + (parseInt(annot[key].row)+1);
exeWindow.innerHTML = "";
}
if (TogetherJS.running) {
TogetherJS.send({type: "execute"});
}
};
Im trying to capture the error logs, and before execute a valid code works, but once I introduce for example 2+2, despite of exeWindow changes correctly, if a rewrite it to 2+a for example, searching a new error, the exeWindow doesn´t changes and the error does not appears in errorWindow.
EDIT: Sorry, the problem is that is not getting the correct errors, only the errors like 'missing semicolon'.
If someone is interested, the solution I found is the next one:
function execute(){
try {
exeWindow.innerHTML = eval(editor.getValue());
errorWindow.innerHTML = "";
} catch(err){
var annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key)){
errorWindow.innerHTML = annot[key].text + " Line " + " " + (parseInt(annot[key].row)+1);
exeWindow.innerHTML = "";
}
}
}
if (TogetherJS.running) {
TogetherJS.send({type: "execute"});
}
};
Simple as that :)
I'm using one example code from StackOverflow to get the search results' title, URL and snippet:
for (int s = 0; s < 20; s = s + 4)
{
String address = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start=" + s + "&q=";
String query = "ucd";
String charset = "UTF-8";
URL url = new URL(address + URLEncoder.encode(query, charset));
Reader reader = new InputStreamReader(url.openStream(), charset);
GoogleSearch results = new Gson().fromJson(reader, GoogleSearch.class);
for (int i = 0; i < 4; i++)
{
System.out.println("Title: " + results.getResponseData().getResults().get(i).getTitle().replaceAll("<b>", "").replaceAll("</b>", ""));
System.out.println("URL: " + results.getResponseData().getResults().get(i).getUrl());
System.out.println("Snippet: " + results.getResponseData().getResults().get(i).getSnippet() + "\n");
System.out.println(results.getResponseData().getResults().get(i));
}
}
But it seems that the http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q= does not return the snippet from search.
Any other ways using Google API to get this? Can't find one after search...
Use the method getContent() rather than getSnippet(). For example:
System.out.println("Snippet: " + results.getResponseData().getResults().get(i).getContent() + "\n");
I'm having a strange problem when trying to updated a div with a couple of paragrahs of text from AJAX.
Here are functions I'm using:
var receivePapers = getXmlHttpRequestObject();
function get_papers(myCat){
if (receivePapers.readyState == 4 || receivePapers.readyState == 0) {
receivePapers.open("GET", 'http://server/path/tocode/file.php?get_papers=1&student_id=1&category=' + myCat, true);
receivePapers.onreadystatechange = handlereceivePapers;
receivePapers.send(null);
}
}
function handlereceivePapers() {
if (receivePapers.readyState == 4) {
var container_div = document.getElementById('paper_container');
var xmldoc = receivePapers.responseXML;
var paper_nodes = xmldoc.getElementsByTagName("paper");
var n_papers = paper_nodes.length;
// Clear the whole container div.
container_div.innerHTML = "";
container_div.innerHTML = "<table class='categoryHeader' width='100%'><tr><th class ='categoryHeader' width='80%' ><br/> " + paper_nodes[1].getElementsByTagName("category")[0].firstChild.nodeValue + "</br> <br/><br/></th></tr>";
container_div.innerHTML += "<tr><td>";
for (i = 0; i < n_papers; i++) {
var paper_id = paper_nodes[i].getElementsByTagName("paper_id");
var paper_title = paper_nodes[i].getElementsByTagName("paper_title");
var paper_desc = paper_nodes[i].getElementsByTagName("paper_desc");
var paper_time = paper_nodes[i].getElementsByTagName("paper_time");
var user_real_name = paper_nodes[i].getElementsByTagName("user_real_name");
var summary_div = document.createElement('div');
summary_div.innerHTML += "<table class='paper'><tr><td class='paperLike' width=80px rowspan=2 valign='top'><div id='" + paper_id[0].firstChild.nodeValue + "'> <img src='images/Like.png' style='padding-top:5px' border='0' /></div></td><td><table width='100%'><tr><td class='paperTitle' style='background-color:white; text-align=left; '><a class='paperTitle' style='padding-left:0;' href='#" + paper_id[0].firstChild.nodeValue + "'>" + paper_title[0].firstChild.nodeValue + "</a></td><td class='paperName' style='margin-right:0; width:200px; background-color:white; text-align:right; vertical-align:text-top;'><span align='right' style='background-color:white; text-align:right; vertical-align:text-top; ' > " + user_real_name[0].firstChild.nodeValue + "</span></td></tr></table></td><td rowspan='2' class='paperLength' style='width:80px; text-align:right; padding-top:8px;' >" + paper_time[0].firstChild.nodeValue + " minutes</td></tr><tr><td class='paperDescription' align='left' colspan='1'>" + paper_desc[0].firstChild.nodeValue + "</td></tr></table>";
container_div.appendChild(summary_div);
}
container_div.innerHTML += "</tr></td></table";
}
}
Here is the XML that's getting returned:
<root>
<paper id="23">
<paper_id>23</paper_id>
<paper_title>title</paper_title>
<paper_desc>
First paragraph of desc
<br/>
<br/>
Second paragraph of desc
<br/>
<br/>
Third paragraph of desc
<br/>
</paper_desc>
<paper_time>45</paper_time>
<user_real_name>Bob Student</user_real_name>
<user_id>2322</user_id>
<category>Languages</category>
</paper>
...
When I push the content to container_div only the first paragraph is showing up. If I stick a Javascript alert() in to return paper_desc it only contains the first paragraph. I've tried looking for other nodes but this says there's only 1 node:
alert(paper_nodes[i].getElementsByTagName("paper_desc").length);
You use paper_desc[0].firstChild.nodeValue
paper_desc[0] is a set of nodes: text nodes and br nodes. You get only the first child of this set, so you get only the first text.
Your alert() call only shows you have only one paper_desc node, not how many nodes you have inside.
I also found strange that you used paper_nodes[1] but I don't know if there is a second node in your XML and if you really want to target it.