Skip to content

Instantly share code, notes, and snippets.

@ggendre
Created September 10, 2013 10:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggendre/6507448 to your computer and use it in GitHub Desktop.
Save ggendre/6507448 to your computer and use it in GitHub Desktop.
BlackBerry10 AJAX Fix via QML fix ajax calls via a QML gateway. see story here (fr) : http://www.haploid.fr/blog/2013/09/10/blackberry10-et-ajax/
/* bind handleAjax native function to a message sent by the webview JavaScript
send result to webview
*/
WebView {
id : webview
onMessageReceived: {
try {
if (message && message.data) {
var jsonObj = JSON.parse(decodeURIComponent(message.data));
switch (jsonObj.type){
case "ajax":
handleAjaxCall(jsonObj.options, function(params){
params.callbackID=jsonObj.callbackID;
//Send back the result to JS
webView.postMessage(JSON.stringify(params));
});
break;
}
}
} catch (e) {
console.log('ERROR in received message: ' + e;
}
}
}
/* mimics $.ajax jQuery methods on the native side
and send a result as a JSON
*/
function handleAjaxCall(options,callback){
var url= options.url;
var type= (options.type in [ 'POST', 'GET' ]) ? options.type : "GET"; //default to GET
var data = options.data ? options.data : {}; //default to empty params
//add params to url if sending data through GET
if (type=="GET"){
url+="?"+serializeAjaxParams(options.data);
}
var request = new XMLHttpRequest();
request.onreadystatechange=function() {
if(request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
try{
var response = JSON.parse(request.responseText);
}catch(e){
var response = request.responseText;
}
var params={
success : true,
data : response
}
callback(params);
}
else {
// This is very handy for finding out why your web service won't talk to you
console.log("Native Ajax Error " + request.status + ", " + request.statusText);
var params = {
error: true,
status : request.status,
statusText : request.statusText
}
callback(params);
}
}
}
var encodedString = encodeURIComponent(data);
request.open(type, url, true); // only async supported
// You might not need an auth header, or might need to modify - check web service docs
//request.setRequestHeader("Authorization", "Bearer " + yourAccessToken);
// Post types other than forms should work fine too but I've not tried
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Form data is web service dependent - check parameter format
var requestString = "text=" + encodedString;
request.send(requestString);
}
//returns the querystring encoding of a javascript object
//also converts recursive objects (using php "array" notation for the query string)
function serializeAjaxParams(obj, prefix) {
var str = [];
for(var p in obj) {
var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
str.push(typeof v == "object" ?
serializeAjaxParams(v, k) :
encodeURIComponent(k) + "=" + encodeURIComponent(v));
}
return str.join("&");
}
/*
this is the webview side, add this in a script tag in your webview
*/
var lib=window.Zepto || window.jQuery;
if (lib){
//store callbacks in an array
var callbacks=[];
//replace $.ajax and send options to native
lib.ajax=function(options){
//add a new callback to treat the result of the call
callbacks.push(function(params){
if (params.success && options.success){
options.success(params.data);
}else if (params.error){
options.error({ status:params.status, statusText:params.statusText });
}
};
navigator.cascades.postMessage(encodeURIComponent(JSON.stringify({
type: "ajax",
options : options
callbackID : calbacks.length
})));
};
//handler for messages sent from the nativeSide
navigator.cascades.onmessage=function(jsonObj){
if (jsonObj.callbackID && callbacks[jsonObj.callbackID]){
//automatically call the result callback
callbacks[jsonObj.callbackID](jsonObj);
}else{
//treat other messages from the native side
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment