FBJS/Examples/Ajax

From Facebook Developer Wiki

Revision as of 23:57, 12 October 2009 by Zalapao Web (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Contents

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.

Note: JSON Parsing Changed

As we announced on the Developer blog and the Developer Forum, we modified our JSON parsing engine. This affects you only if you use FBJSAjax with the JSON responseType, and your application emits JSON which does not conform to the JSON specification but which we currently parse anyway. (Even in this case, it is unlikely you are affected.)

You should avoid building your own JSON, and instead use the PHP function json_encode.

Example of Ajax Object in Action

Solid example of how to make an onclick call.

  • Note that url must be full, absolute path to file on your server -- not a canvas page (apps.facebook...).
  • 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! --Does anyone have an alternative for queries that may take longer for some users?
  • 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
  • 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>


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.

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);

These are sent along in POST.

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?

Working Example

Here is a working example with parameters that test Ajax.post(callbackurl,params) and send data with POST and GET at the same time. It also contains a setTimeout counter that some have been struggling with. You can copy and paste it and work from there. Hope it helps! -- 11:48, 23 April 2009 (PDT)

<!-- Sample code written by Fabio Quinzi, student of Computer Science at University of Bologna --> <!-- You will need to change '$callbackurl' and possibly the 'require_once' line --> <!-- Please stop changing this page and writing code that doesn't work. This code works well. Thanks! --> <h1>Example Page</h1> <h3>You Are:</h3> <fb:name uid="<?=$user_id?>" useyou="false"/><br/> <?php $callbackurl='http://www.yourwebsite.com/post_example.php'; //you can find post_example.php file down. $initcounter=0; //perhaps retrieve value from database echo "<h3>setTimeout Counter increased in the script: <span id='counterSpan'>".$initcounter."s</span></h3><br/>"; ?> <h2>Div where test links:</h2> <div id="actionDiv">[[Nothing happening in this div yet.]]</div><br/> <h3>Select <a href="#" onclick="do_ajax('actionDiv',0);return false;">Option 1 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv',1);return false;">Option 2 (AJAX)</a></h3> <h3>Select <a href="#" onclick="do_ajax('actionDiv',2);return false;">Option 3 (AJAX)</a></h3> </div> <script type="text/javascript"> <!-- function do_ajax(div,val) { var ajax = new Ajax(); ajax.responseType = Ajax.FBML; ajax.ondone = function(data) { document.getElementById(div).setInnerFBML(data); } var params={"action":'select',"option":val,"othertest":'anystring',"otherval":100}; //add parameters as comma separated "param":value ajax.post('<?=$callbackurl?>?t='+val,params); //GET values sended with "val" and POST values sended with "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>


Your "post_example.php":

<?php echo "Your string in POST method is: ".$_POST['othertest']."</br>Your number POST method is: ".$_POST['otherval']."</br>"; $user = isset($_POST['fb_sig_user']) ? $_POST['fb_sig_user'] : null; if ($_GET['t'] == 0) { // Ajax.RAW tested with GET 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 tested with GET 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 tested with GET echo 'This is an FBML string. The current time is: '.date('r').', and you are '.($user ? '<fb:name uid='.$user.' useyou=false />' : 'anonymous').'.'; } ?>

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.'); }


How to load a file in a div with loading image

<script type="text/javascript"> <!-- function General_Refresh(url,div){ //Showing the load image (pay attention to /> of <img document.getElementById(div).setInnerXHTML('<span id="caric"><center><img src="http://www.yourdomain/load.gif" /></center></span>'); var ajax = new Ajax(); ajax.responseType = Ajax.FBML; ajax.ondone = function(data) { //Hide the loading image document.getElementById('caric').setStyle('display','none'); document.getElementById(div).setInnerFBML(data); } //If there are errors re-try ajax.onerror = function() { General_Refresh(url,div); } ajax.post(url); } General_Refresh("mydomain.com","mydiv"); //--> </script> //Example <div id="mydiv"></div><a onclick='General_Refresh("mydomain.com","mydiv");'>Load content</a>
reference