Checking for navigator.globalization on deviceready returns undefined on iOS - ios

I am using PhoneGap 2.2.0 on iOS and binding to the devicready event to see if the navigator.globalization object is there. I am getting undefined.
My code looks like this:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady()
{
alert('deviceready');
navigator.globalization.getLocaleName(function(d)
{
window.localStorage.setItem('localeLanguage', d.value);
console.log('localeLanguage: is'+d.value);
},
function(error)
{
console.log('error getting locale language');
});
}
The alert('deviceready') never fires. I am really at a loss here. I'm setting up my scripts as follows.
<script src="js/jquery-1.8.2.min.js"></script>
<script src="js/jquery.mobile-1.2.0.min.js"></script>
<script type="text/javascript" src="cordova-2.2.0.js"></script>
<script type="text/javascript">
//alert(typeof navigator.globalization);
</script>
<script src="js/jquery.ui.map.full.min.js"></script>
<script src="js/jquery.ui.map.services.min.js"></script>
<script src="js/jquery.i18n.min.js"></script>
<script src="js/languages.js"></script>
<script src="js/oakglobalization.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
<script type="text/javascript" src="js/custom.js"></script>
Any ideas would be helpful as this is a showstopper now.

Try :
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
to add you event listener.
And maybe try to update your cordova version. The current version is the 2.6.0.
Another point : with phonegap, use the Navigator.notification.alert method instead of the native javascript alert. More info here.
Hope this helps ! Bye !

Not sure if you solved it or not, but at least for me ( PG 3.3.0 ) using navigator.globalization I had to install the cordova plugin and change the XML accordingly.
command-line> cordova plugin add org.apache.cordova.globalization
config.xml>
<feature name="Globalization">
<param name="ios-package" value="CDVGlobalization" />
</feature>
On that note, it didn't work on browser emulators ( ie.: ripple ) only on the real iOS xcode emulator ...
Backup your project just in case ;)

Related

jQuery UI error: TypeError: this._addClass is not a function [duplicate]

I am having an issue getting a dialog to work as basic functionality. Here is my jQuery source imports:
<script type="text/javascript" src="scripts/jquery-1.9.1.js"></script>
<script type="text/javascript" src="scripts/jquery-ui-1.11.1.js"></script>
<script type="text/javascript" src="scripts/json.debug.js"></script>
Html:
<button id="opener">open the dialog</button>
<div id="dialog1" title="Dialog Title" hidden="hidden">I'm a dialog</div>
<script type="text/javascript">
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
</script>
From the posts around seems like as a library import issue. I downloaded the JQuery UI Core, Widget, Mouse and Position dependencies.
Any Ideas?
Be sure to insert full version of jQuery UI. Also you should init the dialog first:
$(function () {
$( "#dialog1" ).dialog({
autoOpen: false
});
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
});
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" />
<button id="opener">open the dialog</button>
<div id="dialog1" title="Dialog Title" hidden="hidden">I'm a dialog</div>
if some reason two versions of jQuery are loaded (which is not recommended), calling $.noConflict(true) from the second version will return the globally scoped jQuery variables to those of the first version.
Some times it could be issue with older version (or not stable version) of JQuery files
Solution use $.noConflict();
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
jQuery( document ).ready(function( $ ) {
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
});
// Code that uses other library's $ can follow here.
</script>
If you comment out the following code from the _Layout.cshtml page, the modal popup will start working:
</footer>
#*#Scripts.Render("~/bundles/jquery")*#
#RenderSection("scripts", required: false)
</body>
</html>
Change jQueryUI to version 1.11.4 and make sure jQuery is not added twice.
I just experienced this with the line:
$('<div id="editor" />').dialogelfinder({
I got the error "dialogelfinder is not a function" because another component was inserting a call to load an older version of JQuery (1.7.2) after the newer version was loaded.
As soon as I commented out the second load, the error went away.
Here are the complete list of scripts required to get rid of this problem.
(Make sure the file exists at the given file path)
<script src="#Url.Content("~/Scripts/jquery-1.8.2.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.24.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript">
</script>
and also include the below css link in _Layout.cshtml for a stylish popup.
<link rel="stylesheet" type="text/css" href="../../Content/themes/base/jquery-ui.css" />
I had a similar problem and in my case, the issue was different (I am using Django templates).
The order of JS was incorrect (I know that's the first thing you check but I was almost sure that that was not the case, but it was). The js calling the dialog was called before jqueryUI library was called.
I am using Django, so was inheriting a template and using {{super.block}} to inherit code from the block as well to the template. I had to move {{super.block}} at the end of the block which solved the issue. The js calling the dialog was declared in the Media class in Django's admin.py. I spent more than an hour to figure it out. Hope this helps someone.

cordova inappbrowser iOS issues

I am working on an app for both android and iOS that will be opening external links. I am currently using cordova-plugin-inappbrowser 1.0.1 to open my links and it is working perfectly in Android, but I seem to be running into the same problem that many other people have. In iOS, I do not get a toolbar to appear and thus am stuck as I cannot click on the "done" button (or back/forward buttons for that matter.) I have built the app using both phonegap build online and through the command line tools, with the same behavior in each instance. It does not work in either an emulated environment or a native device environment. I have been searching online and this seems to be an extremely common problem, but none of the proposed solutions have worked over the past 2 days and ~15 hours of testing (for just a stupid little link!) I would like to remain in-app, but would not be opposed to going to safari if that is the only solution. My relevant code and versions:
Phonegap cli-5.1.1 (iOS 3.8/Android 4.02)
Cordova 3.5.0-0.2.7
cordova-plugin-inappbrowser 1.0.1
config.xml relevent code:
<plugins>
<plugin name="InAppBrowser" value="CDVInAppBrowser" />
</plugins>
<feature name="InAppBrowser">
<param name="ios-package" value="CDVInAppBrowser" />
</feature>
index.html:
<link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" />
<link rel="stylesheet" href="jquery/jquery.mobile.structure-1.4.5.min.css" />
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="jquery/jquery-2.1.4.min.js"></script>
<script src="jquery/jquery.mobile-1.4.5.min.js"></script>
<script src="phonegap.js"></script>
<script src="cordova.js"></script>
<script src="cordova_plugins.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Global InAppBrowser reference
var iabRef = null;
function iabLoadStart(event) {
alert(event.type + ' - ' + event.url);
}
function iabLoadStop(event) {
alert(event.type + ' - ' + event.url);
}
function iabClose(event) {
alert(event.type);
iabRef.removeEventListener('loadstart', iabLoadStart);
iabRef.removeEventListener('loadstop', iabLoadStop);
iabRef.removeEventListener('exit', iabClose);
}
// Cordova is ready
//
function onDeviceReady() {
alert('Device is ready!');
//iabRef = window.open('http://apache.org', '_blank', 'location=yes');
//iabRef.addEventListener('loadstart', iabLoadStart);
//iabRef.addEventListener('loadstop', iabLoadStop);
//iabRef.addEventListener('exit', iabClose);
}
</script>
<style type="text/css">
.centeredImage
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
body
{
background: #000 !important;
background-image:url(backgrounds/1080widephone.png) !important;
background-size:cover !important;
}
.ui-content{
background: transparent !important;
}
.ui-page{
background: transparent !important;
}
.ui-footer{
background: transparent !important;
}
</style>
</head>
Various links (all act as buttons):
window.open('url' ,'_blank')
(NOTE: This appears to open in the default WebView for iOS and the inappbrowser for Android)
cordova.InAppBrowser.open('url' ,'_blank', 'location=yes' , 'toolbar=yes', 'toolbarposition=top' , closebuttoncaption=Return'
(NOTE: Nothing happens when I use this in either iOS or Android builds. I based this syntax off of the description)
My kneejerk reaction is that the plugin isn't loading, but I don't see how that can be the case if it is clearly working in an android build but not an iOS build using exactly the same code on phonegap build. Any help would be greatly appreciated, I feel like I'm running around in circles here!
I know this is a late response but I’ve found one possible solution.
In my case, I was using ngCordova’s $InAppBrowser within the Ionic framework to open a file or url. To test this, I was using Xcode’s iPhone simulator as well as Ionic’s “Ionic View” app. Within both of these options, $InAppBrowser will NOT show a “Back” or “Done” button.
However, if you open your project’s .xcodeproj in Xcode and run your application on an actual iOS device, the InAppBrowser should work as expected.
I spent hours on this issue only to discover Ionic View restricts the options of $InAppBrowser. However, I’m still not 100% sure as to why this doesn’t work in the iOS emulator.
Note: I believe all of this applies even if you’re directly using Cordova and not ngCordova.
The values for the options string in
cordova.InAppBrowser.open
needs to be a single string of name=value pairs separated by ,
So try:
cordova.InAppBrowser.open('url' ,'_blank', 'location=yes,toolbar=yes,toolbarposition=top,closebuttoncaption=Return');
Additionally you should make sure your application's links open with the IAB by hijacking them and opening them in the IAB and suppressing the default event... for example with JQuery to hijack all the links in a div with id "infoExternalContent" and open them in the IAB with some options set for iOS only (using Cordova device platform to detect platform):
$('#infoExternalContent').find('a').each(
function() {
var href = $(this).attr('href');
var iabOptions = (device.platform === 'iOS' ? 'location=no,enableViewportScale=yes,transitionstyle=fliphorizontal' : '');
if (href.indexOf('http') === 0) {
$(this).click(function(e) {
e.preventDefault();
cordova.InAppBrowser.open(''.concat(this.href), '_blank', iabOptions);
});
}
}
);
I don't use phonegap build, but I can't imagine that it wants all of this loaded ...
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="jquery/jquery-2.1.4.min.js"></script>
<script src="jquery/jquery.mobile-1.4.5.min.js"></script>
<script src="phonegap.js"></script>
<script src="cordova.js"></script>
<script src="cordova_plugins.js"></script>
cordova.js is loaded twice, along with phonegap.js. Just sayin'
If you uncomment
iabRef = window.open('http://apache.org', '_blank', 'location=yes');
What happens?
I would also try
cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');
If neither of those open a window to apache, I would readd the plugin.

phonegap + jquery mobile, good practices

until now I was not using this index.js that Phonegap recommends :
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
Where should I put my own js functions and events (all my js file), into this, out of this, in another file ?
Where should I call those js files and where should I call the app.initialize, in relation to the position of the calls to the js files ?
Here's my html :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="height=device-height,width=device-width,initial-scale=1.0,maximum-scale=1.0">
<link rel="stylesheet" href="css/jquery.mobile-1.3.2.css" type="text/css" media="all" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="all" />
<script src="js/jquery-1.9.1.js"></script>
<script src="js/index.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
<script src="js/jquery.mobile.config.js"></script>
<script src="js/jquery.mobile-1.3.2.js"></script>
<script src="js/jquery-geturlvar.js"></script>
<script src="js/boardDims.js"></script>
<script src="js/functions.js"></script>
<!-- <script src="cordova.js"></script>-->
</head>
<body>
For now I am compiling using the remote service : $ phonegap remote run android
It would be really useful to have a default template of an app using Phonegap + JQM, for beginners like me ;-)
That index.js is included as an example, you don't really need to use it. It is basically showing you how to work with ondeviceready. You need to use ondeviceready when you work with plugins, since most of their calls will only be available after ondeviceready has been fired. So you hook up your calls to plugins on a listener to ondeviceready. I am doing it like this for instance:
<script type="text/javascript">
function onLoad() {
document.addEventListener("deviceready", MYAPP.events.onDeviceReady, false);
}
</script>
</head>
<body onload="onLoad();">
And inside MYAPP.events.onDeviceReady I do the calls to geolocation, camera, or whatever plugin I'm working with.
BTW, two important things to notice in you example: You need to include cordova.js before you can access ondeviceready or work with any plugin, plus you are including index.js twice. Perhaps you duplicated the <script src="js/index.js"></script> to edit it and include js/cordova.js and forgot to change the name/path?
Apart from that, what I do is separating the app's JS and the external libs in two separate directories for better organisation, like "lib" and "js", so you would include "js/functions.js" and "lib/jquery.js".
I include both the libs and custom JS files at the bottom of the body tag for a slight better performance: Where should I put <script> tags in HTML markup?
And I name the files under "js" (custom JS files for the app) according to their purpose/content, like: events.js, models.js, settings.js, util.js, ... You can see in the snippet above that I have "namespaced" my custom JS objects under the capitalised name of the app, so everything in util.js will be called like: MYAPP.util.formatDate().

How to use (phonegap, angularjs and jquery mobile) for windows phone 8?

when I tried to run even a blank app, the console output is:
"Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?"
Doctype is:
<!DOCTYPE html>
And this are script references:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height" />
<link rel="stylesheet" href="css/jquery.mobile.structure-1.3.0.min.css" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type='text/javascript' src='js/angular.min.js'></script>
<script type='text/javascript' src='js/angular-ui.js'></script>
<script type='text/javascript' src='js/jqm-setup.js'></script>
<script type="text/javascript" src="js/jquery.mobile.js"></script>
<script type="text/javascript" src="js/jquery-mobile-angular-adapter.min.js"></script>
<script type="text/javascript" src="cordova-2.5.0.js"></script>
<script type="text/javascript" src="js/index.js"></script>-->
This error disappears only when I remove the jquery mobile stuff...
Thanks in advance.
I would avoid JQuery Mobile in PhoneGap applications. I got to meet Andrew Trice, Adobe PhoneGap Evangelist, at a DC Droid Meet and listened to him present in a few Webinars. I've heard him say more than once that JQuery Mobile has huge performance issues. He recommended using other frameworks if possible. There are many other frameworks out there with good design, widgets, and samples that make them easy to learn. I think he even created his own called AppUI. Just look around and you'll find some really cool ones.
That error is definitely what it says: your cordova.js file is not being included correctly. Fix that first.
To answer your larger question: Angular, jQuery Mobile, and PhoneGap will play together but it comes with some big caveats.
The biggest issue is that the jQuery Angular Mobile adapter is currently abandoned while they invest time in building a better solution: angular-jqm. That means that the adapter only works with outdated versions of the libraries.
Second: those outdated library versions have some issues working with Windows Phone. These are fixable, too, but lock you into an even less maintainable version of them.
So here is the setup:
<script src="javascripts/vendor/jquery-mobile-1.3.1.js"></script>
<!-- this angular-1.0.6 includes a patch to support WP8 URLs: https://github.com/angular/angular.js/issues/2303 -->
<script src="javascripts/vendor/angular-1.0.6.js"></script>
<script src="javascripts/vendor/jquery-angular-mobile-adapter-1.3.2.js"></script>
Unfortunately I was never able to get partials to load via XHR so I included all pages in index.html document.
<body ng-controller="AppController">
<div data-role="page" id="first" ng-controller="FirstController">
<h1>First Page</h1>
<p>{{foo}}</p>
<p>Second Page</p>
</div>
<div data-role="page" id="second" ng-controller="SecondController">
<h2>Second Page</h2>
</div>
</body>
Then you need to switch off a few niceties in the JavaScript and set up your routes:
<script>
var so_example = angular.module('so_example', []).
config(function ($routeProvider, $locationProvider, $compileProvider) {
// turn off html5 mode so that we just navigate around using hashes
$locationProvider.html5Mode(false).hashPrefix("");
// allow for the odd URLs included in Windows Mobile PhoneGap
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel|x-wmapp0):/);
$routeProvider.
when('/second', {
templateUrl: '#second',
jqmOptions: { transition: 'slide' }
}).
when('/', {
templateUrl: "#first"
});
}).
controller("FirstController", function ($scope) {
$scope.foo = "Hello, World!";
}).
controller("SecondController", function ($scope) {
});
</script>
Now you need to leverage the Cordova library before you bootstrap Angular to your HTML:
var app = (function () {
function onDeviceReady() {
angular.bootstrap(document, ['so_example']);
$.mobile.phonegapNavigationEnabled = true;
}
return {
initialize: function() {
document.addEventListener('deviceready', onDeviceReady, false);
}
};
})();
app.initialize();

self.port is undefined error [on mozilla add-on SDK 1.8]

Following this guide, I did a little variation and I keep receiving this error:
self.port is undefined
at base.js[my content code]
here my add-on code:
PageMod({
include: [data.url('base.html')],
contentScriptWhen: 'start',
contentScriptFile: [data.url('jquery-1.7.2.min.js'),data.url('jquery-ui-1.8.21.custom.min.js'),data.url('base.js')],
contentStyleFile: [data.url('css/mint-choc/jquery-ui-1.8.21.custom.css'),data.url('css/base.css')],
onAttach: function(worker) {
worker.port.on("request", function(txt) {
console.log(txt);
worker.port.emit("response","response for "+txt);
});
}
});
and my content code:
// initialized by jQuery
$(function() {
self.port.on("response",function(txt){console.log("response "+txt);}) //this line is where the error point to.
$('#tabs').tabs();
testLoadLinks();
});
function testReceiveRequest(request) {
console.log('received:',request);
self.port.emit("request",request);
}
I'm using the browser editor with the SDK version 1.8, can someone please help me fix this?
After some testing and debugging, I found out my two mistakes and i'm sorry i didn't put the whole code because I thought it wasn't related:
I had this in base.html
<link type="text/css" href="css/mint-choc/jquery-ui-1.8.21.custom.css" rel="stylesheet" />
<link type="text/css" href="css/base.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.21.custom.min.js"></script>
<script type="text/javascript" src="js/base.js"></script>
and this on main.js
PageMod({
include: [data.url("base.html")],
contentScriptWhen: 'start',
contentScriptFile: [data.url('jquery-1.7.2.min.js'),data.url('jquery-ui-1.8.21.custom.min.js'),data.url('base.js')],
contentStyleFile: [data.url('css/mint-choc/jquery-ui-1.8.21.custom.css'),data.url('css/base.css')],
onAttach: function(worker) {
console.log("attaching...")
worker.port.on("request", function(txt) {
console.log(txt);
worker.port.emit("response","response for "+txt);
});
}
});
My scripts are on the /data/js/ folder, they couldn't be found thus not loading the pageMod part of script in the main.js, but they were being loaded by the content script itself inside the DOM, where self.port is undefined. I just removed the script and styles tags from the base.html because they are already in the pageMod, and fixed the path in the data.url('js/base.js') and the others. Now i learned the scripts in the add-on scope can access the DOM scope and change it, but scripts inside the DOM cannot (they can?) communicate with the add-on scope. If you want scripts to interact with the add-on, you should left them in the add-on scope. I hope to help someone who commits the same mistake.
Thanks canuckistani.

Resources