我正在使用Adam Shaw开发一个基于FullCalendar的Web应用程序,但我实际上使用的是支持移动版本的旧版本(link),我实际上已经完成了开发Web应用程序并在android上测试它尽管iPhone设备无法解析特定的日历事件,但机器和PC的工作非常完美
网络应用程序有一个引擎,可以从Facebook和Google日历和Firebase服务器获取事件数据,我可以从所有三个提供商处获取事件,并在iPhone上的FullCalendar手机上显示后两者(Google Calendar和Firebase服务器) ),虽然在Facebook事件数据上,它只是不会在FullCalendar上显示事件。
我设法打印事件,在警报上显示它们(显示不会显示的事件),所以我确定Facebook Graph API不是问题(这是我所希望的),似乎问题在于FullCalendar本身,但是我找不到FullCalenar API以不同方式处理相同事件数据的原因,如果解析问题,事件将不会在Android和PC机器上显示,所以我很确定代码本身没有问题,但只有iPhone机器才需要更多的一些要求
帮助太多了
var page_module = (function ()
{
let facebook_app_id = "1888264188125920";
let pw = "Mgo6B97nHZKdwXMiGw5P";
let events = []; // where ALL the events will be
let users = []; // where all the users info will be
let google = [];
let fb = 0; //
let uneffective_load = 0;
const initModule = function()
{
get_users_db();
//// Calendar initation virtual space ////
let elemDiv = document.createElement('div'); // limits the calendar UI into a div named calendar1
elemDiv.id = "calendar1"
elemDiv.className = "calendar1";
const speculated_height = window.innerHeight * 0.70; // 70% height
document.body.appendChild(elemDiv);
$('#calendar1').fullCalendar(
{
height: speculated_height,
header: { // defines the header of the calendar (buttons)
left: 'prev,next,today',
center: 'title', // which month/year we are in
right: 'month,agendaWeek,agendaDay'
},
theme: true,
eventRender: function(event, element) // generates pop up info about the event
{
element.attr('title', event.tooltip);
},
isRTL: false, // Right to left, hebrew mode
monthNames: ["ינואר", "פבואר", "מרץ" , "אפריל", "מאי", "יוני" , "יולי" , "אוגוסט", "ספטמבר" , "אוקטובר", "נובמבר", "דצמבר"], // hebrew language use (month names)
monthNamesShort: ["ינואר", "פבואר", "מרץ" , "אפריל", "מאי", "יוני" , "יולי" , "אוגוסט", "ספטמבר" , "אוקטובר", "נובמבר", "דצמבר"], // fullcalendar api for short month names, in hebrew it's short anyways
dayNames: ["ראשון", "שני", "שלישי" , "רביעי" , "חמישי", "שישי", "שבת"], // hebrew day names
dayNamesShort: ["ראשון", "שני", "שלישי" , "רביעי" , "חמישי", "שישי", "שבת"], // ...
buttonText: // buttons in hebrew
{
prev: 'הקודם', // <
next: 'הבא;', // >
prevYear: 'שנה קודמת', // <<
nextYear: 'שנה הבאה', // >>
today: 'היום',
month: 'חודשי',
week: 'שבועי',
day: 'יומי'
},
columnFormat:
{
month: 'ddd', // Mon
week: 'ddd d/M', // Mon 7/9
day: 'dddd d/M' // Monday 7/9
},
timeFormat:
{
agenda: 'h:mm{ - h:mm}', // 5:00 - 6:30
// our case
'': 'h:mm{ - h:mm}' // 5:00 - 6:30
},
eventClick: function(event) // on click event handler, uses event object
{
if (event.url)
{
window.open(event.url);
return false;
}
},
});
//// END OF Calendar initation virtual space ////
/// Facebook API initation virtual space ///
// depends on IP being either localhost or specific firebase-project approved by author
FB.init(
{
appId : ''+facebook_app_id,
xfbml : true,
version : 'v2.8'
}); // API call function to "throw" API ID and be approved upon IP filtering of Facebook management
/// END of Facebook API initation virtual space ///
//Table build metafunction
build_filter_table();
};
const gather_all_events_from_all_facebook_pages = function()
{
// subdibision into local function!
const add_event_to_calendar = function(id, name, date, email, enddate,location, source,url) // subfunction responisble for adding event to fullcalendar API event and render that
{
let color = "#";
users.forEach(function(val)
{
if(val.id == email)
color+=val.color;
return;
});
let event;
if(source == "Facebook")
event = {id: email , title: name , start: date, end:enddate , url: 'https://www.facebook.com/events/'+id , backgroundColor: color, event_source: email, tooltip: name, location,allDay:false,};
else if(source == "Manual")
event = {id: email , title: name , start: date, end:enddate , url: url , backgroundColor: color, event_source: email, tooltip: name, location, allDay:false,};
else if(source == "Google")
event = {id: email , title: name , start: date, end:enddate , backgroundColor: color, event_source: email, tooltip: name, location,allDay:false,};
events.push(event);
};
const withdraw_events_from_facebook_page = function(data, email) // subfunction responsible for scanning entire event database file from facebook page
{
// subfunction to print results into Fullcalendar API
let i;
for(i=0; i<data.length; i++)
{
let event_date = new Date(data[i].start_time); // sets a new Date for event date formating to be dynamic
//event_date.setISO8601(data[i].start_time); // converts time from Facebook API date format to Javascript Date format
let end_date;
if(data[i].end_time)
end_date= new Date(data[i].end_time);
let place_name;
if(data[i].place)
place_name = data[i].place.name;
else
place_name = null;
add_event_to_calendar(data[i].id, data[i].name, event_date, email, end_date, place_name ,"Facebook");
}
};
const page_through_all_events_from_response = function(response,email)
{
withdraw_events_from_facebook_page(response.data,email); // adds all the event from THIS page to the event array
if(response.paging.next) // if there's a next page
{
$.getJSON(response.paging.next, function(next_data) // recursive call to gather the events from the next page (until done)
{
page_through_all_events_from_response(next_data,email);
});
}
};
const add_events_from_page = function(str, email) // subfunction responsible for doing the API request for the event database
{
//+"&since="
let month_ago = parseInt(new Date(moment().subtract(2, 'months')).valueOf()/1000);
let month_ahead = parseInt(new Date(moment().add(2, 'months')).valueOf()/1000);
FB.api
(
"/"+ str+"/events?access_token="+config_module.getaccessToken(pw)+"&since="+month_ago+"&until="+month_ahead, // the HTTP request defined in FB API
function (response)
{
if (response && !response.error) // if request was approved by server
{
page_through_all_events_from_response(response, email);
}
else
{
console.log(response.error);
}
}
);
};
const scan_for_direct_events = function() // manual event entry - database scanner
{
let database = firebase.database();
let leadsRef = database.ref('Events'); // gets to database /Events folder
leadsRef.once('value',function(snapshot)
{
snapshot.forEach(function(childSnapshot)
{
if(childSnapshot.val().approve == 1) // add each child that is "approved" by admin to the event database
{
add_event_to_calendar(childSnapshot.val().id, childSnapshot.val().name, new Date(childSnapshot.val().start_time),
childSnapshot.val().id, new Date(childSnapshot.val().end_time),childSnapshot.val().location, "Manual",childSnapshot.val().url);
}
});
});
};
const scan_all_db_for_pages = function() // subfunction responsible for facebook DB load via Firebase API call
{
let database = firebase.database();
let leadsRef = database.ref('Facebook'); // go to /Facebook folder on database
leadsRef.once('value',function(snapshot)
{
snapshot.forEach(function(childSnapshot)
{
if(childSnapshot.val().charAt(0) == '1') // adds each child that is approved by admin (child being a facebook page)
add_events_from_page(childSnapshot.key,childSnapshot.val().substring(1, childSnapshot.val().length));
});
}).then(scan_google_calenders);
};
scan_for_direct_events(); // add manual events
scan_all_db_for_pages(); // adds all events from facebook database
$(document).ajaxStop(function ()
{
local_storage_func(); // "filters" the rendering of the events on the page from the last picked configuration
// 0 === $.active
});
};
const create_buttons = function() // creates the navigation buttons
{
let div = document.createElement("div"); // div for navigation buttons
div.id = "top_buttons_div";
div.className = "top_buttons_div";
const back_button_build = function()
{
let link = document.createElement("a");
let pic = document.createElement("IMG");
pic.src = "buttons/admin.png";
pic.height = 45;
pic.width = 75;
link.appendChild(pic);
link.href = "login_page/login.html";
div.appendChild(link);
};
document.body.appendChild(div);
back_button_build(); // defined it into functions for future possibility for modularity
};
const get_users_db = function() // scans the entire user database to create users array
{
let database = firebase.database();
let leadsRef = database.ref('Users'); // get to Users folder on firebase db
leadsRef.once('value',function(snapshot)
{
snapshot.forEach(function(childSnapshot) // build user array while each user object consists of user id and user color
{
let email = childSnapshot.key;
let obj = childSnapshot.val();
let user_obj = new Object(); // create the user "object"
user_obj.id = email;
user_obj.key = childSnapshot.key;
user_obj.color = obj.color;
user_obj.url = obj.url;
users.push(user_obj); // adds to array
});
}).then(function()
{
database.ref("Names").once('value',function(snapshot2) // appends user nickname to user id at users array
{
snapshot2.forEach(function(childSnapshot)
{
users.forEach(function(val,index,arr)
{
if(val.id == childSnapshot.key)
val.name = childSnapshot.val(); // actual appending call
});
});
}).then(render_table_content) // appends user data to GUI table
}) // scan_google_calenders
};
const scan_google_calenders = function()
{
const add_event_to_calendar = function(id, name, date, email, enddate, source,url) // subfunction responisble for adding event to fullcalendar API event and render that
{
let color = "#";
users.forEach(function(val)
{
if(val.id == email)
color+=val.color;
return;
});
let event;
if(enddate == "Full day")
{
event = {id: email , title: name , start: date , backgroundColor: color, event_source: email, tooltip: name,url: url, allDay:true};
}
else
{
event = {id: email , title: name , start: date, end:enddate , backgroundColor: color, event_source: email, tooltip: name,url: url};
}
events.push(event);
};
let database = firebase.database();
let leadsRef = database.ref('Google'); // go to /Facebook folder on database
leadsRef.once('value',function(snapshot)
{
snapshot.forEach(function(childSnapshot)
{
let obj = childSnapshot.val();
users.forEach(function(val)
{
if(obj.id == val.id)
{
obj.color = val.color;
obj.name = val.name;
google.push(obj);
}
});
});
}).then(function()
{
google.forEach(function(val)
{
var calendarid = val.val; // will look somewhat like 3ruy234vodf6hf4sdf5sd84f@group.calendar.google.com
$.ajax({
type: 'GET',
url: 'https://www.googleapis.com/calendar/v3/calendars/' + calendarid+ '/events?key=' + config_module.google_key,
dataType: 'json',
success: function (response)
{
response.items.forEach(function(event)
{
let s = new Date(event.start.dateTime);
if(s.toString() == 'Invalid Date' && event.summary)
{
add_event_to_calendar(val.id, event.summary, new Date(event.start.date), val.id, "Full day" ,null, event.htmlLink);
}
else
{
let e = new Date(event.end.dateTime);
if(event.summary)
add_event_to_calendar(val.id, event.summary, s, val.id, e ,null, event.htmlLink);
}
});
//do whatever you want with each
},
error: function (response)
{
//console.log(response);
//tell that an error has occurred
}
});
});
});
};
const build_filter_table = function()
{
let table = document.createElement("table"); // builds a new table
table.id = "table";
let main_row = table.insertRow(0); // creates the first line which on each cell we define the cell's content on different lines
let main_cell1 = main_row.insertCell(0);
let pic1 = document.createElement("IMG");
pic1.src = "icons/Organization.png";
main_cell1.append(pic1);
let main_cell2 = main_row.insertCell(1);
let you_get_nothing_good_day_sir = document.createElement("IMG");
you_get_nothing_good_day_sir.src = "icons/Color.png";
main_cell2.append(you_get_nothing_good_day_sir);
let div = document.createElement("div");
div.id = "div_table";
div.className = "div_table";
div.appendChild(table);
document.body.appendChild(div);
};
const render_table_content = function()
{
const checkbox_handler = function(e) // function is responisble for alerting between "filter" and "unfilter" state according to checkbox value
{
let status = "";
let element = e.srcElement || e.target;
if(uneffective_load == 0)
{
element.checked = false;
alert("Page is not ready yet");
}
if(element.checked == true)
{
status="addEventSource"; // "command" to do
localStorage.setItem(element.id,"1");
}
else
{
status = "removeEvents"; // "command" to do
localStorage.setItem(element.id,"0");
}
add_remove_by_id(element.id,status);
};
let i=1;
let table = document.getElementById("table"); // adds data to table
users.forEach(function(val,index,arr)
{
let row = table.insertRow(i);
let cell1 = row.insertCell(0);
let user_nick = "";
if(val.name == null) // will be either username or nickname (if exists), nickname having the apperhand
user_nick+= val.id;
else
user_nick+= val.name;
if(val.url && val.url.length > 0)
cell1.innerHTML = "<a href='" +val.url+ "'>" + user_nick + "</a>";
else
cell1.innerHTML = user_nick;
let cell2 = row.insertCell(1); // "color" sample cell
cell2.style.backgroundColor = "#" + val.color; // color defination
let cell3 = row.insertCell(2);
let checkbox = document.createElement("INPUT"); // dummy function box with the aforementioned event handler to switch between states
checkbox.setAttribute("type", "checkbox");
checkbox.checked=false;
checkbox.id = val.id;
checkbox.addEventListener('click', checkbox_handler);
cell3.appendChild(checkbox);
i++;
if(index+1 == arr.length) // will actually render the events (not just from facebook pages, but from everything) after completing the table with all the data
{
gather_all_events_from_all_facebook_pages();
}
});
};
const add_remove_by_id = function(email,status) // status being the command to do, email is the id
{
let temp_arr = new Array();
let month_ago = new Date(moment().subtract(2, 'months'));
let month_ahead = new Date(moment().add(2, 'months'));
events.forEach(function(val,index,arr) // creates a temproary array that holds all the events that are linked to the user with id==email
{
if(val.id == email && val.start.valueOf() > month_ago.valueOf() && val.start.valueOf() < month_ahead.valueOf() )
{
temp_arr.push(val);
}
});
if(status == "addEventSource") // if the command was to add those events
{
$('#calendar1').fullCalendar(status,temp_arr); // we add those events from the array
}
else
{
$('#calendar1').fullCalendar(status,email); // full calendar API special function that handles "remove event" rendering
//$('#calendar1').fullCalendar('removeEvents',id);
}
};
const local_storage_func = function() // reads the local storage for previous table filtering "configuration" to apply them
{
uneffective_load = 1;
$.each(localStorage, function(i) // reads ALL the local storage values
{
if(document.getElementById(localStorage.key(i)) != null && localStorage.getItem(localStorage.key(i)) == 1) // if value is 1, we grab the key as source id
{
document.getElementById(localStorage.key(i)).click(); // and applies "click" emulation
}
})
$('#calendar1').fullCalendar("rerenderEvents");
};
return { initModule, gather_all_events_from_all_facebook_pages, create_buttons, events,users,build_filter_table,local_storage_func,google};
}());
$( document ).ready(function()
{
let logo = document.createElement("IMG");
logo.src = "icons/lit1.jpg";
logo.id = "logo";
logo.style.width = "100%";
document.body.append(logo);
//document.header.append(h);
page_module.initModule(); // second move, make EVERYTHING, snowball function
page_module.create_buttons(); // first move -> creates the navigation buttons
document.getElementsByClassName("fc-border-separate")[0].tBodies[0].style.opacity = "0.5";
//document.getElementsByClassName("fc-view fc-month-view fc-basic-view")[0].firstChild.tBodies[0].style.opacity = 0.5
});
&#13;
div.top_buttons_div
{
width: 100%;
}
div.calendar1
{
width:100%;
}
div.div_table
{
width: 100%;
}
body
{
background-image: url('icons/background.jpg');
background-size: 100% 100%;
background-repeat: no-repeat;
}
&#13;
<!DOCTYPE html5>
<html>
<head>
<meta charset="UTF-8">
<!--Full Calendar API and jquery API loading files-->
<link rel='stylesheet' href='libs/fullcalendar-1.5.2/fullcalendar/fullcalendar.css' />
<script src='libs/fullcalendar-1.5.2/jquery/jquery-1.7.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js'></script>
<script src='libs/fullcalendar-1.5.2/fullcalendar/fullcalendar.js'></script>
<!--END of Full Calendar API and jquery API loading files-->
<!--Facebook API script files-->
<script src="https://connect.facebook.net/es_LA/sdk.js"></script>
<!--END of Facebook API script files-->
<!--Google Firebase API loading files-->
<script src="https://www.gstatic.com/firebasejs/3.7.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.7.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.7.1/firebase-database.js"></script>
<!-- <script src="https://apis.google.com/js/api.js"></script> -->
<!--END of Google Firebase API loading files-->
<!--Loaded a personal script to combine API's as well as page design and logic initate-->
<script src="config.js"></script> <!--Required in order to access Firebase & Facebook databases while identifying ourselves-->
<link rel='stylesheet' href='style.css' />
<script src="script.js"></script>
<!--END of Loaded a personal script to combine API's as well as page design and logic initate-->
<!--Loaded theme script files and css files-->
<link rel='stylesheet' href='libs/jquery-ui-1.12.1.custom/jquery-ui.css' />
<script src='libs/jquery-ui-1.12.1.custom/jquery-ui.js' />
<!--END of Loaded theme script files and css files-->
<script src='libs/polyfill/modernizr-custom.js'></script>
<script src='libs/polyfill/js-webshim/minified/polyfiller.js'></script>
<script>
$.webshims.polyfill();
</script>
</head>
<body>
</body>
</html>
&#13;