I have a problem where a drop-down select box does not drop-down (it's essentially inactive) when viewed on an Android mobile device. It works fine on desktop browsers as well as ios browser - bringing up a picker wheel on ios and a dropdown select list from the desktop.
Sample code is;
<select id = "log_or_norm" autofocus>
<option value="1">Lognormal</option>
<option value="2">Normal</option>
</select>
I tried the suggestion found at;
http://youngliferamblings.wordpress.com/2011/08/09/select-dropdown-in-android-webview/
which was
The select tag just doesn’t work sometimes in Android, especially in an app using webview. This drove me nuts for a long long time. The main fix I found, even if your select is buried deep in divs and rows and what ever, is this css:
select {
visibility: visible;
-webkit-appearance: menulist-text;
}
The -webkit-appearance might be the only one actually needed and setting it to ‘listbox’ works too.
That’s all. This deserved its own post.
Without luck....
Am hoping that one of the gurus here can provide an elegant solution that will avoid me having to go down the route of making discrete buttons for each option. I'm not fussed as to whether the Android experience gets a nice picker wheel or not, but need to be able to allow Android users to select an option.
Thanking you in advance
Try
getDriver().createElement(By.id("your locator"));
getDriver().createElement(By.id("your locator")).sendKeys("option Name you want to give");
var divCreated = false;
$(document).ready(function () {
var value = "";
$("select").each(function (i) {
$(this).click(function () {
//alert(($(this).is(":focus")));
if (!($(this).is(":focus"))) {
if (!divCreated) {
$("body").append('<div class="for_select"></div>');
divCreated = true;
}
$(this).clone().appendTo(".for_select");
open($(this));
}
});
});
function open(obj) {
var pos = $(obj).offset();
$(".for_select select").css("position", "absolute");
$(".for_select select").css("zIndex", "9999999999999");
var toAdd = $(obj).innerHeight();
$(".for_select select").offset({
top: pos.top + toAdd,
left: pos.left
});
$(".for_select select").attr("size", ($(obj).children("option").length > 10 ? 10 : $(obj).children("option").length));
$(".for_select select").change(function () {
value = $(".for_select select").val();
$(obj).val(value);
$(obj).children("option").each(function () {
if ($(this).text() == value)
$(this).attr("selected", "selected");
else if ($(this).attr("selected")) {
$(this).removeAttr("selected");
}
});
var parentHeight = $(obj).parent().innerHeight();
$(obj).parent().css("height", parentHeight + "px");
$(obj).parent().css("position", "relative");
$(obj).css("position", "absolute");
$(obj).css("left", "0px");
var prevElementsHeight = 0;
var isSelect = false;
$(obj).parent().children("*").each(function () {
if ($(this) == $(obj))
isSelect = true;
if (!isSelect)
prevElementsHeight += $(this).innerHeight();
});
$(obj).css("top", (prevElementsHeight / 2) + "px");
$(obj).css("zIndex", "9999");
close($(".for_select select"));
});
}
function close(obj) {
$(obj).css("position", "static");
$(obj).attr("size", "1");
$(".for_select").empty();
}
});
The solution came rather simple after I battled this for days.
Try debugging by bringing out the select from nested divs until you find the problematic div.
In my case, the problem was that I wrapped all the data-role="page" divs in a parent div (for loading sake on low-end devices). For some reason, < Android 2.3 has a problem with that.
Related
I know Android, and many users, say not to use $event.keyCode || $event.charCode because the returned characters can't be trusted. And its true, it can't. But what about using a regexp to test for the presence of certain characters?
As a case example, US zip codes can be in several formats: 12345, 12345-6789 or 12345 6789. These three formats allow numbers, space and minus sign. But the minus sign could also be the dash sign. So with a physical keyboard you can test for $event.keyCode to match keyCodes [32,109,189] (ie: space, minus, keypad-minus).
But on a softkey board, particularly android soft keyboard, the returned key for almost ALL keys is never correct. On top of which, on android keypress isn't supported, only keydown and keyup - and those present their own challenges. So instead of capturing the keycodes, why not just evaluate the last pressed key and test that character against a regexp?
In my code I have changed things to:
<input id="zip" ng-model="userInfo.zip" ng-keyup="checkKeyCode($event)" ng-blur="setInfo($event,'zip')" >
$scope.checkKeyCode = function() {
var lastChar = $scope.userInfo.zip.slice(-1) ;
var regex1 = /^[\n]*$/ ; // enter key
var regex2 = /^[\d\s-]*$/ ; // numbers, space and minus
if (regex1.test(lastChar)) {
$event.target.blur($event,'zip') ; //force to blur, process data
return ;
}
if (regex2.test(lastChar) == false) {
$scope.errMsg = "Only numbers, space and dash/minus characters are permitted" ;
$scope.errColor = "red" ;
var sLen = $scope.userInfo.zip.length - 1 ;
$scope.userInfo.zip = $scope.userInfo.zip.substring(0,sLen) ; //remove invalid char
return ;
}
if ($scope.userInfo.zip.length > 10) {
$scope.errMsg = "Max length is 10 characters" ;
$scope.errColor = "red" ;
$scope.userInfo.zip = $scope.userInfo.zip.substring(0,10) ;
return ;
}
}
Even though my code works, I have a feeling there are some pitfalls to this method. For example keyCode 109 and 189 are both the minus sign, but does the above regex2 capture both of those or do I need to account a minus sign and a dash - does the regexp treat them differently?
What are the pitfalls and reasons to not do it this way? And last, if this isn't a solid method, then how does one account for keyCodes for Android soft keyboards?
I have a form on my app that I am trying to force a particular format on the text field (ex. dob 11/33/1944). The following code works great on iPhone but on Android the app stops working once I enter the first number. Can someone please help me modify the code so that it works for both iPhone and Android. Thanks for the help.
I have a file called global.js where I have the code that forces the format. This is what I am using:
Mask =
{
mask: function(_field, _function)
{
_field.value = _function(_field.value);
},
dob: function(v)
{
v = v.replace(/\D/g,"");
v = v.replace(/^(\d\d)(\d)/g,"$1/$2");
v = v.replace(/(\d{2})(\d)/,"$1/$2");
return v.slice(0, 10);
},
phone: function(v)
{
v = v.replace(/\D/g,"");
v = v.replace(/^(\d\d)(\d)/g,"($1) $2");
v = v.replace(/(\d{4})(\d)/,"$1-$2");
return v.slice(0, 14);
}
};
On my form i added the following on the top of the of the view for the global.js:
var styles = require('global').Styles;
Then my field is as follows:
// Create a TextField.
var aTextField_dob = Ti.UI.createTextField(
{
top : "10%",
width : '80%',
height:'8%',
color: styles.textfield.color,
font :
{
fontSize : font_text
},
hintText : 'Date of Birth (Ex.01/01/1999)',
paddingLeft : styles.textfield.paddingLeft,
backgroundImage : styles.textfielda.backgroundImage,
});
// Listen for return events.
aTextField_dob.addEventListener('change', function(e)
{
Mask.mask(aTextField_dob, Mask.dob);
});
Here is the issue I get on the Android device, it just keeps repeating itself and the app has to be forced to stop:
[WARN] : IInputConnectionWrapper: getCursorCapsMode on inactive InputConnection
First of all, I’d avoid the issue altogether by using a date picker control. That’d be a better UI/UX anyway.
It’s probable that you are creating infinite recursion in the change event. That could be avoided by using the blur (lost focus) event, or the keypressed event if it can’t wait until focus is lost.
I’m not sure if the regular expression engines are different. Try putting the regex output into another control or just log it – separate it from any possible change event infinite loop to test that out.
I am making an iOS and Android app using Titanium Classic. I am fairly new to Titanium but I have some experience using Javascript. The app will have a window where the user and select from a picker an amount of time in hours and minutes. The selection will be saved and be used later to send a notification to the user that the time they selected is up. I am currently using Titanium's picker function with the type of "count down timer." However, I am having trouble getting the change event to work when the user selects a different time. It also will show the last selected time when I try going to a different window and entering the timer window again.
My question is how can I get the change event to fire the first time the user selects a different number?
In follow up to my question, is there a better way to save the picker selection for later use?
Here is the code for the picker:
var hours = 0;
var minutes = 1;
var win = Ti.UI.createWindow({
backgroundColor: '#A6B97B',
layout: 'horizontal'
});
var picker = Ti.UI.createPicker({
type:Ti.UI.PICKER_TYPE_COUNT_DOWN_TIMER,
top:2,
width: '50%',
height: '20%'
});
picker.addEventListener("change", function(e) {
Ti.App.Properties.setInt('countDownDuration', e.countDownDuration);
if (e.countDownDuration >= 3600000)
{
hours = Math.floor(Ti.App.Properties.getInt('countDownDuration')/3600000);
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000 - (hours*60));
}
else {
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000);
hours = 0;
}
});
var doneBtn = Ti.UI.createButton({
title : 'Get Value',
height : '15%',
width : '30%'
});
doneBtn.addEventListener('click', function() {
// get value
if(hours > 0){
alert('You set the time estimate to ' + hours + ' hours and ' + minutes+ ' minutes');
}
else {
alert('You set the time estimate to ' + minutes + ' minutes');
}
});
If anyone has any advice on how to get the change event to fire the first time, I would really appreciate it. Also, if you know a better way to accomplish saving data from the picker for use later, that would be helpful as well.
Thanks!
Jessica
New to Starling-Feathers, before I start to develop my mobile app, I would like to know what are the best practice to develop the following features using Feathers:
Partial view slide - A part of the next view is shown and the user can drag to see it all. Could this be done with Feathers ScreenNavigator?
Sliding menu from the top
Dragging text elements with title pushing the last items
Since it is hard to describe I've added an animated gif to describe my goals. Thanks for all your advices
I would like to maximize the use of Feathers built in widgets and will appreciate code examples :)
I think these are not that much hard to do in core flash or you can also do it in Starling feathers too. YOu can use list item to do the third point (Dragging text elements with title pushing the last items) .
First and second you can use it with tweening effect i think.
For the third one using feathers list.
(re formated post)
private function addFeatherList():void{
Flist = new List();
Flist.width = 250;
Flist.height = 300;
Flist.x = GAME_W/2 - Flist.width/2;
Flist.y = sampText.height + 5;
this.addChild( Flist );
fontArr = Font.enumerateFonts(true);
for (var i:int=0; i<fontArr.length; i++){
ListArr[i] = { text:Font(fontArr[i]).fontName }
}
var groceryList:ListCollection = new ListCollection( ListArr );
Flist.dataProvider = groceryList;
Flist.itemRendererProperties.labelField = "text";
FeathersControl.defaultTextRendererFactory=function():ITextRenderer{
var render:TextFieldTextRenderer=new TextFieldTextRenderer();
render.textFormat = new TextFormat("Verdana",8,0xFFFFFF,false);
return render;
}
Flist.itemRendererFactory = function():IListItemRenderer //list.itemRendererProperties.accessorySourceField list.itemRendererFactory
{
var renderer:DefaultListItemRenderer = new DefaultListItemRenderer();
renderer.addEventListener(Event.TRIGGERED, onListTriggered);
return renderer;
}
}
I am creating an appliction which uses Google Books API. So whenever I search a book it gives a JSON response and I load those results in my table view. There will be thousands of books results when I search. But I don't want to load everything in my tableview. Whenever I scroll down it only has to load next books.
Can anyone give me a code or rough idea on how to do this in Android using Titanium? I have checked this post: https://github.com/appcelerator/KitchenSink/blob/master/Resources/examples/table_view_dynamic_scroll.js But this is for iPhone, I need it for Android as well. Help me out...
After looking around I have implemented following solution for android:
tableView.addEventListener('scroll',
function(e) {
if (!e.source.__doneUpdating && e.totalItemCount % e.source.__pageSize === 0) {
var distance = e.totalItemCount - e.firstVisibleItem;
if (distance <= e.visibleItemCount) {
if (!e.source.__updating) {
e.source.__updating = true;
e.source.fireEvent('beginUpdate', e);
}
}
}
Ti.API.info('-------------------');
Ti.API.info( 'e.firstVisibleItem: ' + e.firstVisibleItem);
Ti.API.info( 'e.totalItemCount: ' + e.totalItemCount);
Ti.API.info( 'e.visibleItemCount: '+ e.visibleItemCount);
}
);
Where e.source.__pageSize, e.source.__doneUpdating, and e.source.__updating are internal variables that are maintained by the code inserting rows into the tableView.