Scriptaculous dom:loaded working only "sometimes"? - javascript

So basically, I'm working on a Facebook login flow for my website. It's fairly basic, but giving me some problems. The issue appears that the click observer is only working some of the time. A hard refresh will typically fix the problem. The following is my JS code used to get into it...
function fb_login(login_destination)
{
FB.login(function(response) {
if (response.authResponse) {
var fb_auth_token = response.authResponse.accessToken;
var fb_user_id = response.authResponse.userID;
var url = '/login/ajax/fb_login.php?fb_auth_token=' + fb_auth_token + '&fb_user_id=' + fb_user_id + '&fb_login=' + login_destination;
window.location = url;
}
}, {scope: 'email,user_about_me'});
}
document.observe("dom:loaded", load_fb);
function load_fb()
{
window.fbAsyncInit = function(){
FB.init({
appId : 'ID'
status : true,
cookie : true,
xfbml : true,
oauth : true
});
};
$('fb_connect').observe('click',function(event){
var login_destination = $('fb_connect').getAttribute('dest');
fb_login(login_destination);
});
}
The only symptom appears to be that it simply will not respond to clicks on certain page loads. The ID I'm using is tied directly to the image itself. I'm curious if anyone has ran into this and knows how to fix it. Thanks.

I've run into this before. I ended up using timer to start the initialization script as a backup. The function sets a variable and exits if it has already run. Ugly, but effective.

So, I wound up fixing this. The code effectively got changed to this....
function load_fb()
{
var d = document;
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
Basically I'm just now waiting to bring in the FB JS SDK until after the page load (reference earlier code for this to make sense). It doesn't have anything to do with scriptaculous.

Related

Making Facebook Dialog Feed Box appear in the same window as a modal instead of popup of a page

I would like Facebook Dialog Feed to appear as a modal in the same page. The user is authenticated earlier before this call, using PHP. I tried using the iframe property for display, but it is still appearing as a popup.
The code is below:
window.fbAsyncInit = function () {
FB.init({ appId: '****************', cookie: true, xfbml: true, oauth: true });
if (typeof facebookInit == 'function') {
facebookInit();
}
};
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
function facebookInit() {
FB.ui({
url : 'http://url.com',
method: 'feed',
name: 'Hey',
link: 'http://url.com',
display: 'iframe',
picture: '',
caption: fb_description,
}, function (response) {
if (response && response.post_id) {
window.location = "/hello";
} else {
window.location = "/hello";
}
}
);
}
Is there a reason why this is appearing as a popup and not appearing as a modal?
The only way to show the feed dialog in the same window instead of popup is to use the direct url redirection.
You can use it like this-
function facebookInit() {
var app_id = "{app-id}";
var fb_description = "{description}";
var redirect_uri = "{redirect-url}";
var link = "{link to share}";
var name = "{name}";
var url = "https://www.facebook.com/dialog/feed?"+
"app_id="+app_id+
"&caption="+fb_description+
"&link="+link+
"&name="+name+
"&redirect_uri="+redirect_uri;
location.href = url;
}
Edit:
The documentation says-
If you are using the JavaScript SDK, this will default to a modal iframe type for people logged into your app or async when using within a game on Facebook.com, and a popup window for everyone else
If your app is inside the facebook, then only it will open as a model iframe type, else, a popup or completely on window will be shown.

Facebook API - Detect if session is active OR NOT active

I'm sure I'm simply overlooking something in the Facebook API docs. Basically, after I've loaded the FB Graph, I need to know if the session is active... I cannot simply assume they're logged out and simply re-render if they're logged in once the 'auth.statusChange' event is triggered. I need to know right off the bat.
Below is the code that I've used. Most importantly the FB.getLoginStatus/getAuthResponse/getAccessToken don't work like I'd expect; essentially where it indicates, when invoked, whether they're logged in or out.
(function(d) {
// Create fb-root
var fb_root = document.createElement('div');
fb_root.id = "fb-root";
document.getElementsByTagName('body')[0].appendChild( fb_root );
// Load FB Async
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
// App config-data
var config = {
appId : XXXX,
cookie: true,
status: true,
frictionlessRequests: true
};
window.fbAsyncInit = function() {
// This won't work.
// I can't assume they're logged out and rely on this to tell me they're logged in.
FB.Event.subscribe('auth.statusChange', function(response) {});
// Init
FB.init(config);
// These do not inidicate if the user is logged out :(
FB.getLoginStatus(function(response) { });
FB.getAuthResponse(function(response) { });
FB.getAccessToken(function(response) { });
};
}(document));
Any help is much appreciated. :)
Thanks for the help, but I found the answer on another post: https://stackoverflow.com/a/7765144/560686
Apparently, when you're still in Sandbox mode FB.getLoginStatus() will fire the callback only when they're logged in, but not when they're logged out. To get this to work, I had to Disable the Sandbox mode. :)

FB.Event.subscribe('edge.create', function()) trigger works with Link button but not with Link box

I've created two test pages, one with a Facebook Link button and one with a Link box.
When somebody clicks "Like" I want an image pixel to be fired so we can pick this up from the web server logs.
It works just fine with the Like button but for some reason not with the Like box. Both Like plugins are included as XFBML versions.
The code I am using for both when it comes to triggering the pixel call:
<div id="fb-root"></div>
<script type="text/javascript">
<!--
window.fbAsyncInit = function()
{
FB.init({
appId: '{{appId}}',
status: true,
cookie: true,
xfbml: true
});
FB.Event.subscribe('edge.create', function(){
var tracking_pixel = new Image(1, 1);
tracking_pixel.src = '{{image_pixel_url}}';
});
};
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if(d.getElementById(id))
{
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// -->
</script>
I have also declared:
<html xmlns:fb="http://ogp.me/ns/fb#">
Any suggestions are appreciated!
Thanks in advance.
/Marcus

FB.getLoginStatus Requires Page Refresh before Firing

I have a Facebook Page Tab App that is not loading correctly until after the page is refreshed. I have been trying to solve this problem for over a week, and am reaching my wits end.
Here is the code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https:////connect.facebook.net/en_US/all.js"></script>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '***************', // App ID
channelURL : '//www.********.com/**********/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<script type="text/javascript">
$(document).ready(function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//User Logged In
}
else if (response.status === 'not_authorized') {
//Log User Into App
}
else
{
top.location = "http://www.facebook.com";
}
});
});
</script>
Like I said, if add something like alert("Test") immediately after FB.getLoginStatus(function(response) { it doesn't pop up on the first page load, but does after the page is refreshed.
Can someone please help point me in the right direction?
Thanks,
Fred
First of all you are loading the SDK both Synchronously and Asynchronously. Remove the synchronous line. Then all your FB related lines should be within the window.fbAsyncInit. You can't subscribe to events before the sdk is fully loaded.
You can try it this way if you haven't already
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user, someone you know
} else {
// no user session available, someone you dont know
}
});

Is there a way to detect if the Facebook Javascript SDK loaded successfully?

I use Facebook as the membership system of my website. It uses the code to generate a login control, allowing users to login via their facebook account. It's essentially one click if they're already a member, 2 if they're not (for granting permissions).
I got a problem though... feedback is suggesting the login button isn't always loading correctly. Instead of loading the facebook login control, it simply states (in text) "login via facebook" - which is what the login button would say if the control loaded successfully.
Testing shows that is what happens when the facebook javascript SDK fails to load completely (for whatever reason). I've seen instances where a # in the url prevents the SDK from loading.
To better support this issue, how would I go about detecting if the facebook javascript SDK loaded, and is ready? That way, if it fails, I can leave some sort of note for the user.
Here's how it's currently added to the page:
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '***************',
status: true,
cookie: true,
xfbml: true
});
FB.Event.subscribe('auth.login', function (response) {
window.location.reload();
});
};
(function () {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
</script>
You should load the Javascript Library Asynchronously and put all your FB related functions inside the window.fbAsyncInit method:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
This code loads the SDK asynchronously so it does not block loading
other elements of your page. This is particularly important to ensure
fast page loads for users and SEO robots.
The URLs in the above code are protocol relative. This lets the
browser to load the SDK over the same protocol (HTTP or HTTPS) as the
containing page, which will prevent "Insecure Content" warnings.
The function assigned to window.fbAsyncInit is run as soon as the SDK
is loaded. Any code that you want to run after the SDK is loaded
should be placed within this function and after the call to FB.init.
For example, this is where you would test the logged in status of the
user or subscribe to any Facebook events in which your application is
interested.
A quick example is the following:
<div id="fb-root"></div>
<script>
var isLoaded = false;
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
isLoaded = true;
// Additional initialization code here
};
function checkIfLoaded() {
if(isLoaded) console.log("LOADED!");
else console.log("NOT YET!");
return false;
}
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
Check
(Just clicked the check link a couple of times)
Please note that you can still construct the Login Link server-side and WITHOUT JavaScript. Example using the PHP-SDK:
$loginUrl = $facebook->getLoginUrl();
...
...
<a href="<?php echo $loginUrl; ?>">
<img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif">
</a>
Trigger an event when the SDK is loaded:
window.fbAsyncInit = function() {
FB.init({appId: "#{KeyManager.facebook_app_id}", status: true, cookie: true, xfbml: true});
jQuery('#fb-root').trigger('facebook:init');
};
And listen for the event like this:
$("#fb-root").bind("facebook:init", function() {
..
});
If you are using jQuery (and you have loaded jQuery prior to the FB initialization) you can use a Deferred to run additional initialization.
<script>
window.fbLoaded = $.Deferred();
window.fbAsyncInit = function() {
FB.init({
appId : '----------',
xfbml : true,
status : true,
version : 'v2.7'
});
window.fbLoaded.resolve();
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Then elsewhere (in a JS file) you can do this (in fact the key of this method is you can put this in as many places as you want and they will all get triggered):
window.fbLoaded.done(function () { alert('FB initialized'); });
Note: If the initialization completes BEFORE you add the done event it will fire immediately (that is how Deferreds work). So you can put it wherever you want.
Be sure to test what you want the behavior to be if the API is never initializaed (just comment out the (function(d,s,id)... part
Just look for FB object after loading FB JS SDK sync/async as given:
if (typeof FB !== 'undefined') {
alert("FB JS API is available now");
} else {alert("do something...")}
That's a enough check to call any Facebook JS API related method safely.
Promise-based version, for modern browsers
// Load Facebook JS SDK
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = 'https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.11';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Create a new promise, set to resolve using the global function `fbAsyncInit`,
// which the Facebook JS SDK will call once it's ready.
new Promise((resolve, reject) => {
window.fbAsyncInit = resolve;
}).then(() => {
// ... your code here ...
});
What globals does this JS file introduce?
Let's say it creates a
var FaceBook = function() {//make friends! Or whatever...}
You can test for if (FaceBook) and go from there.
It seems likely that they give you some sort of load event for when their framework is booted up, so to speak.
According to this page http://www.techsirius.com/2014/04/detect-social-SDK-didnt-load.html
$(window).load(function(){
if(typeof window.FB == 'undefined'){
alert('Facebook SDK is unable to load, display some alternative content for visitor');
}
else{
alert('Facebook is working just fine');
}
});
Load the script dynamically (add a script tag from js) and check for error / success events.
var FB;
jQuery.fbInit = function(app_id) {
window.fbAsyncInit = function() {
FB.init({
appId : app_id,
status : true,
channelUrl: '#',
cookie : true,
xfbml : true
});
FB = FB;
getLoginStatus();
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/it_IT/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
$('<div />').attr('id','fb-root').appendTo('body');
};
/**
* https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
*/
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
$('#fb-root').trigger('facebook:init',[response]);
} else if (response.status === 'not_authorized') {
$('#fb-root').trigger('facebook:init',[response]);
} else {
$('#fb-root').trigger('facebook:init',[response]);
}
});
}
If you want check the status from another javascript (with the suggestion of #Leo Romanovsky )
$("#fb-root").on("facebook:init", function(event, response) {
if(response.status === 'connected') {
alert("logged with FB")
}else{
alert("No Logged with FB")
}
});
I use this from few days :
var isLoaded = false;
$(document).on('DOMSubtreeModified', function () {
if ($('#fb-root').length && !isLoaded) {
isLoaded = true;
// ...
}
});
What do you think ?
As stated in other answers; with thanks to #ifaour & #Leo Romanovsky; the best way to detect if the SDK is loaded successully is to trigger an event when the fbAsyncInit is called.
If the event is captured then the SDK is loaded. The code below shows how this could be achieved:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Fire an event when the FB library asynchronously is loaded
$("#fb-root").trigger("facebook:init");
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}
(document, "script", "facebook-jssdk"));
</script>
// Somewhere else in the code
$(document).ready(function () {
$("#fb-root").bind("facebook:init", function () {
console.log("The event is fired FB SDK object is ready to be used.");
});
});
In the event that the event is not fired you could add a timer to check if FB object is 'undefined' and show the appropriate message.
Note 1: Downside there could a slight delay till this event is fired.
Note 2: "feedback is suggesting the login button isn't always loading correctly". I know that FFv49 private browsing blocks the call to fb.

Categories

Resources