Skip to content

Instantly share code, notes, and snippets.

@aj-justo
Last active August 29, 2015 14:06
Show Gist options
  • Save aj-justo/0d24c5623bed39cb14f5 to your computer and use it in GitHub Desktop.
Save aj-justo/0d24c5623bed39cb14f5 to your computer and use it in GitHub Desktop.
Cordova development notes (versions 2.8.x)

Cordova 2.8 development notes

Events nightmare

This page throws a bit of light on the subject:

To move to another page before a page loads (login in this case): use pagebeforechange. This event is fired twice, first when put all pages (or at least all involved in this page changing) in the root dir use event.preventDefault() inside the pagebeforechange just after calling changePage()

Karma + Jasmine testing

Jasmine needs some additions to work with the API calls and with JQM: jasmine-ajax and jasmine-jquery respectively. Jasmine-jquery has a known bug with Chrome and it also needs a workaround to play nicely with jasmine-ajax: (https://github.com/velesin/jasmine-jquery#cross-domain-policy-problems-under-chrome)

Just moving the jasmine.Ajax.useMock() after the call to loadFixtures() inside the BeforeEach:

     jasmine.getFixtures().fixturesPath = 'base';
     loadFixtures('signup.html');
     jasmine.Ajax.useMock();

After adding a fixture in a BeforeEach(), we can setup the knockout viewmodel:

	jasmine.Ajax.useMock();
	viewmodel = new userUpdateSharedViewModel();
	ko.applyBindings(viewmodel, $('[data-role="page"]')[0]);

And load the responses for all the ajax calls made by the viewmodel:

 _.each(ajaxRequests, function(request){
     request.response(
		{ status: 200, 
		responseText:mockAPIResponses[request.url] 
		}
	);
});

Also, when running jasmine from a browser, the version of jasmine and jasmine-ajax appear not to be compatible: jasmine-ajax calls for spec.after() and the current version of jasmine uses spec.afterFn(). This does not happen when running the tests via karma, I guess the npm installation uses an older version of jasmine.

Serving jasmine-jquery fixtures with karma’s webserver: The files need to be included in the conf file under files like this:

{
    pattern: 'pages/*.html',
    watched: true,
    included: false,
    served: true
}

And the html2js preprocessor needs to be excluded (it is included by default apparently, but not documented!!):

preprocessors: {
    '**/*.coffee': 'coffee'
}

Related: karma-runner/karma#481

Testing device-dependent code

All the code that depends on plugins etc (things not available under normal test conditions/browser) must be separated, perhaps keeping a wrapper object with the dependencies so we can change this object when testing. Something like: { networkStatus: window.navigator.network, gelocation: cordova.require(“gelocation”) } And we change it for: { networkStatus: dummyNetwork, geolocation: dummyGeolocation }

Orientation change

The page element was not re-sizing correctly, leaving a white “patch” on the bottom half of the screen. Bug described here: http://forum.jquery.com/topic/jquery-mobile-white-area-when-changing-orientation

Added:

$( window ).on( "orientationchange", function( event ) {
    $( window ).trigger( "throttledresize");
});

And CSS:

body, html {
    height: 100% !important;
    min-height: 100% !important;
}

[data-role="page"] {
    height: 100% !important;
    min-height: 100% !important;
}

Note: If using iScroll, the scroller element cannot be the same one as the page element given the height attributes above.

Avoid flash of the DOM elements when transitioning page

When using knockout with AJAX, JQM shows the DOM elements of the page for a millisecond before knockout hides them again (because of the conditional bindings that check for our loaded() flag) until the AJAX is done.

I think the only way to avoid this is to set the content elements as hidden via css by default, and put them back to visible either in the knockout viewmodel or in the a pageshow event handler. I did the latter to avoid repeating it on every viewmodel.

Android 2.x browsers AJAX PUT calls must include some data: http://stackoverflow.com/questions/5808963/android-jquery-ajax-error-length-required window.location.search is undefined. ajax cache needs to be disabled

Backbutton on android

The event can be handled but it has some limitations: http://stackoverflow.com/questions/9631933/override-android-backbutton-behavior-only-works-on-the-first-page-with-phonegap

Apparently the event is un-subscribed if we use navigator.app.exit() inside the handler.

Getting active page with JQM: ($.mobile.activePage.attr('id') Offline state (no internet connection): document.addEventListener("offline", function() { alert("No internet connection"); }, false);

Debugging android

adb logcat -s “CordovaLog” The android browser does not appear to accept more than one argument to console.log or debug. It needs to be one string only or separate the args in multiple console.log calls. To debug geolocation there is also a very useful flag:

DeviceReady event

Both in Android and iOS the “device” plugin has to be added to config.xml, otherwise we do not receive this event, for IOS:

Barcode reader plugin for iOS

To solve this issue: https://github.com/phonegap/phonegap-plugins/issues/225 It needs this fix: https://github.com/phonegap/phonegap-plugins/commit/1b0bd50d0c116ec782e425d3f9fc40bf518d80eb

Barcode reader plugin for Android

Some general info on how to install this plugin and any other android plugin: http://stackoverflow.com/questions/16919823/zxing-barcode-scanner-plugin-for-phonegap-android-not-working-on-nexus-7-which-i
THIS IS IN FACT A VERY USEFUL LINK TO REMIND MYSELF ABOUT HOW TO LINK PROJECTS My problems were: mixing library and plugin code for different cordova versions and not updating the library (project) with: android update project --path ./ --target 5

iOS 7 full screen mode

I put this under a pageinit listener: if (navigator.userAgent.match(/iPhone OS 7/i)) { $("[data-role='page']").css("margin-top", "30px"); }

Sending data with PUT/POST request with jQuery

If we pass jquery’s ajax() an object as the data to be send, it will by default convert it to form-data: param1=a&param2=b We need to stringify the object and set processData to false: ajaxOptions.processData = false; ajaxOptions.data = JSON.stringify(params);

iOS forms and jquery mobile messages

jQuery mobile messages ($.mobile.loading() etc) are hidden behind the virtual keyboard when a form is submitted and the last used input retains focus. To hide the virtual keyboard so msgs are visible just blur() all the elements on submit, like:

$("#FirstName, #LastName, #Email").change().blur();

Note: the change() call is to force knockout to update the observables bind to that input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment