Re:FullCalendar(由Adam Shaw提供)iPhone设备上的移动版bug

时间:2017-06-08 18:47:59

标签: javascript android iphone facebook fullcalendar

我正在使用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;
&#13;
&#13;

0 个答案:

没有答案