FBJS/Examples/Ajax

From Facebook Developers Wiki

Jump to: navigation, search

Contents

[edit] Ajax Examples

Ajax examples are below even though I think this page was meant for one example and people added in more. If you haven't implemented Ajax on the Facebook Platform then you probably want to start from the FBJS page.

[edit] Example of Ajax Object in Action

  • Solid example of how to make an onclick call. One you should note that there is no "setInnerHtml" call in FBJS for security reasons. If you want to add dynamic HTML you must add it on the server side and pass it using the setInnerFBML call. (Beta. You can now use setInnerXHTML to pass HTML back from Ajax calls. You can also use FBJS_LocalProxy to bypass the Facebook server hop.)
  • Don't pass HTML with setTextValue because it won't work.
  • Ajax has an apparent short ~10 second max timeout!
  • Ajax calls must be made over the default HTTP port: 80
  • Be aware of silent 5000 byte size limit to JSON replies if JSON is not perfect (use json_encode to avoid this bug) http://bugs.developers.facebook.com/show_bug.cgi?id=363
  • Note that url must be full, absolute path to file on Your server
  • Ideally the url will point to a non-static location that has content sent through some form of CGI. In formal language, the url must respond to a request for application/x-www-form-urlencoded content.
  • When using JSON and setInnerFBML, the prefix of the FBML parameter has to be 'fbml_'. The parameter will then be sanitised, and passed on to setInnerFBML.
These links demonstrate the Ajax object:<br /> <a href="#" onclick="do_ajax(Ajax.JSON); return false;">JSON</a><br /> <a href="#" onclick="do_ajax(Ajax.RAW); return false;">RAW</a><br /> <a href="#" onclick="do_ajax(Ajax.FBML); return false;">FBML</a><br /> <label><input type="checkbox" id="requirelogin" checked="checked" /><span>Require Login?</span></label><br /> <div><span id="ajax1"></span><span id="ajax2"></span></div> <script><!-- function do_ajax(type) { var ajax = new Ajax(); ajax.responseType = type; switch (type) { case Ajax.JSON: ajax.ondone = function(data) { document.getElementById('ajax1').setTextValue(data.message + ' The current time is: ' + data.time + '. '); document.getElementById('ajax2').setInnerFBML(data.fbml_test); } break; case Ajax.FBML: ajax.ondone = function(data) { document.getElementById('ajax1').setInnerFBML(data); document.getElementById('ajax2').setTextValue(''); } break; case Ajax.RAW: ajax.ondone = function(data) { document.getElementById('ajax1').setTextValue(data); document.getElementById('ajax2').setTextValue(''); } break; } ajax.requireLogin = document.getElementById('requirelogin').getChecked(); ajax.post('http://example.com/testajax.php?t='+type); } //--></script>


[edit] PHP Source Code

Source code of http://example.com/testajax.php:

<?php $user = isset($_POST['fb_sig_user']) ? $_POST['fb_sig_user'] : null; if ($_GET['t'] == 0) { // Ajax.RAW echo 'This is a raw string. The current time is: '.date('r').', and you are '.($user ? 'uid: #'.$user : 'anonymous').'.'; } else if ($_GET['t'] == 1) { // Ajax.JSON echo '{"message": "This is a JSON object.", "time": "'.date('r').'", "fbml_test": "Hello, '.($user ? '<fb:name uid='.$user.' useyou=false />' : 'anonymous').'."}'; } else if ($_GET['t'] == 2) { // Ajax.FBML echo 'This is an FBML string. The current time is: '.date('r').', and you are '.($user ? '<fb:name uid='.$user.' useyou=false />' : 'anonymous').'.'; } ?>


Note: For brevity's sake we are trusting $_POST['fb_sig_user'] without checking the full signature. This is unsafe as anyone could easily forge a user's action. Always be sure to either use the Facebook object which is supplied with the client libraries, or check the sig values per Platform spec.

[edit] Query Parameters

You can also specify query parameters as the query argument in ajax.post, as such:

var queryParams = { "param1" : value1, "param2" : value2 }; ajax.post("http://example.com/testajax.php", queryParams);

This has the added benefit all the parameter values are automatically made URL-safe (via JavaScript escape function) before constructing the final URL.

Shouldn't encodeURIComponent be used to make a string URL-safe?

[edit] Working Example

Here is a working example with parameters. It also contains a setTimout counter that some have been struggling with. You can copy and paste it and work from there. Hope it helps! --512493462 06:10, 24 October 2007 (PDT)

<!-- Sample code written by Matt Burke, free as in 'free beer' --> <!-- You will need to change '$callbackurl' and possibly the 'require_once' line --> <?php //For AJAX, replace with your full callback url (not canvas/app page): $callbackurl='http://[PLACE_YOUR_CALLBACK_URL_HERE]/example.php'; //AJAX Response (should be first php): if (isset($_REQUEST['action'])) { echo "[[You selected: ".$_REQUEST['option'].".]]"; exit; //Important! Stops remaining php after AJAX request is processed } require_once('appinclude.php'); //follow example to require login //can have normal php code here ?> <div style='margin:15px;'> <center> <h1>Application Title</h1> <h3>You are:</h3> <fb:profile-pic uid="<?=$user?>" size='square' linked="true" /><br/> <fb:name uid="<?=$user?>" useyou="false"/><br/> <?php $initcounter=0; //perhaps retrieve value from database echo "<h3>A FBJS counter, using setTimeout: <span id='counterSpan'>".$initcounter."s</span></h3><br/>"; ?> <h2>A div:</h2> <div id="actionDiv">[[Nothing happening in this div yet.]]</div><br/> <h3>Select <a href="#" onclick="do_ajax('actionDiv','The First');return false;">Option 1 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv','Number Two');return false;">Option 2 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv','Option 3');return false;">Option 3 (AJAX)</a></h3> </div> <script type="text/javascript"><!-- //FBJS AJAX, using FBML (modified from example on wiki): function do_ajax(div,val) { var ajax = new Ajax(); ajax.responseType = Ajax.FBML; ajax.ondone = function(data) { document.getElementById(div).setInnerFBML(data); } ajax.requireLogin = 1; var params={"action":'select',"option":val}; //add parameters as comma separated "param":value ajax.post('<?=$callbackurl?>',params); } //setTimeout counter: var counterValue=<?=$initcounter?>; function incCounter(units) { counterValue++; document.getElementById('counterSpan').setTextValue(counterValue+units); setTimeout(function() {incCounter("s")},1000); } setTimeout(function() {incCounter("s")},1000); //1000 = 1 sec //it is possible to simply call incCounter, //but that would increment the counter immediately upon page load //--> </script>


<h1>Application Title</h1> <h3>You are:</h3> <fb:profile-pic uid="<?=$user?>" size='square' linked="true" /><br/> <fb:name uid="<?=$user?>" useyou="false"/><br/> <?php $initcounter=0; //perhaps retrieve value from database echo "<h3>A FBJS counter, using setTimeout: <span id='counterSpan'>".$initcounter."s</span></h3><br/>"; ?> <h2>A div:</h2> <div id="actionDiv">[[Nothing happening in this div yet.]]</div><br/> <h3>Select <a href="#" onclick="do_ajax('actionDiv','The First');return false;">Option 1 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv','Number Two');return false;">Option 2 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv','Option 3');return false;">Option 3 (AJAX)</a></h3> </div> <script type="text/javascript"><!-- //FBJS AJAX, using FBML (modified from example on wiki): function do_ajax(div,val) { var ajax = new Ajax(); ajax.responseType = Ajax.FBML; ajax.ondone = function(data) { document.getElementById(div).setInnerFBML(data); } ajax.requireLogin = 1; var params={"action":'select',"option":val}; //add parameters as comma separated "param":value ajax.post('<?=$callbackurl?>',params); } //setTimeout counter: var counterValue=<?=$initcounter?>; function incCounter(units) { counterValue++; document.getElementById('counterSpan').setTextValue(counterValue+units); setTimeout(function() {incCounter("s")},1000); } setTimeout(function() {incCounter("s")},1000); //1000 = 1 sec //it is possible to simply call incCounter, //but that would increment the counter immediately upon page load //--> </script>

[edit] Server Error Handling

You can also add some nice error handling to your calls and display a message using FBJS Dialog element.

function ajax_action(e) { el = document.getElementById(e); if(!el.hasClassName('loading')) { el.addClassName('loading'); ajax = new Ajax(); ajax.responseType = Ajax.JSON; ajax.requireLogin = true; ajax.post('http://foo.com/data.json'); ajax.ondone = function(data) { updateSomething(); }; ajax.onerror = function() { show_error_dialog(el); el.removeClassName('loading'); }; } } function show_error_dialog(el) { dialog = new Dialog(Dialog.DIALOG_CONTEXTUAL).setContext(el).showMessage('Oups', 'A communication error occured. Try reloading the page.'); }