I am creating a Phonegap/Jquery Mobile App in Android using a WebViewClient and when user clicks on the button I want to show a spinner while I load a JNI/javascript function. However I am unable to do so with the code below.
NOTE: If I remove the call to the JNI/Javascript function then the spinner showed up as expected. Helper is a java class that is registered from DroidGap onCreate() method as appView.addJavascriptInterface(helperObject, "Helper");
Also if copy pasted as .html and browsed through browser will work (offcourse I am not calling the JNI/Javascript function that time as well) meaning it shows the spinner provided I have a sleep() time. However when I am using Android it doesn't show. The index.html is in assets/www folder.
<head>
<title>Employee Finder</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.20/jquery-ui.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script type="text/javascript" src="http://fgnass.github.com/spin.js/spin.js"></script>
<!-- <script src="phonegap-1.3.0.js"></script> -->
<script>
$(document).ready(function() {
$('#findemp').click(function() {
var empNumber = $("#employeenumber").val();
showSpinner();
var empdetail = JSON.parse(window.Helper.getEmpDetails(empNumber));
//Above call takes 3-4 sec and is a JNI call meaning calling a java function.
hidespinner();
});
});
function showSpinner()
{
var opts = {
lines: 13, // The number of lines to draw
length: 7, // The length of each line
width: 4, // The line thickness
radius: 10, // The radius of the inner circle
rotate: 0, // The rotation offset
color: '#000', // #rgb or #rrggbb
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: 'auto', // Top position relative to parent in px
left: 'auto' // Left position relative to parent in px
};
var spinner = new Spinner(opts).spin();
$("#loading").append(spinner.el);
}
function hidespinner(){
$('.spinner').hide();
}
</script>
</head>
<body>
<div data-role="page" id="page1">
<div data-role="header">
<h1>Find Employee Data</h1>
</div>
<div data-role="content" id="searchDetails">
<input name="employeenumber" type="text" id="employeenumber" placeholder="Employee Number" min="13"/>
<input type="button" id="findemp" data-theme="b" value="Find Employee"/>
<div id="loading" ></div>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
<div data-role="page" data-theme="b" data-add-back-btn="true" id="page2">
<div data-role="header">
<h1>Page Two</h1>
</div>
<div id="empDetails">
<p><b>Name: </b></p><p id="name"></p>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
</html>
Spin.js is ok, but if you're already using JQuery mobile, you're better off using the built-in spinner.
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
in the header, and then:
$.mobile.loadingMessageTextVisible = true;
$.mobile.loadingMessage = "please wait...";
$.mobile.showPageLoadingMsg();
shows the built-in jquery mobile spinner.
$.mobile.hidePageLoadingMsg();
hides the mobile spinner.
So using a timeout function seems to be sort of working. Its not a solution but at least I see the spinner for some time and then the function executed.
$('#findemp').click(function() {
showSpinner('#loading');
setTimeout(function() {
getempData();
hidespinner();}, 1000);
});
function getempData()
{
var empNumber = $("#employeenumber").val();
var empdetail = JSON.parse(window.Helper.getEmpDetails(empNumber));
//transition to a result page here
}
Related
I am trying to implement a switch element using onsen ui to enable/disable BT and having trouble talking to the controller js.
<script>
var app = angular.module('app', ['onsen']);
app.controller('Controller', function($scope) {
$scope.item=[{selected:true}];
$scope.enBT = function(){
var Checked = BTSwitch.isChecked();
alert(Checked);
}
}
</script>
Below is my HTML code.
<div class="app">
<h1 >Apache Cordova using Onsen</h1><br /><br />
<ons-span id="enBluetooth" style="font-size: 40"> Enable bluetooth
<label class="switch">
<input type="checkbox" var="BTSwitch" ng-model="item.selected" ng-change="enBT" class="switch__input">
<div class="switch__toggle"></div>
</label>
</ons-span><br />
</div>
The switch UI displays but I cannot get it to respond to ng-change nor does it show the startup state as true, which is set in JS. Please can someone tell me what I am doing incorrectly? Thanks for your help!
First, you need to set ng-app attribute in the wrapper element, or call angular.bootstrap(document, ['app']), to run the app.
Second, you need to set ng-controller attribute in the wrapper element to bind the controller to the view.
Third, $scope.item doesn't need to be an array. Just $scope.item = {selected: true} is enough.
And there are a few other mistakes in your code. Try below snippet.
var app = angular.module('app', ['onsen']);
app.controller('Controller', function($scope) {
$scope.item= {selected:true};
$scope.enBT = function(){
var Checked = $scope.item.selected;
alert(Checked);
};
});
<link href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.6/build/css/onsen-css-components.css" rel="stylesheet"/>
<link href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.6/build/css/onsenui.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.6/build/js/angular/angular.min.js"></script>
<script src="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.6/build/js/onsenui.min.js"></script>
<div ng-app="app" class="app" ng-controller="Controller">
<h1 >Apache Cordova using Onsen</h1><br /><br />
<ons-span id="enBluetooth" style="font-size: 40"> Enable bluetooth
<label class="switch">
<input type="checkbox" var="BTSwitch" ng-model="item.selected" ng-change="enBT()" class="switch__input">
<div class="switch__toggle"></div>
</label>
</ons-span><br />
</div>
I am developing android apps using phonegap + Jquery mobile. My apps displaying the list in listview div but look and feel of listview not working on 2.3.3 and working fine on version greater than 3.0.
following is the my index.html page. please suggest me answer.
<!DOCTYPE HTML>
<html>
<head>
<title>ListView</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
<link rel="stylesheet" href="js/jquery.mobile-1.4.1.css" />
<script src="js/jquery-1.10.2.min.js"></script>
<script src="cordova.js"></script>
<script src="js/jquery.mobile-1.4.1.js"></script>
</head>
<body>
<div data-role="page" id="courseList">
<div data-theme="a" data-role="header">
<h3>
Course List
</h3>
</div>
<div data-role="content">
<!-- <div class="example-wrapper" data-iscroll> -->
<ul data-role="listview" id="output" data-theme="b">
</ul>
<!-- </div> -->
</div>
</div>
</body>
<script>
$(document).ready(function() {
if(window.isphone) {
document.addEventListener("deviceready", onDeviceReady, false);
} else {
onDeviceReady();
}
});
// device APIs are available
function onDeviceReady() {
// Now safe to use device APIs
$.ajax({
url:"http://www.cilibrary.ojaswitech.com/getLatestNews",
// crossDomain: true,
//type : "POST",
dataType: 'json',
async: true,
success: function (result) {
$.each(result, function(i, item) {
$('ul').append('<li><a href="">' + item + '<p></li>');
});
$('#output').listview("refresh");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
})
}
</script>
</html>
following is the two images. first is left side image 2.3.3 and second is right side image 4.2.2
This is a known bug which is introduced in version 1.4.1 and effects Android 2.3.x devices and IE8. The problem is in lines 3195 and 3222 of jquerymobile.js. There's a default property which happens to be a reserved keyword.
You can solve this problem either by modifying these two lines;
duration = $.fn.animationComplete.default; // this
duration = $.fn.animationComplete.defaultDuration; // to this
// and
$.fn.animationComplete.default = 1000; // this
$.fn.animationComplete.defaultDuration = 1000; // to this
or wait until version 1.4.2 is out with the fix for this bug.
Reference
Acctually there might be an even easier way. Try with replacing:
$('#output').listview("refresh");
with this instead:
$('#output').listview("create");
=) Good luck!
Danny
I have a PhoneGap application that uses JQuery mobile to navigate between pages.
When I navigate from the main page to a page containing a Google map, the map shows only a single tile at a time in the top left corner like this:
What can be the reason for this ?
**
Source Code:
The following script is in the head of my page
<script>
$(document).on("pageinit", "#stores", function () {
var centerLocation = new google.maps.LatLng('57.77828', '14.17200');
var myOptions = {
center: centerLocation,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
callback: function () { alert('callback'); }
};
map_element = document.getElementById("map_canvas");
map = new google.maps.Map(map_element, myOptions);
var mapwidth = $(window).width();
var mapheight = $(window).height();
$("#map_canvas").height(mapheight);
$("#map_canvas").width(mapwidth);
google.maps.event.trigger(map, 'resize');
});
</script>
My Page is like this
<!-- Home -->
<div data-role="page" id="home">
.
.
.
</div>
<div data-role="page" id="stores">
<div data-role="content" id="map_canvas"></div>
</div>
I navigate from home to the maps page like this:
Stores
Update
after applying Gajotres solution the tiles become like this
intro
Newer versions of jQuery Mobile and Google Maps v3 are a little bit special.
Your first problem was using pageinit event to the the calculation. At that point you cant get a correct page height and width. So instead use pageshow, you will find it working in my example.
Before you show the map you need to resize its content DIV. This is because content div will resize according to available inner elements. So we need to fix this manually, through javascript or CSS. I already have a answer on that question: google map not full screen after upgrade to jquerymobile 1.2 but I can also show you a working example:
Working example
Working jsFiddle example: http://jsfiddle.net/Gajotres/GHZc8/ (Javascript solution, CSS solution can be found in a bottom link).
Code
HTML
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
</head>
<body>
<div data-role="page" id="index">
<div data-theme="a" data-role="header">
<h3>
First Page
</h3>
</div>
<div data-role="content" id="content">
<div id="map_canvas" style="height:100%"></div>
</div>
<div data-theme="a" data-role="footer" data-position="fixed">
<h3>
First Page
</h3>
</div>
</div>
</body>
</html>
Javascript
Here's a function used to calculate correct page height:
$('#map_canvas').css('height',getRealContentHeight());
function getRealContentHeight() {
var header = $.mobile.activePage.find("div[data-role='header']:visible");
var footer = $.mobile.activePage.find("div[data-role='footer']:visible");
var content = $.mobile.activePage.find("div[data-role='content']:visible:visible");
var viewport_height = $(window).height();
var content_height = viewport_height - header.outerHeight() - footer.outerHeight();
if((content.outerHeight() - header.outerHeight() - footer.outerHeight()) <= viewport_height) {
content_height -= (content.outerHeight() - content.height());
}
return content_height;
}
Another solution
There's also another solution to this problem that only uses CSS and it can be found HERE. I prefer this solution cause it don't require javascript to correctly fix the map height.
CSS:
#content {
padding: 0;
position : absolute !important;
top : 40px !important;
right : 0;
bottom : 40px !important;
left : 0 !important;
}
One last thing
Also if page width is still incorrect just set it to 100%:
$('#map_canvas').css('width', '100%');
I have had this issue for months banging my head against the wall trying to find a solution. Even setting the style properties for the content and map-canavas divs did not solve all the problems. google.maps.event.trigger(map, "resize") did not do it either. The map was full screen now but still centered in the top left. And if you called your initialize functions on every pageshow the map would reset back to its original position each time.
I was able to come up with this called on the pageshow event and solved all my problems!
$('map-page').on("pageshow", function() {
var latLng = map.getCenter();
google.maps.event.trigger(map,'resize');
map.setCenter(latLng);
});
CSS
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
.ui-page { -webkit-backface-visibility: hidden; }
</style>
Here is my content and map-canvas div.
<div data-role="content" id="mapContent" style="padding:0;position:absolute;
top:40px;right:0px;bottom:60px;left:0px; ">
<div id="map-canvas" style="width:100%;" >
</div>
</div><!-- /Content -->
It gets the current center of the map, resizes the map to the current div, then sets the map center. This way, if the user navigates away from the page and comes back, the map does not lose its position.
Hope this helps.
Robert
Developing an android app in html5(phonegap) and I had to use a scrollView. Could find anything in html5 as we have in Java so I'm trying to use the library iScroll which served the purpose of scrolling but as I scroll down it bounces back to top, I suppose it is called rubber-band-effect. How do I handle this glitch? Plus as I scroll down by dragging I get a warning in Logcat:
W/webview(2795): Miss a drag as we are waiting for WebCore's response for touch down.
Check my following code in which the list items are getting dynamically added which should not be the issue, the problem IMO lies in html itself.
<!DOCTYPE html>
<html>
<head>
<title>Storage Example </title>
<link rel="stylesheet" type="text/css" href="indexCss.css" />
<style type="text/css" media="all">
body,ul,li {
padding:0;
margin:0;
border:0;
}
</style>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
<script src="index.js" type="text/javascript" charset="utf-8" >
</script>
</head>
<body>
<header>
<input type="text" id="name" placeholder="enter name" />
<input type="button" value="Add" onclick='Add();' />
</header>
<div id="wrapper">
<div id="scroll-content">
<div id="result"></div>
</div>
</div>
<footer>
Some Footer Content
</footer>
<script type="text/javascript" src="iscroll.js"></script>
<script type="text/javascript">
var theScroll;
function scroll() {
theScroll = new iScroll('wrapper');
}
document.addEventListener('DOMContentLoaded', scroll, true);
</script>
</body>
</html>
I had this problem solved, removing the height:100%; property from my wrapper.
bottom:0; made sure the wrapper stretched all the way to the bottom of the screen.
Try this:
scroll = new iScroll(this, {
useTransform: false,
useTransition: true
});
If does not work, go through this:
https://groups.google.com/forum/#!topic/iscroll/CMB9d_e5d4Y
This problem occurs when you have a container div for your wrapper The fix for this is to set the height of the container to 99%.
Following is the CSS which finally fixed this issue for me:
#productsScreen{ /* my container */
height: 99%;
z-index: 1;
top: 0px;
left: 0;
overflow: auto;
}
#productListWrapper{
background:transparent;
position:absolute;
z-index:1;
top: 88px;
bottom:49px;
left:0;
width:100%;
overflow:auto;
}
#productsListScroller {
position:absolute; z-index:1;
-webkit-tap-highlight-color:rgba(0,0,0,0);
width:100%;
padding:0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
}
Hope that helps!
Had the same issue and after sweet midnight debugging fount that my wrapper was resizing for some reason to height way bigger than the phone screen. Im using jquery mobile paging and somehow it was messing with the iScroll. Here is how i solved it:
HTML
<div id="screen" data-role="page">
<div data-role="content">
<div id="list-wrapper">
<ul>
...
</ul>
</div>
</div>
<div data-role="footer">
...
</div>
</div>
JS
// the iScroll should be initialized after the page is visible
// to prevent bug with display:none. If you are not using
// jQuery mobile paging this can be skipped.
$('#screen').on('pageshow', function() {
// calculate the expected height of the real content wrapper and set it
var screenHeight = $('#screen').height();
var footerHeight = $('#screen [data-role="footer"]').height();
var realContentHeight = screenHeight - footerHeight;
$('#list-wrapper').css({'height': realContentHeight + 'px'});
// create or refresh the iScroll after resizing the wrapper
if (myScrollFunction != null ) {
setTimeout(function () {
myScrollFunction .refresh();
}, 100);
} else {
setTimeout(function () {
myScrollFunction = new iScroll('list-wrapper');
}, 100);
}
});
I'm using JQuery 1.1.0 and Phonegap 1.9.0 to develop a html5 App for Android. I have a little animation which draws a battery on the canvas and updates it. It looks like a battery, which is loading. It worked very well on android 4.0.4.
Yesterday I received the update to Android 4.1.1 on my Galaxy Nexus. After that change I had issues with my animation. Now it draws to images on the canvas, one is in front and the other is behind with wrong coordinates. I think it has something to do with the Changes to Java Script Engine V8, maybe caching issues?! On every browser on my PC the animation works very well.
My html code is:
<!DOCTYPE html>
<html>
<head>
<title>Hella App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="jquery.mobile-1.1.1.min.css"/>
<script src="jquery-1.7.2.min.js"></script>
<script src="jquery.mobile-1.1.1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova-1.9.0.js"></script>
<style>
.ui-page { background: black;}
</style>
</head>
<body>
<div data-role="page" id="dataPageBattery" data-theme="a">
<h2 align="center">Battery State</h2>
<div data-role="header" data-position="fixed" data-theme="a">
<h1>Car Data</h1>
</div>
<div data-role="content" align="center">
<canvas id="myBatteryCanvas" width="device-width"
height="device-height">
Sorry, your browser doesn't support canvas technology
</canvas>
</div>
<h4 align="center" id="batteryProzent"></h4>
<script type="text/javascript" src="battery.js"></script>
<script>$(document).on("pageshow",init());</script>
<div data-role="footer" data-position="fixed" data-id="persFooter">
<div data-role="navbar">
<ul>
<li>Connect</li>
<li>Cars</li>
<li>Info</li>
</ul>
</div>
</div>
<script>
$('#dataPageBattery').on('swipeleft',function(){
$.mobile.changePage("geolocation.html", { transition: "slide"});
console.log('slideLeft');
})
$('#dataPageBattery').on('swiperight',function(){
$.mobile.changePage("fuelGauge.html", { transition: "slide", reverse: 'true'});
console.log('slideLeft');
})
</script>
</div>
</body>
</html>
My java script code, which I'm loading:
var canvas = document.getElementById("myBatteryCanvas");
var ctx = canvas.getContext("2d");
var x = 50;
var y = canvas.height - 30;
var mx = 2;
var my = 1;
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var prozent = 1;
function drawRect(y, farbe) {
ctx.beginPath();
ctx.rect(124, y, 50, 21);
ctx.fillStyle = farbe;
ctx.fill();
window.setTimeout("draw()", 10);
}
function draw() {
if (y >= 80) {
y -= my;
window.setTimeout("drawRect(y,'red')", 10);
} else if (y >= 50) {
y -= my;
window.setTimeout("drawRect(y,'orange')", 10);
ctx.rect(124, 50 + 50, 50, 40);
ctx.fillStyle = 'orange';
ctx.fill();
} else {
ctx.rect(124, 50, 50, canvas.height - 60);
ctx.fillStyle = 'lightgreen';
ctx.fill();
}
document.getElementById('batteryProzent').innerHTML = '> ' + prozent + ' %';
prozent++;
if (prozent % 4 == 0)
prozent++;
}
function init() {
ctx.rect(122, 40, 54, 100);
ctx.fillStyle = 'floralwhite';
ctx.fill();
ctx.lineWidth = 4;
ctx.strokeStyle = '#303030';
ctx.stroke();
draw();
}
Another nice issue: If I use this html page as the first page to start with inside the Phonegap code, there is no problem. But if I use it inside the whole App, I'm facing the problems.
For this reason, I post my first page too:
<!DOCTYPE html>
<html>
<head>
<title> BLE App</title>
<script type="text/javascript" charset="utf-8" src="cordova-1.9.0.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="Logo.png" />
<link rel="stylesheet" href="jquery.mobile-1.1.0.min.css"/>
<script src="jquery-1.7.1.min.js"></script>
<script src="jquery.mobile-1.1.0.min.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<style>
.ui-page { background: black;}
</style>
</head>
<body>
<div data-role="page" id="mainPage" data-theme="a">
<div data-role="header" data-position="fixed" data-theme="a">
<h1> BLE</h1>
</div><!-- /header -->
<div data-role="content">
<!-- <p> BLE Test App</p> -->
<label for="mainPage_textFrage">Find BLE Devices:</label>
<!-- <input type="text" id="mainPage_textFrage" value="" placeholder="Ihre Frage"/> -->
<a data-role=button id="mainPage_showAnswerButton">Search</a>
</div><!-- /content -->
<div data-role="footer" data-position="fixed" data-id="persFooter">
<div data-role="navbar">
<ul>
<li>Connect</li>
<li>Cars</li>
<li>Info</li>
</ul>
</div><!-- /navbar -->
</div><!-- /footer -->
</div>
<script>
$('#mainPage_showAnswerButton').on('click',function(){
$.mobile.changePage("searchResult.html", { transition: "slideup"});
console.log('click');
})
</script>
</body>
</html>
Is there somebody with same issues? Can somebody help?
Thanks so far!
UPDATE:
I updated JQuery to 1.7.2 and JQuery Mobile to 1.1.1. But still there is no change. The animation isn't working.
Possible solution:
Removing the following line from jquery-mobile-css eliminates the problem:
/*content area*/
.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; }
(removing "overflow-x: hidden" is sufficient).
A better solution is to override the "overflow-x" attribute on the surrounding div-element (not the canvas-element itself).
Example (for battery-status):
<div data-role="content" align="center" data-theme="a" style="overflow-x: visible">
<canvas id="myBatteryCanvas" width="device-width" height="device-height">
Sorry, your browser doesn't support canvas technology
</canvas>
</div>
See also http://code.google.com/p/android/issues/detail?id=35474
When things go wrong when you transition from one page to another but not when you load the page itself standalone, it sounds like you need to (un)load stuff during the page transitions. jQuery Mobile loads anything inside <div data-role="page">...</div> on a page transition. That also means that anything outside these divs is ignored. Not only that, but the javascript code from the previous page still continues on to the next.
I see the two blocks of <script>...</script> at the bottom of the 2 HTML pages and only one of those will load, namely the one on the page that you refresh at. Make sure these scripts are loaded by inserting the the scripts inside the data-role="page divs
You should change the following
<script>$(document).ready(window.setTimeout("init()", 500));</script>
to
<script>$(document).on("pageshow",window.setTimeout("init()", 500));</script>
per the jQM documentation you shouldn't use $(document).ready(...)
We are having the same issue here with our phone running Android 4.1.1. We have an html5 canvas application that displays a slider. The image of the slider is displayed 2 times. On our android 4.1, 4.0, 2.3 devices it displays fine. I don't think you can workaround this defect with a simple java script change. It is simply broken in the latest Jellybean patch.
We've used Nexus S and Galaxy Nexus phones with multiple different versions of android to prove this out (it's not phone specific).