Filter xml file using Javascript - javascript

I am trying to rebuild an old application without the loss of data. The current data has all been stored in xml files that i am trying to read using Javascript.
This is the Javascript (i'm new to this, feedback is appreciated):
// Create a connection to the file.
var Connect = new XMLHttpRequest();
// Define which file to open and
// send the request.
Connect.open("GET", "writers.xml", false);
Connect.setRequestHeader("Content-Type", "text/xml");
Connect.send(null);
// Place the response in an XML document.
var TheDocument = Connect.responseXML;
// Place the root node in an element.
var Customers = TheDocument.childNodes[0];
// Retrieve each customer in turn.
for (var i = 0; i < Customers.children.length; i++){
var Customer = Customers.children[i];
//Create div's for data
document.getElementById("body").innerHTML += "<div id='who" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='age" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='hobby" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='image" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='something" + i + "'></div>"
//Assign data to correct divs
var who = Customer.getElementsByTagName("name");
var who2 = who[0].textContent.toString();
document.getElementById("who"+i).innerHTML += who2;
var age = Customer.getElementsByTagName("age");
var age2 = age[0].textContent.toString();
document.getElementById("age"+i).innerHTML += age2;
var hobby = Customer.getElementsByTagName("hobby");
var hobby2 = hobby[0].textContent.toString();
document.getElementById("hobby"+i).innerHTML += hobby2;
var image = Customer.getElementsByTagName("image");
var image2 = image[0].textContent.toString();
document.getElementById("image"+i).innerHTML += image2;
var something = Customer.getElementsByTagName("something");
var something2 = something[0].textContent.toString();
document.getElementById("something"+i).innerHTML += something2;
}
This is an example of my xml file:
<doc>
<person>
<name>Paul</name>
<age>21</age>
<hobby>blabla</hobby>
<image>thisisanimage.jpg</image>
<something>Random string</something>
</person>
<person>
<name>Peter</name>
<age></age>
<hobby>blabla</hobby>
<image>thisisanimage.jpg</image>
<something>Random string</something>
</person>
</doc>
Now i am trying to filter Peter out, because the age field is empty. Anyone got an idea?

The easiest way is to add a condition in the loop, to test if the age is blank. If the age value is blank then the if block will not be entered, and the next iteration of the loop will start.
for (var i = 0; i < Customers.children.length; i++) {
var Customer = Customers.children[i];
var age = Customer.getElementsByTagName("age");
var age2 = age[0].textContent.toString();
if (age2 != '') { // only do the below code if age2 is not blank
//Create div's for data
document.getElementById("body").innerHTML += "<div id='who" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='age" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='hobby" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='image" + i + "'></div>"
document.getElementById("body").innerHTML += "<div id='something" + i + "'></div>"
document.getElementById("age" + i).innerHTML += age2;
//Assign data to correct divs
var who = Customer.getElementsByTagName("name");
var who2 = who[0].textContent.toString();
document.getElementById("who" + i).innerHTML += who2;
var hobby = Customer.getElementsByTagName("hobby");
var hobby2 = hobby[0].textContent.toString();
document.getElementById("hobby" + i).innerHTML += hobby2;
var image = Customer.getElementsByTagName("image");
var image2 = image[0].textContent.toString();
document.getElementById("image" + i).innerHTML += image2;
var something = Customer.getElementsByTagName("something");
var something2 = something[0].textContent.toString();
document.getElementById("something" + i).innerHTML += something2;
}
}

Related

Converting emails to PDF if subject equals "xxxxx" and date equals today

I have written a script which has a trigger to run every hour, it searches my emails and extracts the data, turns it to a PDF and locates it in a folder if the subject equals "xxxx", it overwrites data in the folder if it already exists.. I would like to add in a new if function where it will only pick up emails for the current day and not history (to save efficiency of the script and data)
function saveGmailAsPDF2() {
var gmailLabels = 'xxxxx';
var driveFolder = DriveApp.getFolderById("folder url");
var threads = GmailApp.search("subject:" + gmailLabels,0,20);
if (threads.length > 0) {
/* Google Drive folder where the Files would be saved */
var folders = DriveApp.getFoldersByName(driveFolder);
var folder = folders.hasNext() ?
folders.next() : DriveApp.createFolder(driveFolder);
/* Gmail Label that contains the queue */
var label = GmailApp.getUserLabelByName(gmailLabels) ?
GmailApp.getUserLabelByName(gmailLabels) : GmailApp.createLabel(driveFolder);
for (var t=0; t<threads.length; t++) {
threads[t].removeLabel(label);
var msgs = threads[t].getMessages();
var html = "";
var subject = threads[t].getFirstMessageSubject();
var previousdoc = driveFolder.getFilesByName(subject + ".pdf"); //gets name of csv, if exists in drive then move to trash before creating new file
if (previousdoc.hasNext()) {
previousdoc.next().setTrashed(true);}
/* Append all the threads in a message in an HTML document */
for (var m=0; m<msgs.length; m++) {
var msg = msgs[m];
html += "From: " + msg.getFrom() + "<br />";
html += "To: " + msg.getTo() + "<br />";
html += "Date: " + msg.getDate() + "<br />";
html += "Subject: " + msg.getSubject() + "<br />";
html += "<hr />";
html += msg.getBody().replace(/<img[^>]*>/g,"");
html += "<hr />";}
/* Convert the Email Thread into a PDF File */
var tempFile = DriveApp.createFile("temp.html", html, "text/html");
folder.createFile(tempFile.getAs("application/pdf")).setName(subject + ".pdf");
tempFile.setTrashed(true);}}}
Explanation:
There is a function getLastMessageDate() that gives the date of a thread's most recent message. You can compare that against the date of today and if they match execute the rest of the code.
Since you use a for loop: for (var t=0; t<threads.length; t++)
I think the condition if (threads.length > 0) is redundant because for loop won't run anyway if threads.length equals 0.
Because of the latter, I transferred the folder creation part of your code into the loop itself and execute it only when the last day of the thread is equal to today. But I leave this part for you to decide.
I can't test your code but this should work:
function saveGmailAsPDF2() {
var gmailLabels = 'xxxxx';
var driveFolder = DriveApp.getFolderById("folder url");
var threads = GmailApp.search("subject:" + gmailLabels,0,20);
// new code
const today = new Date();
const ss = SpreadsheetApp.getActive();
const timezone = ss.getSpreadsheetTimeZone();
const today_dt = Utilities.formatDate(today, timezone, 'yyyy-MM-dd');
///////////
for (var t=0; t<threads.length; t++) {
// new code
var lastMessageDate = threads[t].getLastMessageDate();
var thread_dt = Utilities.formatDate(lastMessageDate, timezone, 'yyyy-MM-dd');
if(today_dt==thread_dt){
///////////
/* Google Drive folder where the Files would be saved */
var folders = DriveApp.getFoldersByName(driveFolder);
var folder = folders.hasNext() ?
folders.next() : DriveApp.createFolder(driveFolder);
/* Gmail Label that contains the queue */
var label = GmailApp.getUserLabelByName(gmailLabels) ?
GmailApp.getUserLabelByName(gmailLabels) : GmailApp.createLabel(driveFolder);
threads[t].removeLabel(label);
var msgs = threads[t].getMessages();
var html = "";
var subject = threads[t].getFirstMessageSubject();
var previousdoc = driveFolder.getFilesByName(subject + ".pdf"); //gets name of csv, if exists in drive then move to trash before creating new file
if (previousdoc.hasNext()) {
previousdoc.next().setTrashed(true);}
/* Append all the threads in a message in an HTML document */
for (var m=0; m<msgs.length; m++) {
var msg = msgs[m];
html += "From: " + msg.getFrom() + "<br />";
html += "To: " + msg.getTo() + "<br />";
html += "Date: " + msg.getDate() + "<br />";
html += "Subject: " + msg.getSubject() + "<br />";
html += "<hr />";
html += msg.getBody().replace(/<img[^>]*>/g,"");
html += "<hr />";}
/* Convert the Email Thread into a PDF File */
var tempFile = DriveApp.createFile("temp.html", html, "text/html");
folder.createFile(tempFile.getAs("application/pdf")).setName(subject + ".pdf");
tempFile.setTrashed(true);}}}

How to Log value of all cells in a column on google app scripts

I am trying to get all the values in column L which is indexed as column 11(var check). However I am only getting the value of the first cell in the column and it stops looping through. I have created a comment for a reference.
Could someone please help me?
Please ignore:
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
function myFunction(e) {
var sheet = SpreadsheetApp.openById("1naSWINA8_uxeLUsj0lFntqILyDj2nirb56uvkBel79Y").getSheetByName("CRM Feedback");
var ss = SpreadsheetApp.getActive().getSheetByName("Form Responses 1");
var data = sheet.getRange(4, 1, ss.getLastRow(), ss.getLastColumn()).getValues();
var manager_email = "XXXXX";
for( var i = 0; i< data.length;i++ ) {
var timestamp = data[i][0];
var requesterEmail = data[i][1];
var starRating = data[i][2];
var requestCatergory = data[i][3];
var description = data[i][4];
var label = data[i][5];
var ticketId = data[i][6];
var comment = data[i][7];
var status = data[i][8];
var priority = data[i][9];
var office = data[i][10];
//I am trying to log all the values in column 11
var check = data[i][11];
Logger.log(check)
var checkTimestamp = data[i][0]
if(check == false){
continue;
} else {
var subject = "CT IT feedback - ";
var body = "<body>";
body += "<br><b>Requester email:</b> " + requesterEmail
body += "<br><b>Star Rating:</b> " + starRating
body += "<br><b>Request Category</b> " + requestCatergory
body += "<br><b>Description:</b> " + description
body += "<br><b>label: </b> " + label
body += "<br><b>Ticket ID: </b>" + ticketId
body += "<br><b>Comment: </b>" + comment
body += "<br><b>status: </b>" + status
body += "<br><b>priority:</b> " + priority
body += "<br><b>office: </b>" + office
body += "</body>";
MailApp.sendEmail(manager_email, subject, body, {htmlBody:body})
var sent_string = "sent";
ss.getRange(i + 1, 12).setValue(sent_string)
if (sent_string){
return
}
}
}
}
You want to loop through all data rows and send emails for each row where the status is not set to "sent" yet
You want to set the status of a row to "sent" after sending an email
The problem is that
you have a return statement which makes you exit the for loop and stop iterating
You seem not to change the status for the right sheet and the right row
I suggest you to modify your code as following:
function myFunction(e) {
var sheet = SpreadsheetApp.openById("1naSWINA8_uxeLUsj0lFntqILyDj2nirb56uvkBel79Y").getSheetByName("CRM Feedback");
var ss = SpreadsheetApp.getActive().getSheetByName("Form Responses 1");
var data = sheet.getRange(4, 1, ss.getLastRow(), ss.getLastColumn()).getValues();
var manager_email = "XXX";
for( var i = 0; i< data.length;i++ ) {
var timestamp = data[i][0];
var requesterEmail = data[i][1];
var starRating = data[i][2];
var requestCatergory = data[i][3];
var description = data[i][4];
var label = data[i][5];
var ticketId = data[i][6];
var comment = data[i][7];
var status = data[i][8];
var priority = data[i][9];
var office = data[i][10];
//I am trying to log all the values in column 11
var check = data[i][11];
Logger.log(check)
var checkTimestamp = data[i][0]
if(check != "sent"){
var subject = "CT IT feedback - ";
var body = "<body>";
body += "<br><b>Requester email:</b> " + requesterEmail
body += "<br><b>Star Rating:</b> " + starRating
body += "<br><b>Request Category</b> " + requestCatergory
body += "<br><b>Description:</b> " + description
body += "<br><b>label: </b> " + label
body += "<br><b>Ticket ID: </b>" + ticketId
body += "<br><b>Comment: </b>" + comment
body += "<br><b>status: </b>" + status
body += "<br><b>priority:</b> " + priority
body += "<br><b>office: </b>" + office
body += "</body>";
MailApp.sendEmail(manager_email, subject, body, {htmlBody:body})
var sent_string = "sent";
//are you sure you want to set the stutus in ss and not in sheet to 'sent'?
//Keep in mind that you start with row 4
sheet.getRange(i +4, 12).setValue(sent_string)
}
}
}

address book using json html javascript

I am working on Address book using HTML,CSS and Javascript. First I am reading some data entries from a JSON file. Then storing those entries into local storage. Then I am taking input from the user in few input fields through the function called addToBook(). And then storing all the data in JSON format in the variable called addressBook. But when i am trying to print this data in the function called showaddressBook(). It is not happening as it is showing as Undefined in the chrome console. Refer to this line(console.log(addressBook[i].practice_name);) in the function showaddressBook(). Any idea guys. Thanks in advance.
window.onload = function(){
var quickAddFormDiv = document.querySelector('.quickaddForm');
var AddBtn = document.getElementById('Add');
// Form Fields
var lastname = document.getElementById('lastname');
var firstname = document.getElementById('firstname');
var email = document.getElementById('email');
var specialty = document.getElementById('specialty');
var practicename = document.getElementById('practicename');
// Divs etc.
var addBookDiv = document.querySelector('.addbook');
var addressBook = [];
var people;
localStorage.clear();
//--------------------------------------------------------------------
//To display the contents of JSON file
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(xhttp.responseText);
people = response.people;
//var output = "";
var str1 = '';
for(var i = 0; i <people.length;i++){
str1 += '<div id="entry">';
str1 += '<div id="name"><p>' + people[i].last_name +', '+people[i].first_name+ '</p></div>';
str1 += '<div id="email"><p>' + people[i].email_address + '</p></div>';
str1 += '<div id="practicename"><p>' + people[i].practice_name + '</p></div>';
str1 += '<div id="specialty"><p>' + people[i].specialty + '</p></div>';
str1 += '<div id="del">Delete</div>';
}
for(var i = 0; i < people.length;i++){
var obj = new jsonStructure(people[i].last_name,people[i].first_name,people[i].email_address,people[i].specialty,people[i].practice_name);
addressBook.push(obj);
localStorage['addbook'] = JSON.stringify(addressBook);
}
document.getElementsByClassName("addbook")[0].innerHTML = str1;
}
};
xhttp.open("GET", "people.json", true);
xhttp.send();
//------------------------------------------------------------------------------
AddBtn.addEventListener("click", addToBook);
//var addressBook = [];
addBookDiv.addEventListener("click", removeEntry);
function jsonStructure(lastname,firstname,email,specialty,practicename){
this.lastname = lastname;
this.lastname += ", "+firstname;
this.email = email;
this.specialty = specialty;
this.practicename = practicename;
}
function addToBook(){
var isNull = lastname.value!='' && firstname.value!='' && email.value!='' && specialty.value!='' && practicename.value!='';
if(isNull){
// format the input into a valid JSON structure
var obj = new jsonStructure(lastname.value,firstname.value,email.value,specialty.value,practicename.value);
addressBook.push(obj);
localStorage['addbook'] = JSON.stringify(addressBook);
console.log(localStorage['addbook']);
clearForm();
showaddressBook();
}
}
function removeEntry(e){
// Remove an entry from the addressBook
if(e.target.classList.contains('delbutton')){
var remID = e.target.getAttribute('data-id');
addressBook.splice(remID,1);
localStorage['addbook'] = JSON.stringify(addressBook);
showaddressBook();
}
}
function clearForm(){
var formFields = document.querySelectorAll('.formFields');
for(var i in formFields){
formFields[i].value = '';
}
}
function showaddressBook(){
if(localStorage['addbook'] === undefined){
localStorage['addbook'] = '';
} else {
addressBook = JSON.parse(localStorage['addbook']);
addBookDiv.innerHTML = '';
var str = '';
for(var i = 0; i <addressBook.length;i++){
str += '<div id="entry">';
str += '<div id="name"><p>' + addressBook[i].last_name +', '+addressBook[i].first_name+ '</p></div>';
str += '<div id="email"><p>' + addressBook[i].email_address + '</p></div>';
str += '<div id="practicename"><p>' + addressBook[i].practice_name + '</p></div>';
str += '<div id="specialty"><p>' + addressBook[i].specialty + '</p></div>';
str += '<div id="del">Delete</div>';
console.log(addressBook[i].practice_name);
}
}
}
showaddressBook();
}
There are typo mistakes,
practice_name should be practicename
last_name should be lastname
first_name should be firstname
email_address should be email
Try:
for(var i = 0; i <addressBook.length;i++){
str += '<div id="entry">';
str += '<div id="name"><p>' + addressBook[i].lastname +', '+addressBook[i].firstname+ '</p></div>';
str += '<div id="email"><p>' + addressBook[i].email + '</p></div>';
str += '<div id="practicename"><p>' + addressBook[i].practicename + '</p></div>';
str += '<div id="specialty"><p>' + addressBook[i].specialty + '</p></div>';
str += '<div id="del">Delete</div>';
console.log(addressBook[i].practicename);
}

how to display image through XML to html

Hie i am practicing XML , Javascript. I want to display image for each animal in a row. But my main problem arises uneven nesting in images . Some have two images while some have 4. I have XML File as follows:
<zoo>
<animal>
<common_name>Elephant</common_name>
<images>
<image>elephant13.jpg</image>
</images>
</animal>
<animal>
<common_name>Emu</common_name>
<images>
<image>emu12.jpg</image>
<image>emu26.jpg</image>
<image>emu23.jpg</image>
</images>
</animal>
<animal>
<common_name>Lion</common_name>
<images>
<image>lion51.jpg</image>
<image>lion46.jpg</image>
</images>
</animal>
<zoo>`
My javascript for img is :
for(var y = 0; y < noOfImages ; y++)
{
if (images)
{
images.src ="images/" + zooRoot.getElementsByTagName("image")[i].firstChild.nodeValue;
ul.appendChild(images);
}
}
Try this. This get's the document node of xml and queries for images from it. Once you have the array, you iterate over it and get the inner text from the node.
var xmlimages = xml.getElementsByTagName('image');
for(var i=0; i< xmlimages.length; i++) {
images.src = "images/" + xmlimages[i].innerHTML.trim(); // trim used to remove all the white space from text that you get when you use innerHTML
}
Please insert loop on node:
for(var y = 0; y < noOfImages ; y++)
{
if (images)
{
var imgData = zooRoot.getElementsByTagName("image");
for (i = 0; i <imgData.length; i++) {
images.src ="images/" + imgData[i].firstChild.nodeValue;
ul.appendChild(images);
}
}
}
Try to get Animal as an object, then create a HTMLstring and insert it in node;
var animalsNode = zooRoot.getElementsByTagName('animal');
var animals = [];
for(var i=0; i<animalsNode.length; i++){
var animalName = animalsNode[i].getElementsByTagName("common_name").innerHTML;
var animalImageNodes = animalsNode[i].getElementsByTagName("image");
var animalImages = [];
//will store image paths into animalImages
for(var j=0; j<animalImageNodes.length; j++){
animalImages.push("image/" + animalImageNodes.innerHTML);
}
animals.push({
common_name: animalName,
images: animalImages //array of image urls
})
}
var animalsHTML = function(animals){
//lets cereate string with "html table"
var animalsHtml = "<table>";
for(var i=0; i<animals.length; i++){
animalsHtml += "<tr>";
animalsHtml += "<td>" + animals[i].name + "</td>"
+ "<td><img src='" + animals[i].images[0] + "' /></td>";
animalsHtml += "</tr>";
}
animalsHtml += "</table>";
return animalsHtml;
}
tableNode.innerHTML = animalsHTML(animals);
or you can define animal array more functional way =)
var animals = zooRoot.getElementsByTagName('animal').map(function(animalNode){
return {
common_name: animalNode.getElementsByTagName('common_name')[0].innerHTML,
images: animalNode.getElementsByTagName('image').map(function(imageNode){
return "image/" + imageNode.innerHTML;
})
};
});
//and more js style of draw-function
var animalsHTML = function(animals){
return "<table>" + animals.reduce(function(curr, next){
return curr + "<tr><td>" + next.name + "</td>"
+ "<td>"
+ next.images.reduce(function(c, n){
return c + "<img src='" + n "' />"
},'')
+ "</td>"
+ "</tr>";
}, '') + "</table>";
}
tableNode.innerHTML = animalsHTML(animals);
I didn't test it, but it should work.

Converting Table data to the xml structured data

I stuck the below requirement, Here I have to show all the table data to the xml structured data, I tried with the following, I'm getting xml structure but struggling to show row data with table headers like below
<rowset>
<row name='SequnceNumber'>
<row>Item</row>
<row>Weight</row>
<row>LableNo</row>
<row>Unitcost</row>
<row>Delete</row>
</rowset>
<rowset>
<rowset name='1212121'>
<Item>test1</Item>
<Weight>3000</Weight>
<LableNo>test1</LableNo>
<Unitcost>test1</Unitcost>
<Delete>test1</Delete>
</rowset>
I tried with below code,
$(document).ready(function(){
$("#idXmlData").click(function(){
var xmlStart = "<?xml version=\"1.0\" encoding=\"UTF-8\">";
var xml = xmlStart;
$(".mutliple tr").each(function() {
var cells = $("td", this);
if (cells.length > 0) {
xml +="<rowset name='" + cells.eq(0).text() + "'>\n";
for (var i = 1; i < cells.length; ++i) {
//var tableHeaders=["SequnceNumber","Item","Weight","LableNo","Unitcost","Delete"];
//for(var j=0;j<tableHeaders.length;j++){
// xml += "\t<"+j+">" + cells.eq(i).text() + "</"+j+">\n";
xml += "\t<row>" + cells.eq(i).text() + "</row>\n";
//}
}
xml += "</rowset>\n";
}
});
window.alert(xml);
});
});
JS fiddle
It will be a bit easier if you format your table to include header with th as you can see in the following code, because separating header text from other rows is going to make things a bit simpler.
Here's JS for that :
$("#idXmlData").click(function(){
var xmlStart = "<?xml version=\"1.0\" encoding=\"UTF-8\">";
var xml = xmlStart;
var xmlFirstRowSet = "<rowset><row name='";
var thArray = new Array();
$('th').each( function(index) {
thArray[index] = $(this).html();
});
xmlFirstRowSet = xmlFirstRowSet + thArray[0] + "'>";
var headerRowSet='';
for(var i=1; i< thArray.length; i++) {
headerRowSet = headerRowSet + "<row>" + thArray[i] + "</row>";
}
headerRowSet = headerRowSet + "</rowset>";
xmlFirstRowSet = xmlFirstRowSet + headerRowSet;
var bodyRowSet ='';
$(".mutliple tbody tr").each(function() {
bodyRowSet = bodyRowSet + "<rowset name='" + $(this).find('td').html() + "'>";
$(this).find('td:not(:first-child)').each(function() {
$td = $(this);
var tdValue = $(this).html();
var $th = $td.closest('table').find('th').eq($td.index()).html();
bodyRowSet = bodyRowSet + "<" + $th + ">" + tdValue + "</" + $th + ">";
});
bodyRowSet = bodyRowSet + "</rowset>";
});
xml = xmlStart + xmlFirstRowSet + bodyRowSet;
console.log(xml);
window.alert(xml);
});
Here's a working Fiddle

Categories