Sujesh Arukil
Sujesh Arukil

Reputation: 2469

Phonegap Windows Phone 7 Dynamic HTML loading and cross-domain calls using jQuery

Alright, I have searched a lot and I get a lot of Android dev using Phonegap. A couple of questions:

  1. How do I load a local HTML file into a div in Phonegap using jQuery? Something like:

    $('#contentDiv').load(url, function(response){});

I know Android files can be accessed using android_assets/www/html/file.html. What is the equivalent of this in Windows Phone 7 and iOS? I tried www/html/file.html but I keep getting 404 not found.

  1. Now this is the one that is driving me nuts! Basic Ajax post to a cross domain. From the Phonegap website it says no cross-origin issues with Phonegap because it is from a local file, but every single time I hit the error handler and the status is 0.

Any help would be greatly appreciated. I know there are a lot of devs out there trying to do this and someone must have cracked it.

Upvotes: 3

Views: 2044

Answers (2)

LauroNolasco
LauroNolasco

Reputation: 1

var path = window.location.href; path = path.substring( 0 , path.indexOf('index.html') );

Upvotes: 0

Sujesh Arukil
Sujesh Arukil

Reputation: 2469

Alright, to all those who might hit on this. Here is how to get things working with loading files and making ajax calls.

  1. Make sure you are loading all your initialization scripts in the "deviceready" callback of Cordova phonegap. If you don't and try to make a call something like

$('#contentDiv').load(url, function(response){});

Cordova does not know about the url mapping you are trying to hit. Cordova hooks into the ajax call and will pick the file locally and provide it to your callback. If Cordova is not initialized (i.e the device ready has not fired), the browser control treats it like a remote get and lands you in to the usual Cross-Origin issue and rejects it. At least, this is what I think is happening. So make sure your device ready function fires, before you make ajax calls for files.

  1. $.support.cors = true; to the rescue. Add this before you make an ajax call for a remote resource. Obviously, step 1 should be the one to initialize your local scripts.

here is a modified index.js. What this does? Well, it checks if the navigator is a mobile device and not a desktop and also sets if the device is using cordova.

I am using require.js to load my modules. the bootstrapper.js is the file that will load my initial screen and do what it needs to do to get the first screen inside index.html.

var app = {
   // Application Constructor
   isCordova: false,
    initialize: function () {
        app.bindEvents();
    },
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// `load`, `deviceready`, `offline`, and `online`.
bindEvents: function () {
    window.isCordova = app.isCordova;
    if (app.isMobile())
        document.addEventListener('deviceready', app.cordovaReady, false);
    else
        app.onReady();
},
cordovaReady: function () {
    window.isCordova = true;
    app.onReady();
},
// deviceready Event Handler
//
// The scope of `this` is the event. In order to call the `receivedEvent`
// function, we must explicity call `app.receivedEvent(...);`
onReady: function () {
    app.configureRequire();
    app.define3rdPartyModules();
    app.loadPlugins();
},
isMobile: function () {
    var testMobile = function (a) {
        return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))
    }
    window.isMobile = testMobile(navigator.userAgent || navigator.vendor || window.opera);
    return window.isMobile;
},
configureRequire: function () {
    requirejs.config({ baseUrl: 'js/app', paths: { 'filePath': '../../html'} });
},
define3rdPartyModules: function () {
    //this function defines a require js modules and attaches it to the root.

    define('jquery', [], function () { window.jQuery.support.cors = true; return window.jQuery; });
    define('ko', [], function () { return window.ko; });
    define('bootstrap', [], function () { return window.bootstrap; });
    define('amplify', [], function () { return window.amplify; });
    define('infuser', [], function () { return window.infuser; });
    define('moment', [], function () { return window.moment; });
    define('sammy', [], function () { return window.Sammy; });
    define('underscore', [], function () { return window._; });
    define('notifier', ['jquery', 'bootstrap'], function () { return window.Notification });

},
loadPlugins: function () {
    requirejs([], app.boot());
},
boot: function () {
    require(['bootstrapper'], function (bs) {
        bs.run();
    });
}

};

Note that I already have my base libraries included in the index.html and I am just creating a global namespace for all my core libraries. Rest of my app specific files will be loaded on demand by require.

enjoy!

Upvotes: 2

Related Questions