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.
Related
I seem to have a little trouble getting a value to be returned from a dropdown lookup field. I've got the following code that gets me the values from the list I'm doing the lookup upon:
var siteUrl = _spPageContextInfo.webServerRelativeUrl;
function getDropdownValues(tempNumTitle) {
var clientContext = new SP.ClientContext(siteUrl);
var tempDropdownValueList = clientContext.get_web().get_lists().getByTitle('Temps');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View>' +
'<RowLimit>' +
'100' +
'</RowLimit>' +
'</View>');
this.tempQuery = tempDropdownValueList.getItems(camlQuery);
clientContext.load(tempQuery);
clientContext.executeQueryAsync(
// on success of getting Temp Values from dropdown
// match it with the tempNum entry
function (sender, args) {
var tempDropDownValues = {};
var tempEnumerator = tempQuery.getEnumerator();
while(tempEnumerator.moveNext()) {
var tempItem = tempEnumerator.get_current();
var tempTitle = tempItem.get_item('Title');
var tempId = tempItem.get_item('ID');
tempDropDownValues[tempTitle] = tempId;
}
selectTemp(tempNumTitle, tempDropdownValues)
},
// on failure
function (sender, args) {
console.info('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
It performs this fine, giving me the dropdown values. It then calls the function selectTemp with the parameters of the tempNumTitle we are looking for, and the list of dropdown values retrieved. Here is the next function:
function selectTemp(tempNumTitle, tempValues) {
var clientContext = new SP.ClientContext(siteUrl);
var tempMatchValueList = clientContext.get_web().get_lists().getByTitle('Numbers-Temp');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View>' +
'<Query>' +
'<Where>' +
'<Eq>' +
'<FieldRef Name="Title" />' +
'<Value Type="Text">' + tempNumTitle + '</Value>' +
'</Eq>' +
'</Where>' +
'</Query>' +
'</View>');
this.tempMatchValueQuery = tempMatchValueList.getItems(camlQuery);
clientContext.load(tempMatchValueQuery);
clientContext.executeQueryAsync(
// on success
function (sender, args) {
var temp = '';
tempEnumerator = tempMatchValueQuery.getEnumerator();
while(tempEnumerator.moveNext()) {
var tempItem = tempEnumerator.get_current();
temp = tempItem.get_item('Temp0');
}
},
// on failure
function (sender, args) {
console.info('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
It almost gets me what I'm looking for, but I get something like this:
temp: {$1E_1: 3, $2e_1: "Temp 3"}
Where I want the value of the $2e_1, or "Temp 3". How can I get that value, without just going temp["$2e_1"]?
When accessing a lookup column or a people picker column, the column value is a complex type rather than a simple string.
You can invoke .get_lookupValue() on the returned object to get a text representation of the lookup column's value, or .get_lookupId() to get the ID number of the corresponding item in the lookup list (or in the site collection's user information list in the case of a people picker column).
So in your case, assuming "Temp0" is the internal name of a lookup column, you should be able to do this:
temp = tempItem.get_item('Temp0').get_lookupValue();
Hello i try to query the tasks from sharepoint 2013 with javascript.
This is what i got so far:
var context = new SP.ClientContext.get_current();
var userSessionManager = new SP.WorkManagement.OM.UserOrderedSessionManager(context);
var userSession = userSessionManager.createSession();
var userSettingsManager = new SP.WorkManagement.OM.UserSettingsManager(context);
var locations = userSettingsManager.getAllLocations();
var locationFilter = userSettingsManager.locationFilter
var query = new SP.WorkManagement.OM.TaskQuery(context);
var myTasks = userSession.readTasks(query);
var task;
var tasks = [];
var overDue = [];
var dueSoon = [];
var anTimeDue = [];
var dateForEvaluation = new Date();
getMyTasks();
function getMyTasks() {
context.load(locations);
context.load(myTasks);
context.executeQueryAsync(onGetMyTasksSuccess, onGetMyTasksFail);
}
function onGetMyTasksSuccess() {
console.log("Successfully retrieved tasks...");
var taskEnumerator = myTasks.getEnumerator();
while (taskEnumerator.moveNext()) {
task = taskEnumerator.current;
//console.log("Task: " + task.get_id() + " - Taskname: " + task.get_name() + " - Beschreibung: " + task.get_description() + " - dueDatum: " + task.get_dueDate() + " - Startdatum: " + task.get_startDate() + " - Persönlich: " + task.get_isPersonal() + " - Fertiggestellt: " + task.get_isCompleted());
tasks.push({
taskName: task.get_name(),
description: task.get_description(),
dueDate: task.get_dueDate(),
startDate: task.get_startDate(),
personally: task.get_isPersonal(),
complete: task.get_isCompleted(),
location: task.get_locationId()
});
}
console.log(tasks);
console.log(locations)
}
// This function is executed if the above call fails
function onGetMyTasksFail(sender, args) {
console.log('Failed to get tasks. Error:' + args.get_message());
}
This code works but gives me always all Tasks back. I only need the not completed Tasks. Well i tried too look a the referenc pages but there are no code examples or anything.
So my question is how to filte the tasks to get only the not completed Tasks?
Any Advise or held would be great and thanks for your time.
As i discoverd the only working option for me is to us an if Statement where i query the is_completet method result.
Here is the now Working Code:
function onGetMyTasksSuccess() {
console.log("Successfully retrieved tasks...");
var taskEnumerator = myTasks.getEnumerator();
while (taskEnumerator.moveNext()) {
task = taskEnumerator.current;
if (task.get_isCompleted() === false) {
tasks.push({
taskName: task.get_name(),
description: task.get_description(),
dueDate: task.get_dueDate(),
startDate: task.get_startDate(),
personally: task.get_isPersonal(),
complete: task.get_isCompleted(),
location: task.get_locationId()
});
}
}
console.log(tasks);
countForForm(tasks);
}
The importend thing here is if (task.get_isCompleted() === false) its by no means perfect but i works good enough. Sadly the JavaScript API is not good documented for sharepoint sp.workmanagment.js.
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 :-)
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.
Let's say I have:
var directions = [ "name", "start_address", "end_address", "order_date" ];
I'm trying to find a slick, fast way to turn that array into this:
data: {
"directions[name]" : directions_name.val(),
"directions[start_address]" : directions_start_address.val(),
"directions[end_address]" : directions_end_address.val(),
"directions[order_date]" : directions_order_date.val()
}
Notice the pattern. The name of the array "directions" is the prefix to the values.
I'm interested how people can either do this or at least suggest a way for me to try.
Any tips would be appreciated.
Thanks!
EDIT **
Thanks for the suggestions so far. However, I forgot to mention that the array "directions" needs to be dynamic.
For example, I could use:
places = ["name", "location"]
should return
data: {
"places[name]" : places_name.val(),
"places[location]" : places_location.val()
}
alpha = ["blue", "orange"]
should return
data: {
"alpha[blue]" : alpha_blue.val(),
"alpha[orange]" : alpha_orange.val()
}
So basically I could just pass an array into a function and it return that data object.
var directions = ["name", "start_address", .... ];
var data = someCoolFunction( directions );
Hope that makes sense.
** EDIT **************
I want to thank everyone for their help. I ended up going a different route. After thinking about it, I decided to put some meta information in the HTML form itself. And, I stick to a naming convention. So that an HTML form has the information it needs (WITHOUT being bloated) to tell jQuery where to POST the information. This is what I ended up doing (for those interested):
// addBox
// generic new object box.
function addBox(name, options) {
var self = this;
var title = "Add " + name.charAt(0).toUpperCase() + name.slice(1);
var url = name.match(/s$/) ? name.toLowerCase() : name.toLowerCase() + "s";
allFields.val(""); tips.text("");
$("#dialog-form-" + name).dialog( $.extend(default_dialog_options, {
title: title,
buttons: [
{ // Add Button
text: title,
click: function(){
var bValid = true;
allFields.removeClass( "ui-state-error" );
var data = {};
$("#dialog-form-" + name + " input[type=text]").each(function() { // each is fine for small loops :-)
var stripped_name = this["name"].replace(name + "_", "");
data[name + "[" + stripped_name + "]"] = $("#dialog-form-" + name + " #" + name + "_" + stripped_name).val();
});
// verify required fields are set
$("#dialog-form-" + name + " input[type=text].required").each(function() {
bValid = bValid && checkLength( $(this), $(this).attr("name").replace("_", " "), 3, 64 );
});
// find sliders
$("#dialog-form-" + name + " .slider").each( function() {
data[name + "[" + $(this).attr("data-name") + "]"] = $(this).slider( "option", "value" );
});
data["trip_id"] = trip_id;
if(options != null) { $.extend(data, options); } // add optional key/values
if(bValid) {
$(".ui-button").attr("disabled", true);
$.ajax( { url : "/" + url, type : "POST", data : data } );
}
}
},
{ text: "Cancel", click: function(){$( this ).dialog( "close" );} }
]
}));
}
It's really unclear what you want here. Perhaps you should give the interface to the function you want, and an example of some code which sets up some sample variables and calls the function.
What you seem to be asking for is to dynamically find variables which you have already declared in the environment, such as directions_name and directions_start_address, and call the val() method on each of them, then construct a dictionary mapping strings to those results. But the keys of the dictionary contain JavaScript syntax. Are you sure that's what you want?
function transform(name)
{
var data = {};
var names = window[name];
for (var i=0; i<names.length; i++)
{
data[name + "[" + names[i] + "]"] = window[name + "_" + names[i]].val();
}
return data;
}
Edit: To use JQuery to look up objects by ID instead of the above approach (which looks up global variables by name):
function transform(name)
{
var data = {};
var names = $("#" + name);
for (var i=0; i<names.length; i++)
{
data[name + "[" + names[i] + "]"] = $("#" + name + "_" + names[i]).val();
}
return data;
}
This will look up the name in the global space of the window (which will work in a browser anyway). You call that function with "directions" as the argument. For example:
var directions = [ "name", "start_address", "end_address", "order_date" ];
var directions_name = {"val": function() {return "Joe";}};
var directions_start_address = {"val": function() {return "14 X Street";}};
var directions_end_address = {"val": function() {return "12 Y Street";}};
var directions_order_date = {"val": function() {return "1/2/3";}};
data = transform("directions");
Is that what you want?
(Note: I see someone else posted a solution using $ and "#" ... I think that's JQuery syntax, right? This works without JQuery.)
Edit: Note that this lets you use a dynamic value for "directions". But I'm still not sure why you want those keys to be "directions[name]", "directions[start_address]", instead of "name", "start_address", etc. Much easier to look up.
Edit: I fixed my sample code to use functions in the values. Is this really what you want? It would be easier if you weren't calling val() with parens.
Like this:
var data = { };
for(var i = 0; i < directions.length; i++) {
var name = directions[i];
data["directions[" + name + "]"] = $('#directions_' + name).val();
}
Or,
data["directions[" + name + "]"] = directionsElements[name].val();
EDIT: You can pass an array and a prefix.