We are developing a Cordova based Android application.
All HTML pages are local(in assets/www folder).
We load HTML pages using jquery mobile changePage method and register for events(button click events etc) in pageChange callback.
For android 2.3 and above this works fine, requested page is loaded and events(click events etc) are binded properly.
On Android 2.2 we are facing an issue, on changePage method call requested page is loaded but pageChange event is not fired(so click events are not binded properly).
Any idea what could be causing this?
Is there are issue with changePage on lower versions of android?
I don't know if pageChange event is working on an Android 2.2 but there are some easy workarounds.
Pageshow can be used instead. It is last event to trigger before pageChange triggers so it can also be used for event binding.
$(document).on('pagebeforeshow', '#index', function(){
});
One last thing, you don't need to wait for changePage to bind click events. You can use something called delegated event binding. For it to work it doesn't matter if object exists in DOM or not because event will be binded to the document. It will propagate to element only when such need exists, for example if object is clicked.
This is how you do delegated event binding:
$(document).on('click', '#elementID', function(){
});
I think it's high time you drop support to Android 2.2. Even PhoneGap officially deprecated the support to Android 2.2. Only less than 5% use Android 2.2 and below
In my experience I usually use pagecreate event to bind events for buttons etc. This event is fired once the page is created. Try the method below on Android 2.2 and see whether it helps you out.
You can do something as below
$(document).on('pagecreate', '#myPageID', function(){
//Registering button click
$('#myButton').bind('click',function(){
alert('button click');
});
});
Related
I've this following JS code, it's working perfectly in the desktop but it's not working in the touch devices.
jQuery(document).ready(function(){
jQuery("#gallery_trigger").click(function () {
jQuery(".my-second-portfolio").trigger( "click");
});
});
From my analysis, I figured that following line of code is not working
jQuery(".my-second-portfolio").trigger( "click");
I understand that .trigger( "click"); is not appropriate for the touch devices, so could you please help me to work this code in all devices?
Try 'tap' or 'vclick'
http://api.jquerymobile.com/tap/
$(".my-second-portfolio").tap();
The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate. Because of this $(document).ready() will trigger before your first page is loaded and every code intended for page manipulation will be executed after a page refresh. This can be a very subtle bug. On some systems it may appear that it works fine, but on others it may cause erratic, difficult to repeat weirdness to occur.
Classic jQuery syntax:
$(document).ready(function() {
});
To solve this problem (and trust me this is a problem) jQuery Mobile developers created page events. In a nutshell page events are events triggered in a particular point of page execution. One of those page events is a pageinit event and we can use it like this:
$(document).on('pageinit', function() {
});
To execute a code that will only available to the index page we could use this syntax:
$('#index').on('pageinit', function() {
});
There's also another special jQuery Mobile event and it is called mobileinit.When jQuery Mobile starts, it triggers a mobileinit event on the document object. To override default settings, bind them to mobileinit. One of a good examples of mobileinit usage is turning off ajax page loading, or changing default ajax loader behavior.
$(document).on("mobileinit", function(){
//apply overrides here
});
Or you could use something like this:
$('div:jqmData(url="index.html")').on('pageshow',function(){
// code to execute on that page
//$(this) works as expected - refers the page
});
You could try to use $('.my-second-portfolio')[0].click(); to simulate a mouse click on the actual DOM element (not the jQuery object), instead of using the .trigger() jQuery method.
Note: DOM Level 2 .click() doesn't work on some elements in Safari. You will need to use a workaround.
http://api.jquery.com/click/
I'm having separate but related issues relating to dropdown events in both the native and chrome browser on an android device (Samsung Galaxy Tab4).
Chrome - when selecting an item in a dropdown, the change event is fired EVERY time but the UI value doesn't update until focus is changed
Native Browser - The first time a select is changed, everything works fine. All subsequent interactions with select is as follows
--- First time an option is selected, change event DOES NOT fire and value does not update on UI
--- Second time an option is selected, change event does fire, value updates on UI
I'm using knockout with Ajax calls to fill the dropdown list. Here's the template code html (on change event here is just an alert for testing change event):
<div class="col-xs-5 col-sm-5 col-md-2 col-lg-2 search-form-label" data-bind="visibleFade: advancedSearch">
Proceeding Type
</div>
<div class="col-xs-7 col-sm-7 col-md-4 col-lg-4 search-form-data" data-bind="visibleFade: advancedSearch">
<select class="select-12" data-bind="disabled: !proceedingTypeCodes.loaded(), event: {change: onSelectChange}, value: ProceedingType, options: proceedingTypeCodes, optionsText: 'Name', optionsValue: 'Code', optionsCaption: '-- ALL --'"></select>
</div>
The view model is actually built up based on a model brought back from an Ajax call (using the json, it creates the model and binds to self. Values are brought back based on ajax requests, added to select list and loaded is marked as true. This is all called on page load
_dataService.getRemoteSiteData("Case/GetCaseStatusCodes?isForSomething=false", null, _loadCaseStatusCodes);
var _loadProceedingTypeCodes = function (data) {
_viewModel.buildModel({ proceedingTypeCodes: data }, _self);
_self.proceedingTypeCodes.loaded(true);
};
It's worth mentioning that all of this works for all other browsers, devices and platforms. We even have another site that uses this exact same paradigm for building select lists which works great (although there is only one select list on that search page whereas there are multiple ones on this page).
Anyone run into this problem?
I believe this problem is unique to Android's native browser and even when I stripped away knockout, bootstrap, etc, there was still some inconsistency.
What seems to be working is using jquery 'on' and $(this).focus methods to guarantee what you click on is in focus
$('.container').on('click','select',function(){
$(this).focus();
});
I used on as this call is in my _layout page so these inputs won't be on the page when it loads (generally) but it can really go anywhere. Very annoying bug but I think this is a decent workaround.
Related to the chrome issue, this was fixed in Chrome 40.* release
I have set up a small mobile application and during tests I have stumbled upon a problem with older versions of mobile devices running Android version 2. Please note that iPhones, iPads and newer versions of Android, namely 4.xx display the pages well. The problem is as follows:
When page is called directly from the link:
Home
it is properly displayed.
However, when there is a click handler on a link, like here:
$(document).on('click', '#lstAddrList li', function ()
{
var anchor = $(this).find('a');
sessionStorage.SiteAddr = anchor.attr('id');
changePage();
});
the list line (in this case) stays selected and nothing happens. It is ONLY after the calling page is refreshed directly from the browser when the called page is displayed. I have a feeling that older Androids do not properly handle changePage() method.
Will you have some ideas?
I am using Prototype JavaScript library for creating dynamic drop-down menus. Before the page loads, there is no event attached to the select statements with id, id_bran and id_gen. As can be seen, the init_image is called when the page loads, and the onclick event is attached to those select statement.
This works fine in desktops where I can use a mouse to execute the click event. It however does not work in my Android and iPhone browsers. When the page loads, the init_image is called and the getval function is executed. Later however, when I make a selection in the dropdown menu, the onclick event does not call the getval function. So I am confident that the prototype library is working on my Android and iPhone as the ajax request is made on page load but it fails subsequently. What's going wrong here?
<!--
MY HTML body->onload
The init_image is called the first time when the page is loaded
-->
<body onLoad="init_image();">
//Javscript function called on page load
function init_image() {
getval();
//Assigning the event to id_gen and id_bran for mouse clicks
document.getElementById("id_gen").onclick = getsize;
document.getElementById("id_bran").onclick = getsize;
};
//Javascript function called on page load and during mouse click on the select
//statement with id = id_bran and id_gen
function getval() {
ur = 'szv/c1--'+$F('id_bran')+'/g1--'+$F('id_gen');
new Ajax.Request(ur,
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText;
$('id_val').replace(response);
}
});
};
First of all, you're force-injecting events and the load event which may lead to potential cross-browser issues. If you're using prototype.js, rely on it's native methods which are cross-browser:
<script type="text/javascript">
document.observe("dom:loaded", function() {
.. your code here ..
});
</script>
Then again for properly localizing and observing the click events, instead of:
document.getElementById("id_gen").onclick = getsize;
Use something like:
$('id_gen').on('click', getsize(e).bindAsEventListener(this)); // for prototype 1.7 branch
Or:
$('id_gen').observe('click', getsize(e).bindAsEventListener(this)); // for prototype 1.6 branch
Also by setting passing the e variable there, your getsize() function will have the Event object there, so you could stop it's native behaviour (like leading to #):
function getsize(e) {
e.stop();
.. your code here ..
}
Additionally, it would be best and much less bloated if you lock your whole logic into class and create an object for it... but that's a whole different story... :)
prototype.js is a powerfull tool, but needs some care.
I would suggest you reading some basics on the framework and following the API documentation later on:
http://prototypejs.org/learn/
http://api.prototypejs.org/
I'm building a mobile web app targeting Android users. I need to know what DOM events are available to me. I have been able to make the following work, but not terribly reliably:
click
mouseover
mousedown
mouseup
change
I have not been able to get the following to work:
keypress
keydown
keyup
Does anyone know the full list of what is supported and in what contexts (e.g., is onchange only available to form inputs?)? I can't find a reference for this on The Googles.
Thanks!
Update: I asked the same question on the Android developers list. I will be doing some more testing and will post my results both here and there.
OK, this is interesting. My use case is that I have a series of links (A tags) on a screen in a WebKit view. To test what events area available, using jQuery 1.3.1, I attached every event listed on this page (even ones that don't make sense) to the links then used the up, down, and enter controls on the Android emulator and noted which events fired in which circumstances.
Here is the code I used to attach the events, with results to follow. Note, I'm using "live" event binding because for my application, the A tags are inserted dynamically.
$.each([
'blur',
'change',
'click',
'contextmenu',
'copy',
'cut',
'dblclick',
'error',
'focus',
'keydown',
'keypress',
'keyup',
'mousedown',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
'mousewheel',
'paste',
'reset',
'resize',
'scroll',
'select',
'submit',
// W3C events
'DOMActivate',
'DOMAttrModified',
'DOMCharacterDataModified',
'DOMFocusIn',
'DOMFocusOut',
'DOMMouseScroll',
'DOMNodeInserted',
'DOMNodeRemoved',
'DOMSubtreeModified',
'textInput',
// Microsoft events
'activate',
'beforecopy',
'beforecut',
'beforepaste',
'deactivate',
'focusin',
'focusout',
'hashchange',
'mouseenter',
'mouseleave'
], function () {
$('a').live(this, function (evt) {
alert(evt.type);
});
});
Here's how it shook out:
On first page load with nothing highlighted (no ugly orange selection box around any item), using down button to select the first item, the following events fired (in order): mouseover, mouseenter, mousemove, DOMFocusIn
With an item selected, moving to the next item using the down button, the following events fired (in order): mouseout, mouseover, mousemove, DOMFocusOut, DOMFocusIn
With an item selected, clicking the "enter" button, the following events fired (in order): mousemove, mousedown, DOMFocusOut, mouseup, click, DOMActivate
This strikes me as a bunch of random garbage. And, who's that cheeky IE-only event (mouseenter) making a cameo, then taking the rest of the day off? Oh well, at least now I know what events to watch for.
It would be great if others want to take my test code and do a more thorough run through, perhaps using form elements, images, etc.
Since this is the second most popular Android + JavaScript post on SO (which is just a sad commentary on the state of web development targeting the Android platform), I thought it may be worthwhile including a link to pkk's touch event test results at http://www.quirksmode.org/mobile/tableTouch.html and also http://www.quirksmode.org/mobile/ in general.
As of Android 1.5, the same touch(start|move|end|cancel) events that the iPhone supports work in Android as well.
One problem I found was that touchmove ends get queued up. No workaround yet.