javascript .addclass for each date between start and end - javascript

I am using a JQuery eventcalendar plugin from this website.
My events have a start and end date and I have the following code which adds a green square on the calendar (one for the start date and one for the end date).
The bit I am struggling with is how to add a green square for each date between the start and end date.
eg start date - > 12-08-2012
end date -> 15-08-12
Would highlight 12th 13th 14th and 15th
var eventDate = new Date(parseInt(event.startdate)),
eventYear = eventDate.getFullYear(),
eventMonth = eventDate.getMonth(),
eventDay = eventDate.getDate();
var eventDate1 = new Date(parseInt(event.enddate)),
eventYear1 = eventDate1.getFullYear(),
eventMonth1 = eventDate1.getMonth(),
eventDay1 = eventDate1.getDate();
// add mark in the dayList to the days with events
if (eventYear == flags.wrap.attr('data-current-year') && eventMonth == flags.wrap.attr('data-current-month')) {
flags.wrap.find('.currentMonth .eventsCalendar-daysList #dayList_' + eventDay).addClass('dayWithEvents');
}
if (eventYear1 == flags.wrap.attr('data-current-year') && eventMonth1 == flags.wrap.attr('data-current-month')) {
flags.wrap.find('.currentMonth .eventsCalendar-daysList #dayList_' + eventDay1).addClass('dayWithEvents');
}

I've just made the same enhancement (still fine tuning it actually), and I used datejs for the date matching. I've ported the calendar plugin to a github repo while I work on it, but this enhancement hasn't yet been pushed to it. If you're still interested in an answer, I can hurry up and finish it and provide the link - however it goes something like this:
var daysElement = $element.find('.currentMonth .eventsCalendar-daysList');
var dateToBeChecked = new Date(parseInt(event.startDate));
var endDate = new Date(parseInt(event.endDate));
while (dateToBeChecked.compareTo(endDate) <=0) {
daysElement.find('#dayList_' + dateToBeChecked.getDate())
.addClass('dayWithEvents');
dateToBeChecked.addDays(1);
}
(Note that the "fine tuning" involves handling events that exist in 2 different calendar months, etc.)

I made something similar for the same script, whenever mouse-over the date that contains an end-date:
// add mark in the dayList to the days with events
if (eventYear == flags.wrap.attr('data-current-year') && eventMonth == flags.wrap.attr('data-current-month')) {
flags.wrap.find('.currentMonth .eventsCalendar-daysList #dayList_' + parseInt(eventDay)).addClass('list-group-item-success');
if (event.date_end) {
$('#dayList_' + parseInt(eventDay)).hover(
function () {
$('#dayList_' + parseInt(eventDay)).nextUntil('#dayList_' + parseInt(eventDayEnd)).andSelf().add('#dayList_' + parseInt(eventDayEnd)).addClass('list-group-item-danger');
},
function () {
$('#dayList_' + parseInt(eventDay)).nextUntil('#dayList_' + parseInt(eventDayEnd)).andSelf().add('#dayList_' + parseInt(eventDayEnd)).removeClass('list-group-item-danger');
}
);
}
Before the above will work, there are some modifications needed.
In the part where each data is generated:
$.each(data, function(key, event) {
i added some extra code: (first IF)
if (event.date_end) {
var eventDateTimeEnd = event.date_end.split(" "),
eventDateEnd = eventDateTimeEnd[0].split("-"),
eventTimeEnd = eventDateTimeEnd[1].split(":"),
eventYearEnd = eventDateEnd[0],
eventMonthEnd = parseInt(eventDateEnd[1]) - 1,
eventDayEnd = parseInt(eventDateEnd[2]),
//eventMonthToShow = eventMonth,
eventMonthToShowEnd = parseInt(eventMonthEnd) + 1,
eventHourEnd = eventTimeEnd[0],
eventMinuteEnd = eventTimeEnd[1],
eventSecondsEnd = eventTimeEnd[2],
eventDateEnd = new Date(eventYearEnd, eventMonthEnd, eventDayEnd, eventHourEnd, eventMinuteEnd, eventSecondsEnd);
}
Second IF
if (event.date_end) {
var eventDateEnd = new Date(parseInt(event.date_end)),
eventYearEnd = eventDateEnd.getFullYear(),
eventMonthEnd = eventDateEnd.getMonth(),
eventDayEnd = eventDateEnd.getDate(),
eventMonthToShowEnd = eventMonthEnd + 1,
eventHourEnd = eventDateEnd.getHours(),
eventMinuteEnd = eventDateEnd.getMinutes();
}
As you can see i took the same code and just give it a new naming for each var, just added End to each var.
Then of course when push the event data you need to identify if the data contains an end date.
the formating you using will be different as yours, i made this script working with Bootstrap 3.10
if (event.date_end) {
events.push('<li id="' + key + '" class="list-group-item '+event.type+'"><time datetime="'+eventDate+'"><em>' + eventStringDate + '</em><small>'+eventHour+":"+eventMinute+'</small></time>----TILL-----<time datetime="'+eventDateEnd+'"><em>' + eventStringDateEnd + '</em><small>'+eventHourEnd+":"+eventMinuteEnd+'</small></time>'+eventTitle+'<p class="eventDesc ' + eventDescClass + '">' + event.description + '</p></li>');
}else{
events.push('<li id="' + key + '" class="list-group-item '+event.type+'"><time datetime="'+eventDate+'"><em>' + eventStringDate + '</em><small>'+eventHour+":"+eventMinute+'</small></time>'+eventTitle+'<p class="eventDesc ' + eventDescClass + '">' + event.description + '</p></li>');
}
In the generated Json i added a new field:
{
"date": "1394233485248",
"type": "demo",
"title": "Project B demo",
"description": "Lorem ipsum dolor.",
"url": "http://www.event2.com/",
"date_end": "1402891200000"
},
If anyone wants to help to retrieve the data from mysql/pdo database.... leave me a message.

Related

Am I using isNaN() incorrectly? Very strange (Google Ads) Javascript code - always fails in the first execution but succeeds in subsequent tries

The code below is a Google Ads script. It does a fairly simple thing: it grabs the ad group impression share values from any 2 given periods, and issues an alert for ad groups whose impression share values dropped by more than 10% between the "pre" and "post" periods. More details are in the comments in the code.
Here's the really, really weird part: everytime I preview the code (by pressing the "Preview" button in the Google Ads script console), it always fails the first time, but then in subsequent tries (2nd, 3rd, etc) it always works.
If I go back to the Google Ads main "Scripts" page and then open the script and preview it again, it seems to get "reset" and fails again, and then succeeds in the 2nd try onwards.
The exact error is: "TypeError: Cannot read property 'preImpressionShare' of undefined".
According to the Google Ads script console, the line that causes the error is the following:
if ((!isNaN(adgroup.preImpressionShare)))
My questions are:
One would think that if the code is wrong, it should always fail. Yet, it works most of the time, and only fails in the first try. Why is it unstable like that?
How do I fix the error so that it will always work? Is the isNaN() function being used incorrectly or what?
var config = {
campaignsContain: '', // The script will only look for campaigns that contain this string - leave blank to work on all campaigns
imprShareDropThreshold: 0.1, // The percent change to trigger an alert (0.1 = 10% change)
emails: 'email#myemail.com', // Comma-separated list of emails to alert
}
function main() {
/*Date settings for the "pre" period.*/
var preStartDate = new Date('January 1, 2022');
var preFormattedStartDate = Utilities.formatDate(preStartDate, AdsApp.currentAccount().getTimeZone(), 'EEE, MMM d, YYYY');
preStartDate = Utilities.formatDate(preStartDate, AdsApp.currentAccount().getTimeZone(), 'YYYYMMdd');
var preEndDate = new Date('January 31, 2022');
var preFormattedEndDate = Utilities.formatDate(preEndDate, AdsApp.currentAccount().getTimeZone(), 'EEE, MMM d, YYYY');
preEndDate = Utilities.formatDate(preEndDate, AdsApp.currentAccount().getTimeZone(), 'YYYYMMdd');
/*Date settings for the "post" period.*/
var postStartDate = new Date('February 1, 2022');
var postFormattedStartDate = Utilities.formatDate(postStartDate, AdsApp.currentAccount().getTimeZone(), 'EEE, MMM d, YYYY');
postStartDate = Utilities.formatDate(postStartDate, AdsApp.currentAccount().getTimeZone(), 'YYYYMMdd');
var postEndDate = new Date('February 28, 2022');
var postFormattedEndDate = Utilities.formatDate(postEndDate, AdsApp.currentAccount().getTimeZone(), 'EEE, MMM d, YYYY');
postEndDate = Utilities.formatDate(postEndDate, AdsApp.currentAccount().getTimeZone(), 'YYYYMMdd');
/*GAQL setup for the "pre" period query*/
var preCampaignFilter = config.campaignsContain.length > 0 ? ' AND CampaignName CONTAINS "' + config.campaignsContain + '" ' : '';
var preQuery = 'SELECT AdGroupId, CampaignName, AdGroupName, SearchImpressionShare FROM ADGROUP_PERFORMANCE_REPORT WHERE AdGroupStatus = ENABLED ' + 'DURING ' + preStartDate + ',' + preEndDate;
var preReport = AdsApp.report(preQuery);
var preAdgroups = [];
var preRows = preReport.rows();
/*GAQL setup for the "post" period query*/
var postCampaignFilter = config.campaignsContain.length > 0 ? ' AND CampaignName CONTAINS "' + config.campaignsContain + '" ' : '';
var postQuery = 'SELECT AdGroupId, CampaignName, AdGroupName, SearchImpressionShare FROM ADGROUP_PERFORMANCE_REPORT WHERE AdGroupStatus = ENABLED ' + 'DURING ' + postStartDate + ',' + postEndDate;
var postReport = AdsApp.report(postQuery);
var postAdgroups = [];
var postRows = postReport.rows();
/*Traverse the "pre" period query results, and add them to an array.*/
while (preRows.hasNext()) {
var preRow = preRows.next();
var preAdgroupid = preRow.AdGroupId;
var preAdgroup = preRow.AdGroupName;
var preCampaign = preRow.CampaignName;
var preImpressionShare = parseFloat(preRow.SearchImpressionShare.replace('%', '')) / 100;
let preAdGroupObject = {};
preAdGroupObject.adgroupid = preAdgroupid;
preAdGroupObject.adgroup = preAdgroup;
preAdGroupObject.campaign = preCampaign;
preAdGroupObject.preImpressionShare = preImpressionShare;
preAdgroups.push(preAdGroupObject);
}
/*Traverse the "post" period query results, and add them to an array.*/
while (postRows.hasNext()) {
var postRow = postRows.next();
var postAdgroupid = postRow.AdGroupId;
var postAdgroup = postRow.AdGroupName;
var postCampaign = postRow.CampaignName;
var postImpressionShare = parseFloat(postRow.SearchImpressionShare.replace('%', '')) / 100;
let postAdGroupObject = {};
postAdGroupObject.adgroupid = postAdgroupid;
postAdGroupObject.adgroup = postAdgroup;
postAdGroupObject.campaign = postCampaign;
postAdGroupObject.postImpressionShare = postImpressionShare;
//if(postImpressionShare > 0.1) {
postAdgroups.push(postAdGroupObject);
//}
}
/*Merge the "pre" query results with the "post" query results* and store everything into one single array*/
mergedAdGroups = mergeArrayObjects(preAdgroups, postAdgroups);
//Traverse the "mergedAdGroups" array and calculate the impression share difference between the pre vs. post period.
//Add the results to the "alerts" array only if the impression share difference is less than the threshold (10%)
var alerts = [];
mergedAdGroups.forEach(
function(adgroup)
{
if ((!isNaN(adgroup.preImpressionShare)))
{
//Logger.log(adgroup.preImpressionShare + " and " + adgroup.postImpressionShare);
var difference = (adgroup.postImpressionShare - adgroup.preImpressionShare) / adgroup.preImpressionShare;
//campaigns[campaign].difference = difference;
if (difference < -config.imprShareDropThreshold)
{
alerts.push(' - ' + adgroup.adgroup + " of the campaign " + adgroup.campaign + ': from ' + (adgroup.preImpressionShare * 100).toFixed(2) + '% to ' + (adgroup.postImpressionShare * 100).toFixed(2) +'%' + " [" + (difference * 100).toFixed(2) + '%' + " drop.]");
}
}
}
);
//Combine an intro message for the email alert with the contents of the "alerts" variable (see above) and store everything into the "message" variable.
var message =
'The following campaigns had impression share drops by more than ' + (Math.abs(config.imprShareDropThreshold) * 100).toFixed(2) + '% between the pre and post period' + '. \n\n' +
alerts.join('\n') + '\n\n' +
'---END OF MESSAGE---';
//This is for debugging (to see the results in the Google Ads script console)
//Logger.log(message);
//This line passes the "message" variable and sends it as an email alert.
//if (alerts.length > 0) {MailApp.sendEmail(config.emails, 'Impression Share Drop Alert!', message);}
}
//This function merges 2 arrays based on common adgroup IDs
function mergeArrayObjects(arr1,arr2){
return arr1.map((item,i)=>{
if(item.adgroupid === arr2[i].adgroupid){
//merging two objects
return Object.assign({},item,arr2[i])
}
})
}

vis.js building a dataset dynamically

I'm working on a project and have a need/desire to use vis.js to display data on a timeline. But, because of how the data is being captured, I need to build the dataset for the timeline somewhat dynamically when the page loads. With that in mind, I started experimenting with ways to do this, but have hit a roadblock that is mostly likely due to my own lack of knowledge.
The following is the test code I've been working with (I'm aware it is not the best or cleanest code. I'm focusing on functionality at the moment, but if you have suggestions for cleaning this up, I'm all ears!) What I want to do is use the content from the variable datasetlist to build the dataset. But when I simply try to pass that variable to new vis.DataSet, it doesn't build the visualization. I'd appreciate any guidance anyone may be able to offer. I was wondering if I needed to transform that variable in some way for vis.js to accept it, but haven't been able to figure out if that is indeed the case, and if so, how.
var ERP = "yes";
var ERPDate = "2018";
var CRM = "no";
var CRMDate = "2019";
var IDSeq = 1;
var datasetlist = "";
var yesCount = 0
//count totalitems
if (ERP == "yes") {
yesCount = (yesCount + 1);
}
if (CRM == "yes") {
yesCount = (yesCount + 1);
}
//builddataset
if (ERP == "yes"){
if (yesCount == IDSeq) {
datasetlist = datasetlist + "{id: " + IDSeq + ", content: \'ERP\', start: \'" + ERPDate + "\'}";
} else {
datasetlist = datasetlist + "{id: " + IDSeq + ", content: \'ERP\', start: \'" + ERPDate + "\'},";
}
IDSeq = IDSeq +1
}
if (CRM == "yes"){
if (yesCount == IDSeq) {
datasetlist = datasetlist + "{id: " + IDSeq + ", content: \'CRM\', start: \'" + CRMDate + "\'}";
} else {
datasetlist = datasetlist + "{id: " + IDSeq + ", content: \'CRM\', start: \'" + CRMDate + "\'},";
}
}
//datasetlist = "{id: 1, content: 'ERP', start: '2018'}"
//window.alert(datasetlist);
// DOM element where the Timeline will be attached
var container = document.getElementById('visualization');
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet(datasetlist);
// Configuration for the Timeline
var options = {
height: '500px',
start: new Date(2015, 1, 15),
end: new Date(2025, 1, 15),
timeAxis: {scale: 'year', step: 1}
};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
Vis expects an array of items as the dataset. Something like this,var data = new vis.DataSet([data]) where [data] is an array of objects. So try building your objects and pushing them into an array and then pass that in as the data parameter. The documentation can be found here http://visjs.org/docs/data/dataset.html.

Javascript How to SetTimeOut while getting a list of files with Scripting.FileSystemObject

This code is for internal, offline, single user use, IE only. The code looks at a folder, and lists all files including those in subfolders. It sorts through the data based on some date fields and datelastmodified. It also uses and if to throw out thumbs.db entries. All of the data is put into a table.
My issue is that this script can take a long time to get the data. I would like to add a progress bar but the progress bar cant update while the script is running. After some research it looks like SetTimeOut can allow the page elements to be updated as the script runs, therefore allowing the progress bar to work and looking overall cleaner. However I can not figure out of to implement SetTimeOut into my existing code.
<script type="text/javascript">
var fso = new ActiveXObject("Scripting.FileSystemObject");
function ShowFolderFileList(folderspec) {
var beginningdate = new Date(startdate.value);
var finishdate = new Date(enddate.value);
var s = "";
var f = fso.GetFolder(folderspec);
var subfolders = new Enumerator(f.SubFolders);
for (subfolders.moveFirst(); !subfolders.atEnd(); subfolders.moveNext()) {
s += ShowFolderFileList(subfolders.item().path);
}
// display all file path names.
var fc = new Enumerator(f.files);
for (i = 0; !fc.atEnd(); fc.moveNext()) {
if (fc.item().name != "Thumbs.db") {
var dateModified = fc.item().DatelastModified;
if (dateModified >= beginningdate && dateModified <= finishdate) {
Date.prototype.toDateString = function () {
return [this.getMonth() + 1, '/', this.getDate(), '/', this.getFullYear()].join('');
}
var dateModifiedClean = (new Date(fc.item().DatelastModified).toDateString());
s += "<table border=0 width=100% cellspacing=0><tr " + ((i % 2) ? "" : "bgcolor=#EBF1DE") + "><td width=75%><font class=find><b>" + fc.item().ParentFolder.name + "</b>" + " - " + fc.item().name + "</font></td><td width=25% align=right><font class=find>" + dateModifiedClean + "</font></td></tr>";
i++;
}
}
}
var results = s + "</table>";
return results;
}
function listFiles() {
outPut.innerHTML = ShowFolderFileList('*Path to scan*');
}
</script>
outPut is the ID of a div tag where the results table is displayed. A button calls the listfiles function.

Merging multiple Google calendar feeds into one JSON object in javascript

I am trying to bring in the JSON feeds from multiple Google calendars so that I can sort the upcoming events and display the next X number in an "Upcoming Events" list.
I have this working with Yahoo! pipes but I want to get away from using a 3rd party to aggregate. I think I am close, but I cannot get the JSON objects created correctly. I am getting the data into the array but not in JSON format, so I can't manipulate it.
I have tried var myJsonString = JSON.stringify(JSONData); using https://github.com/douglascrockford/JSON-js but that just threw errors. I suspect because my variable is in the wrong starting format. I have tried just calling the feed like: $.getJSON(url); and creating a function concant1() to do the JSONData=JSONData.concat(data);, but it doesn't fire and I think it would produce the same end result anyway. I have also tried several other methods of getting the end result I want with varying degrees of doom. Here is the closest I have come so far:
var JSONData = new Array();
var urllist = ["https://www.google.com/calendar/feeds/dg61asqgqg4pust2l20obgdl64%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1","https://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1","http://www.google.com/calendar/feeds/rine4umu96kl6t46v4fartnho8%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1"];
urllist.forEach(function addFeed(url){
alert("The URL being used: "+ url);
if (void 0 != JSONData){JSONData=JSONData.concat($.getJSON(url));}
else{JSONData = $.getJSON(url);}
alert("The count from concantonated JSONData: "+JSONData.length);
});
document.write("The final count from JSONData: "+JSONData.length+"<p>");
console.log(JSONData)
UPDATE:
Now with full working source!! :) If anyone would like to make suggestions on how to improve the code's efficiency it would be gratefully accepted. I hope others find this useful.:
// GCal MFA - Google Calendar Multiple Feed Aggregator
// Useage: GCalMFA(CIDs,n);
// Where 'CIDs' is a list of comma seperated Google calendar IDs in the format: id#group.calendar.google.com, and 'n' is the number of results to display.
// While the contained console.log(); outputs are really handy for testing, you will probably want to remove them for regular usage
// Author: Jeramy Kruser - http://jeramy.kruser.me
// This is error-checking code for IE and can be removed
// onerror=function (d, f, g){alert (d+ "\n"+ f+ "\n");}
// This keeps IE from complaining about console.log and can be removed if all the console.log testing statements are removed
// if (!window.console) {console = {log: function() {}};}
// Add a tag to your page to identify it as js-enabled for CSS purposes
document.body.className += ' js-enabled';
// Global variables
var urllist = [];
var maxResults = 3; // The default is 3 results unless a value is sent
var JSONData = {};
var eventCount = 0;
var errorLog = "";
JSONData = { count: 0,
value : {
description: "Aggregates multiple Google calendar feeds into a single sorted list",
generator: "StackOverflow communal coding - Thanks for the assist Patrick M",
website: "http://jeramy.kruser.me",
author: "Jeramy & Kasey Kruser",
items: []
}};
// Prototype forEach required for IE
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
}
}
// For putting dates from feed into a format that can be read by the Date function for calculating event length.
function parse (str) {
// validate year as 4 digits, month as 01-12, and day as 01-31
str = str.match (/^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/);
if (str) {
// make a date
str[0] = new Date ( + str[1], + str[2] - 1, + str[3]);
// check if month stayed the same (ie that day number is valid)
if (str[0].getMonth () === + str[2] - 1) {
return str[0];
}
}
return undefined;
}
//For outputting to HTML
function output() {
var months, day_in_ms, summary, i, item, eventlink, title, calendar, where,dtstart, dtend, endyear, endmonth, endday, startyear, startmonth, startday, endmonthdayyear, eventlinktitle, startmonthday, length, curtextval, k;
// Array of month names from numbers for page display.
months = {'0':'January', '1':'February', '2':'March', '3':'April', '4':'May', '5':'June', '6':'July', '7':'August', '8':'September', '9':'October', '10':'November', '11':'December'};
// For use in calculating event length.
day_in_ms = 24 * 60 * 60 * 1000;
// Instantiate HTML Arrays.
summary = [];
for (i = 0; i < maxResults; i+=1 ) {
// console.log("i: "+i+" < "+"maxResults: "+ maxResults);
if (!(JSONData.value.items[i] === undefined)) {
item = JSONData.value.items[i];
// Grabbing data for each event in the feed.
eventlink = (item.link[0].href);
title = item.title.$t;
// Only display the calendar title if there is more than one
calendar = "";
if (urllist.length > 1) {
calendar = '<br />Calendar: <a href="https://www.google.com/calendar/embed?src=' + item.gd$who[0].email + '&ctz=America/New_York">' + item.gd$who[0].valueString + '<\/a> (<a href="https://www.google.com/calendar/ical/' + item.gd$who[0].email + '/public/basic.ics">iCal<\/a>)';
}
// Grabbing event location, if entered.
if ( item.gd$where[0].valueString !== "" ) {
where = '<br />' + (item.gd$where[0].valueString);
}
else {
where = ("");
}
// Grabbing start date and putting in form YYYYmmdd. Subtracting one day from dtend without a specified end time (which contains colons) to fix Google's habit of ending an all-day event at midnight on the following day.
dtstart = new Date(parse(((item.gd$when[0].startTime).substring(0,10)).replace(/-/g,"")));
if((item.gd$when[0].endTime).indexOf(':') === -1) {
dtend = new Date(parse(((item.gd$when[0].endTime).substring(0,10)).replace(/-/g,"")) - day_in_ms);
}
else {
dtend = new Date(parse(((item.gd$when[0].endTime).substring(0,10)).replace(/-/g,"")));
}
// Put dates in pretty form for display.
endyear = dtend.getFullYear();
endmonth = months[dtend.getMonth()];
endday = dtend.getDate();
startyear = dtstart.getFullYear();
startmonth = months[dtstart.getMonth()];
startday = dtstart.getDate();
//consolidate some much-used variables for HTML output.
endmonthdayyear = endmonth + ' ' + endday + ', ' + endyear;
eventlinktitle = '<a href="' + eventlink + '">' + title + '<\/a>';
startmonthday = startmonth + ' ' + startday;
// Calculates the number of days between each event's start and end dates.
length = ((dtend - dtstart) / day_in_ms);
// HTML for each event, depending on which div is available on the page (different HTML applies). Only one div can exist on any one page.
if (document.getElementById("homeCalendar") !== null ) {
// If the length of the event is greater than 0 days, show start and end dates.
if ( length > 0 && startmonth !== endmonth && startday === endday ) {
summary[i] = ('<h3>' + eventlink + '">' + startmonthday + ', ' + startyear + ' - ' + endmonthdayyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is greater than 0 and begins and ends within the same month, shorten the date display.
else if ( length > 0 && startmonth === endmonth && startyear === endyear ) {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + '-' + endday + ', ' + endyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is greater than 0 and begins and ends within different months of the same year, shorten the date display.
else if ( length > 0 && startmonth !== endmonth && startyear === endyear ) {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + ' - ' + endmonthdayyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is less than one day (length < = 0), show only the start date.
else {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + ', ' + startyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
}
else if (document.getElementById("allCalendar") !== null ) {
// If the length of the event is greater than 0 days, show start and end dates.
if ( length > 0 && startmonth !== endmonth && startday === endday ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ', ' + startyear + ' - ' + endmonthdayyear + where + calendar + '<\/li>'); }
// If the length of the event is greater than 0 and begins and ends within the same month, shorten the date display.
else if ( length > 0 && startmonth === endmonth && startyear === endyear ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + '-' + endday + ', ' + endyear + where + calendar + '<\/li>'); }
// If the length of the event is greater than 0 and begins and ends within different months of the same year, shorten the date display.
else if ( length > 0 && startmonth !== endmonth && startyear === endyear ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ' - ' + endmonthdayyear + where + calendar + '<\/li>'); }
// If the length of the event is less than one day (length < = 0), show only the start date.
else {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ', ' + startyear + where + calendar + '<\/li>'); }
}
}
if (summary[i] === undefined) { summary[i] = "";}
// console.log(summary[i]);
}
// console.log(JSONData);
// Puts the HTML into the div with the appropriate id. Each page can have only one.
if (document.getElementById("homeCalendar") !== null ) {
curtextval = document.getElementById("homeCalendar");
// console.log("homeCalendar: "+curtextval);
}
else if (document.getElementById("oneCalendar") !== null ) {
curtextval = document.getElementById("oneCalendar");
// console.log("oneCalendar: "+curtextval);
}
else if (document.getElementById("allCalendar") !== null ) {
curtextval = document.getElementById("allCalendar");
// console.log("allCalendar: "+curtextval.innerHTML);
}
for (k = 0; k<maxResults; k+=1 ) { curtextval.innerHTML = curtextval.innerHTML + summary[k]; }
if (JSONData.count === 0) {
errorLog += '<div id="noEvents">No events found.</div>';
}
if (document.getElementById("homeCalendar") === null ) {
curtextval.innerHTML = '<ul>' + curtextval.innerHTML + '<\/ul>';
}
if (errorLog !== "") {
curtextval.innerHTML += errorLog;
}
}
// For taking in each feed, breaking out the events and sorting them into the object by date
function sortFeed(event) {
var tempEntry, i;
tempEntry = event;
i = 0;
// console.log("*** New incoming event object #"+eventCount+" ***");
// console.log(event.title.$t);
// console.log(event);
// console.log("i = " + i + " and maxResults " + maxResults);
while(i<maxResults) {
// console.log("i = " + i + " < maxResults " + maxResults);
// console.log("Sorting event = " + event.title.$t + " by date of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
if (JSONData.value.items[i]) {
// console.log("JSONData.value.items[" + i + "] exists and has a startTime of " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,""));
if (event.gd$when[0].startTime.substring(0,10).replace(/-/g,"")<JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"")) {
// console.log("The incoming event value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " is < " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,""));
tempEntry = JSONData.value.items[i];
// console.log("Existing JSONData.value.items[" + i + "] value " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " stored in tempEntry");
JSONData.value.items[i] = event;
// console.log("Position JSONData.value.items[" + i + "] set to new value: " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
event = tempEntry;
// console.log("Now sorting event = " + event.title.$t + " by date of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
}
else {
// console.log("The incoming event value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " is > " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " moving on...");
}
}
else {
JSONData.value.items[i] = event;
// console.log("JSONData.value.items[" + i + "] does not exist so it was set to the Incoming value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
i = maxResults;
}
i += 1;
}
}
// For completing the aggregation
function complete(result) {
// Track the number of calls completed back, we're not done until all URLs have processed
if( complete.count === undefined ){
complete.count = urllist.length;
}
// console.log("complete.count = "+complete.count);
// console.log(result.feed);
if(result.feed.entry){
JSONData.count = maxResults;
// Check each incoming item against JSONData.value.items
// console.log("*** Begin Sorting " + result.feed.entry.length + " Events ***");
// console.log(result.feed.entry);
result.feed.entry.forEach(
function(event){
eventCount += 1;
sortFeed(event);
}
);
}
if( (complete.count-=1)<1 ) {
// console.log("*** Done Sorting ***");
output();
}
}
// This is the main function. It takes in the list of Calendar IDs and the number of results to display
function GCalMFA(list,results){
var i, calPreProperties, calPostProperties1, calPostProperties2;
calPreProperties = "https://www.google.com/calendar/feeds/";
calPostProperties1 = "/public/full?max-results=";
calPostProperties2 = "&orderby=starttime&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=?";
if (list) {
if (results) {
maxResults = results;
}
urllist = list.split(',');
for (i = 0; i < urllist.length; i+=1 ){
// console.log(urllist[i]);
if (urllist[i] === ""){ urllist.splice(i,1);}
else{
urllist[i] = calPreProperties + urllist[i] + calPostProperties1+maxResults+calPostProperties2;}
}
// console.log("There are " + urllist.length + " URLs");
urllist.forEach(function addFeed(url){
$.getJSON(url, complete);
});
}
else {
errorLog += '<div id="noURLs">No calendars have been selected.</div>';
output();
}
}
All right, here's the gist of what needs to change.
Updated fiddle: http://jsfiddle.net/ynuQ5/2/
Don't concat on the return value of $.getJSON. As I mentioned above, that gets you the XMLHttpRequest object, which is a lot more than the data you're interested in. Critically, however, at that point the request hasn't been made and the data isn't available yet.
Instead, handle it in callback for the AJAX request. I updated your URL list to use &callback=?, initialize the JSONData var to look more like the structure in your 2nd screenshot and then changed the javascript for the AJAX requests to this:
var JSONData = { count: 0,
value : {
description: "Calendars from the Unitarian Universalist Association (UUA.org)",
generator: "StackOverflow communal coding",
items: []
}};
// url list declaration goes here
urllist.forEach(function addFeed(url){
$.getJSON(url, function(result) {
if(!result.feed.entry) {
console.log("No entries from " + url);
return;
}
JSONData.count += result.feed.entry.length;
JSONData.value.items = JSONData.value.items.concat(result.feed.entry);
console.log(JSONData);
});
});
Right away you'll notice there are still some discrepancies between the raw data you get back from google and the data provided by the Yahoo pipe transform. Noticeably, a lot of their provided values have been transformed from objects to texts. For example, google gives us this:
id: Object
$t: "http://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full/bbidp5qb4vh5vk9apok1cpnino_20130119"
link: Array[2]
0: Object
href: "https://www.google.com/calendar/event?eid=YmJpZHA1cWI0dmg1dms5YXBvazFjcG5pbm9fMjAxMzAxMTkgNW9jM2t2cDdsbnU1cmQ0a3JnMnNrY3UybmdAZw"
rel: "alternate"
title: "alternate"
type: "text/html"
1: Object
length: 2
published: Object
$t: "2012-11-13T15:59:31.000-05:00"
title: Object
$t: "30 Days of Love"
type: "text"
updated: Object
$t: "2012-11-13T15:59:31.000-05:00"
Where as your yahoo transform returns data more like this:
id: "http://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full/bbidp5qb4vh5vk9apok1cpnino_20130119"
link: "href: "https://www.google.com/calendar/event?eid=YmJpZHA1cWI0dmg1dms5YXBvazFjcG5pbm9fMjAxMzAxMTkgNW9jM2t2cDdsbnU1cmQ0a3JnMnNrY3UybmdAZw"
published: "2012-11-13T15:59:31.000-05:00"
title: "30 Days of Love"
updated: "2012-11-13T15:59:31.000-05:00"
You can transform the data more when you receive it. Or you can modify your display code to use the more convoluted, raw values.
Let me know if I can clear anything up in my code or response.
Edit: Updated fiddle showing how to access author (aka feed name, apparently), start time and title: http://jsfiddle.net/ynuQ5/8/
Let me know if there's more specific stuff you want out of it :-)

Displaying tweets in my website using my timezone

I am able to display my tweets in my website using the JavaScript below.
window.onload = function() {
var siteName = 'xyz';
$.getJSON(
'http://search.twitter.com/search.json?callback=?&rpp=20&q=from:' + siteName,
function(data) {
$.each(data, function(i, tweets) {
for (var num = 0, len = tweets.length; num < len; num++) {
if (tweets[num].text !== undefined) {
$('ul#tweets').append('<li><b>' + tweets[num].created_at.substring(0, 16) +
':</b> ' + tweets[num].text + '</li>');
}
}
});
}
);
};
This displays the tweets in US time. Is it possible to show the tweets in NZ time.
I found an easy solution to my problem. Just creating a new Date object (var tim = new Date(tweets[num].created_at)) did the trick. Here is the code which give shows date and time of tweets in my timezone.
window.onload = function() {
var siteName = 'xyz';
$.getJSON(
'http://search.twitter.com/search.json?callback=?&rpp=20&q=from:' + siteName,
function(data) {
$.each(data, function(i, tweets) {
for (var num = 0, len = tweets.length; num < len; num++) {
if (tweets[num].text !== undefined) {
var tim = new Date(tweets[num].created_at);
$('ul#tweets').append('<li><b>' + tim.toString().substring(0, 24) + ':</b> ' + tweets[num].text + '</li>');
}
}
});
}
);
};
I think, the var tim = new Data(tweets[num].created_at) constructor is taking the date from tweets[num].created_at and converting it to local timezone (my machine time) and constructing a new object tim. So the new object tim has local time.
Can anyone please point me to the documentation of the Date(dateString) constructor.
Yes. You can change the timezone.
The following js code snippet was found from Twitter's web.
function changetimezone(time_value, tz){
if(!tz){
tz = 0;
}
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var t = parseInt(Date.parse(time_value))/1000;
return t + tz * 60;
}
So simply parse changetimezone with created_at and your relative timezone.
e.g. changetimezone(tweets[num].created_at,12);
+1200hrs is New Zealand's timezone.
As for what twitter returns, it's actually not US time. It's GMT+0 (London time). So you can safely put 12hrs instead of 20.

Categories

Resources