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().
Related
I want to use sqlite db for my iOS application using phone gap. I add sqlite plugins, linked sqlite libraries. Did everything correct, when I run my app in emulator iOS 6.1, it launches fine but not giving any alert, I want to display on db success etc. Also I don't know if database is created successfully, where can I find that db file. Here is my code. Thanks in advance.
<!DOCTYPE html>
<html>
<head>
<title>Storage Example</title>
<script type="text/javascript" charset="utf-8" src="js/cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="js/lawnchair.js"></script>
<script type="text/javascript" charset="utf-8" src="js/SQLitePlugin.js"></script>
<script type="text/javascript" charset="utf-8" src="js/Lawnchair-sqlitePlugin.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
//
function onDeviceReady() {
alert("correct");
var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
db.transaction(populateDB, errorCB, successCB);
}
// Populate the database
//
function populateDB(tx) {
tx.executeSql('DROP TABLE IF EXISTS DEMO');
tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');
tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');
tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}
// Transaction error callback
//
function errorCB(tx, err) {
alert("Error processing SQL: "+err);
}
// Transaction success callback
//
function successCB() {
alert("success!");
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Database</p>
</body>
</html>
The cordova.js file is normally in the <project_name>\platforms\android\assets\www directory.
You have shown it to be in <project_name>\platforms\android\assets\www\js as per your code.
<script type="text/javascript" charset="utf-8" src="js/cordova.js"></script>
You need to check the correct path of your cordova.js file. If it is in www directory than you need to change the script tag as below.
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
Is the onDeviceReady() function being fired?
is the alert("correct") being called?
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();
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.
I'm struggling to integrate Cordova(=Phonegap) with Ember.js, and jQuery Mobile. Ember.js + jQuery Mobile works fine, as loading index.html in any desktop browser successfully loads the app.
Using xCode 4 and the iPhone 5.1 simulator, it doesn't show any content within handlebar tags. Which means Ember.js fails to load.
index.html:
<html lang="en">
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta charset="utf-8">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
</head>
<body>
<script type="text/x-handlebars" data-template-name="main">
this text is NOT displayed
</script>
<div> this text IS displayed </div>
<script src="js/vendor/jquery.min.js"></script>
<script src="js/vendor/jquery.mobile.js"></script>
<script src="js/vendor/ember.js"></script>
<script src="js/app/app.js"></script>
<script src="js/vendor/cordova-1.5.0.js"></script>
<script type="text/javascript">
// If you want to prevent dragging, uncomment this section
function preventBehavior(e){
e.preventDefault();
};
document.addEventListener("touchmove", preventBehavior, false);
document.addEventListener("deviceready", onDeviceReady, false);
/* When this function is called, Cordova has been initialized and is ready to roll */
/* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
see http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
for more details -jm */
function onDeviceReady(){
// do your thing!
}
</script>
</body>
</html>
Found the problem. XCode was reporting:
ERROR whitelist rejection: url='http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css'
Following this, I added *.jquery.com to the ExternalHosts array, within Cordova.plist.
Why the following code doesn't work? (if I change remote source there to local, then it works well)
<!DOCTYPE html>
<html>
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script>
$(document).ready(function() {
$("input#autocomplete").autocomplete({
source: "http://jqueryui.com/demos/autocomplete/search.php",
minLength: 2,
select: function( event, ui ) {
}
});
});
</script>
<style>
.ui-autocomplete-loading { background: white url('http://jqueryui.com/demos/autocomplete/images/ui-anim_basic_16x16.gif') right center no-repeat; }
</style>
</head>
<body style="font-size:62.5%;">
<input id="autocomplete" />
</body>
</html>
same origin policy as the source requires a script from another site to be run.
http://en.wikipedia.org/wiki/Same_origin_policy
You could change the source to use a jquery ajax call to another site which can return jsonp.
See this for an example: http://jqueryui.com/demos/autocomplete/#remote-jsonp
or ensure that the source url given returns jsonp.