I have a problem in android phonegap mobile website application, I applied scroll bar in my application, it is working good in PC but when i test in android device(mobile phone) scroll bar not enable.
personally I don't like iscroll.. had many problems using it so I discovered another solution... you can try this:
1.) set your DIV overflow to auto (or scroll) and set its height.. e.g.
<div id="wrapper" style="overflow:auto; height: 200px">...content...</div>
(I usually calculate height with javascript based on user's screen size.. I never set just a fixed height for all devices, this is just for the purpose of this "demo")
2.) add this javascript:
<script>
function isTouchDevice(){
try{
document.createEvent("TouchEvent");
return true;
}catch(e){
return false;
}
}
function touchScroll(id){
if(isTouchDevice()){ //if touch events exist...
var el=document.getElementById(id);
var scrollStartPos=0;
document.getElementById(id).addEventListener("touchstart", function(event) {
scrollStartPos=this.scrollTop+event.touches[0].pageY;
event.preventDefault();
},false);
document.getElementById(id).addEventListener("touchmove", function(event) {
this.scrollTop=scrollStartPos-event.touches[0].pageY;
event.preventDefault();
},false);
}
}
</script>
3.) call it on page load.. if you use jQuery:
$(document).ready(function() {
touchScroll("wrapper");
});
4.) if you want your scrollbars to be visible, just define following CSS rules:
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #000;
}
Use this PhoneGap link
http://phonegap.pbworks.com/w/page/22863184/Hide%20the%20scrollbar%20in%20Android
this works in Android ,PhoneGap Applications for vertical and Horizontal Scroll
Code look Like this
public class MyActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
// Display vertical scrollbar and hide horizontal scrollBar
super.appView.setVerticalScrollBarEnabled(true);
super.appView.setHorizontalScrollBarEnabled(false);
// set scrollbar style
super.appView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
}
}
Related
On long press gesture the context action menu appears along the selected text.
But not getting hide unless I select an option from the menu.
First to enable context action menu, I used this:
overflow-scroll = "true" in the ion-content.
In the CSS class, I wrote:
-webkit-user-select: auto;
But now I can't hide it. It is locked on my view. Even after touching anywhere in my web view, it is still enabled. To hide context menu I used this:
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout:none;
But still not getting success. This particular issue is in android only. For iOS, it is working fine. Any help would be appreciated.
Ionic version - 2.1.0
Update
Finally I found the answer.
I used the following two methods. First method to select text on long press and second method to remove selection.
/*----------- To get selection--------*/
$scope.getSelectionText = function() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
$scope.selectMode = true;
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
$scope.selectMode = true;
}
return text;
};
/*---------------To remove selection----------*/
$scope.remove = function(){
if (window.getSelection) {
if (window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
} else if (document.selection) { // IE?
document.selection.empty();
}
};
And add ng-click to your div
<div class="selectable" ng-click="remove()">
<ng-include src="activeTab.url"></ng-include>
</div>
Finally I found the answer.
I used the following two methods. First method to select text on long press and second method to remove selection.
/*----------- To get selection--------*/
$scope.getSelectionText = function() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
$scope.selectMode = true;
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
$scope.selectMode = true;
}
return text;
};
/*---------------To remove selection----------*/
$scope.remove = function(){
if (window.getSelection) {
if (window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
} else if (document.selection) { // IE?
document.selection.empty();
}
};
And add ng-click to your div
<div class="selectable" ng-click="remove()">
<ng-include src="activeTab.url"></ng-include>
</div>
Lets say there is a login page with username\password TextFields and login Button. When the button is pressed a request is set to a server and ActivityIndicator is shown.
Currently I put StackLayout on top of all other controls not to give the user a possibility to click on them while processing the request. But in some cases TextField stays focused and the user can type there.
I'm already using a component to wrap all TextFields to show validation errors:
#Component({
selector: "field",
template: "<grid-layout><ng-content></ng-content>...</grid-layout>"
})
export class FieldComponent {
#ContentChild(NgModel) private input: NgModel;
...
}
My question is can I set isEnabled property to false on TextField inside ng-content from FieldComponent having NgModel or in some another way?
If it is impossible what is the best practices in this case to disable inputs when an app is busy?
Here is my solution for NativeScript+Angular:
setControlInteractionState() is recursive.
the TextField cursor is hidden (using native android API).
XML:
<GridLayout #mainGrid rows="*" columns="*">
<!-- Main page content here... -->
<GridLayout *ngIf="isBusy" rows="*" columns="*">
<GridLayout rows="*" columns="*" style="background-color: black; opacity: 0.35">
</GridLayout>
<ActivityIndicator width="60" height="60" busy="true">
</ActivityIndicator>
</GridLayout>
</GridLayout>
or
<GridLayout #mainGrid rows="*" columns="*">
<!-- Main page content here... -->
</GridLayout>
<GridLayout *ngIf="isBusy" rows="*" columns="*">
<GridLayout rows="*" columns="*" style="background-color: black; opacity: 0.35">
</GridLayout>
<ActivityIndicator width="60" height="60" busy="true">
</ActivityIndicator>
</GridLayout>
TypeScript:
import { Component, ViewChild, ElementRef } from "#angular/core";
import { View } from "ui/core/view";
import { LayoutBase } from "ui/layouts/layout-base";
import { isAndroid, isIOS } from "platform";
#Component({
templateUrl: "./SignIn.html"
})
export class SignInComponent {
#ViewChild("mainGrid")
MainGrid: ElementRef;
isBusy: boolean = false;
submit() : void {
try {
this.isBusy = true;
setControlInteractionState(<View>this.MainGrid.nativeElement, false);
//sign-in here...
}
finally {
this.isBusy = false;
setControlInteractionState(<View>this.MainGrid.nativeElement, true);
}
}
setControlInteractionState(view: View, isEnabled: boolean) : void {
view.isUserInteractionEnabled = isEnabled;
if (isAndroid) {
if (view.android instanceof android.widget.EditText) {
let control = <android.widget.EditText>view.android;
control.setCursorVisible(isEnabled);
}
}
if (view instanceof LayoutBase) {
let layoutBase = <LayoutBase>view;
for (let i = 0, length = layoutBase.getChildrenCount(); i < length; i++) {
let child = layoutBase.getChildAt(i);
setControlInteractionState(child, isEnabled);
}
}
}
}
NS 2.5.0
There are a couple way you can do this;
You can use a ngIf or binding on isEnabled to disable it based on a data bound value.
You can create a simple routine that you call (my preferred method).
require("nativescript-dom");
function screenEnabled(isEnabled) {
runAgainstTagNames('TextEdit', function(e) { e.isEnabled = isEnabled; });
runAgainstTagNames('Button', function(e) { e.isEnabled = isEnabled; });
}
The nativescript-dom plugin has the runAgainst*, or getElementBy* wrappers to talk to the native layer like you were talking to a html dom.
Full disclosure, I'm the author of nativescript-dom, it is one of the plugins that I use in almost every app/demo I do.
I found an easiest solution in Angular, so i am posting here for any future reference. First in app.component.html file i added a Grid and ScrollView like following:
<GridLayout>
<page-router-outlet></page-router-outlet>
<!-- hack to block UI -->
<ScrollView isUserInteractionEnabled="false" *ngIf="isLoading">
<ActivityIndicator busy="true"></ActivityIndicator>
</ScrollView>
</GridLayout>
Notice the page-router-outlet which is inside the Grid. By default it will be place at row="0". The next thing is ScrollView which has isUserInteractionEnabled set to false.
Now in your app.component.ts file add a a variable called isLoading and toggle it using some kind of events e.g RxJs Observable events
Expanding #KTCO's answer to get the size of the overlay exactly the same as the main grid:
import { Size, View } from "tns-core-modules/ui/core/view";
import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout/grid-layout";
...
...
dialogSize: Size;
mainGrid: GridLayout;
...
submit() {
this.mainGrid = <GridLayout>this.MainGrid.nativeElement;
this.dialogSize = this.mainGrid.getActualSize();
.....
.....
<GridLayout *ngIf="isBusy" rows="auto" columns="auto">
<GridLayout rows="*" columns="*" [width]="dialogSize.width" [height]="dialogSize.height" style="background-color: black; opacity: 0.35">
</GridLayout>
<ActivityIndicator width="50" height="50" busy="true">
</ActivityIndicator>
</GridLayout>
I know this is a little old, but sometimes I just got to do things my way. If you want to accomplish this programmatically:
const excludedView = someViewToBeExcluded;
const enabler = (parentView:View, enable:boolean) => {
parentView.eachChildView(childView => {
if (childView != excludedView) {
enabler(childView, enable);
childView.isEnabled = enable;
}
return true;
});
};
enabler(page, false);
Note: This will not disable/enable the initial parentView (ie. the page in this example)
On android triggered event window resize when you click on the input text or search. From there it take if resizing the window does not occur. I shoveled a lot of sources, how to fix I do not know.
Accordingly, I have written that when the browser is resized remove attributes eventually INPUT text disappears
https://youtu.be/2pAL221qgwc
https://youtu.be/W4M4c4UzMfc
$(function() {
$('nav>#main-menu').click(function() {
if($(this).hasClass('active')) {
$('.nav-menu ul ').slideUp();
$(this).removeClass('active');
}
else {
$(this).addClass('active');
$('.nav-menu ul' ).slideDown();
}
});
//search-toggle
$('.icon-b').click(function() {
//$( "#search-bl" ).slideToggle( "500");
$( "#search-bl" ).toggle( "slide",{ direction: "right" });
});
$(window).resize(function() {
$('.nav-menu ul').removeAttr('style');
$('#search-bl').removeAttr('style');
$('nav>#main-menu').removeClass('active');
});
});
I forgot to add.
Hi I have developed android phonegap app which is responsive.So when keyboard is visible i need to hide the footer in portrait and landscape mode and keyboard is not visible i need to show the footer in both the mode.I have tried the sample but its not working fine.If i open the app in portrait mode i cant able to find the footer in landscape mode when keyboard is not visible.
Here is my sample code:
var is_keyboard = false;
var is_landscape = false;
var initial_screen_size = window.innerHeight;
/* Android */
window.addEventListener("resize", function() {
is_keyboard = (window.innerHeight < initial_screen_size);
is_landscape = (screen.height < screen.width);
if (is_keyboard)
{
$("#footer1").hide();
}
else
{
$("#footer1").show();
}
}, false);
Please guide me.Thanks in Advance.
I think your best bet is to register for the show and hide keyboard events.
document.addEventListener("showkeyboard", function() {
$("#footer1").hide();
}, false);
document.addEventListener("hidekeyboard", function() {
$("#footer1").show();
}, false);
I have designed an app using Phonegap and jQuery Mobile. The fixed footer works properly until I click on a dropdown or text field, which causes the footer to either disappear from view (Android 4.0) or move to the middle of the view (Android 2.2 Galaxy Tab). Any suggestions?
Phonegap Version: Cordova 2.1.0
jQuery Mobile Version: 1.2.0
Here is my code:
<div data-role="footer" class="nav-mobilyzer" data-tap-toggle="false" data-position="fixed">
<div data-role="navbar" class="nav-mobilyzer" data-grid="d">
<h1>footer</h1>
</div>
</div>
I had the problem in some devices the footer displayed and in others it didn't. I found this worked for me:
var initialScreenSize = window.innerHeight;
window.addEventListener("resize", function() {
if(window.innerHeight < initialScreenSize){
$("[data-role=footer]").hide();
}
else{
$("[data-role=footer]").show();
}
});
EDIT:
But what about orientation changes?
var portraitScreenHeight;
var landscapeScreenHeight;
if(window.orientation === 0 || window.orientation === 180){
portraitScreenHeight = $(window).height();
landscapeScreenHeight = $(window).width();
}
else{
portraitScreenHeight = $(window).width();
landscapeScreenHeight = $(window).height();
}
var tolerance = 25;
$(window).bind('resize', function(){
if((window.orientation === 0 || window.orientation === 180) &&
((window.innerHeight + tolerance) < portraitScreenHeight)){
// keyboard visible in portrait
}
else if((window.innerHeight + tolerance) < landscapeScreenHeight){
// keyboard visible in landscape
}
else{
// keyboard NOT visible
}
});
The tolerance accounts for the inexact calculation of landscape height with portrait width and vis-versa.
Okay, this thread is as old as the internet at this point, but the answer above didn't seem to do the job for me.
The best way I found was to bind a method to the jquery .blur() event, and then call fixedtoolbar() methods in a very specific order, i.e.
var that = this;
$(':input').blur(function(){
that.onFocusLoss();
});
......
onFocusLoss : function() {
try {
$("[data-position='fixed']").fixedtoolbar();
$("[data-position='fixed']").fixedtoolbar('destroy');
$("[data-position='fixed']").fixedtoolbar();
console.log('bam');
} catch(e) {
console.log(e);
}
},
The keyboard is opened when we have the focus on an input so:
// hide the footer when input is active
$("input").blur(function() {
$("[data-role=footer]").show();
});
$("input").focus(function() {
$("[data-role=footer]").hide();
});
You can also detect when the keyboard shows and when it hides and show or hide your footer accordingly:
document.addEventListener("showkeyboard", function(){ $("[data-role=footer]").hide();}, false);
document.addEventListener("hidekeyboard", function(){ $("[data-role=footer]").show();}, false);
Try data-hide-during-focus="" and set it to an empty string.
My solution uses another JQUERY attribute on the div footer. Adding data-fullscreen="true" to that div was all I needed. I know that this fix might not have been available until recently, but I am using jqm 1.3.2 and jq 1.9. I thought I would post this solution just in case it helps someone. Good luck. :)