This is a simple Cordova & jQuery mobile (1.4.5) app...
When I click on an item in a listview I want to dinamically build a listview on another page and navigate there.
The code I have works as desired as long as I don't click items/buttons too quickly. If I navigate between pages back and forth quickly then sooner or later I end up with an empty page, with the wrong text in header.
This happens both in Ripple and in actual Android device. Why? how can I avoid this? I think it is related to clicking items during page transition but I don't know.
HTML:
<div data-role="page" id="home">
Exercises
</div>
<div data-role="page" id="categories">
<div data-role="header" data-position="fixed" data-add-back-btn="true" data-back-btn-text="Go back">
<h1>Categories</h1>
</div>
<ul data-role="listview" id="categoryList"></ul>
</div>
<div data-role="page" id="exercises">
<div data-role="header" data-position="fixed" data-add-back-btn="true" data-back-btn-text="Go back">
<h1 id="category"></h1>
</div>
<ul data-role="listview" id="exerciseList"></ul>
</div>
Javascript:
var lastCategoryID;
$(document).on("pagecontainerbeforechange", function (e, data) {
switch (data.toPage[0].id) {
case "categories":
createCategories();
break;
case "exercises":
createExercises(event.target.id, $(event.target).text());
break;
}
});
function createExercises(categoryID, categoryName) {
//Don't rebuild if is same category of last time.
if (lastCategoryID == categoryID) return; else { lastCategoryID = categoryID; }
//Set header text.
$("#category").text(categoryName);
$("#exerciseList").empty();
switch (categoryID){
case "c0":
$("#exerciseList").append('<li>Warming up</li>');
$("#exerciseList").append('<li>Weight lifting</li>');
break;
case "c1":
$("#exerciseList").append('<li>Warming up</li>');
$("#exerciseList").append('<li>Running</li>');
break;
}
$("#exerciseList").listview("refresh");
}
function createCategories() {
$("#categoryList").empty();
$("#categoryList").append('<li>Arms</li>');
$("#categoryList").append('<li>Legs</li>');
$("#categoryList").listview("refresh");
}
Steps to reproduce (it doesn't always happen):
1- Click on "Arms"
2- Quickly click on back button
3- Quickly click on "Arms" again
Instead of getting this:
you get this:
I was able to solve the problem mainly by changing
$(document).on("pagecontainerbeforechange", function (e, data) {
to
$(document).on('vclick', 'a', function () {
Related
I am using below lines of code to show html pages on my application but my app is too slow when scrolling.
Can I use another method to show the text? Can it be by html page or another method? or use listview to show my text?
or is it necessary to create layout for every text page?
Thanks.
ck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/ck.html");
((Button)findViewById(R.id.cb)).setVisibility(View.GONE);((Button)findViewById(R.id.geri)).setVisibility(View.VISIBLE); ((Button)findViewById(R.id.db)).setVisibility(View.GONE); ((Button)findViewById(R.id.bb)).setVisibility(View.GONE); ((Button)findViewById(R.id.ck)).setVisibility(View.GONE);
}
});
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
You Can Use This Library :-
https://github.com/PrivacyApps/html-textview
HtmlTextView is an extended TextView component for Android, which can load HTML and converts it into Spannable for displaying it. It is a replacement for usage of the WebView component, which behaves strange on some Android versions, flickers while loading, etc.
My issue solved using below code you can try this one:
// get our html content
String htmlAsString = getString(R.string.html);
Spanned htmlAsSpanned = Html.fromHtml(htmlAsString); // used by TextView
// set the html content on the TextView
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(htmlAsSpanned);
<resources>
<string name="html">
<![CDATA[
<h1>Main Title</h1>
<h2>A sub-title</h2>
<p>This is some html. Look, here\'s an <u>underline</u>.</p>
<p>Look, this is <em>emphasized.</em> And here\'s some <b>bold</b>.</p>
<p>This is a UL list:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<p>This is an OL list:
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol>
</string>
</resources>
Hope this will help you if not than inform me
I'm trying to dynamically change the html content of a dialog of onse.ui, but it is not working for me, my code is as below:
Here my html code.
<ons-template id="popupFechaCalendario.html">
<ons-dialog style="height: 300px;" var="naviDialog" cancelable>
<ons-navigator var="myNav">
<ons-toolbar inline>
<div class="center contenedorPopup" id="popupFechaCalendario_fecha">html content</div>
</ons-toolbar>
</ons-navigator>
</ons-dialog>
</ons-template>
And here my Javascript code.
$("#popupFechaCalendario_fecha").html("some html...");
ons.createDialog('popupFechaCalendario.html').then(function(dialog) {
dialog.show();
});
I have also tried like,
ons.createDialog('popupFechaCalendario.html').then(function(dialog) {
dialog.on("preshow", function(e) {
$("#popupFechaCalendario_fecha").html("some html...");
});
dialog.show();
});
In advance thank you very much to anyone who can help me
I want to load a website in an android webview and programtically click on an anchor in its code.
the anchor is in a div feild :
<div id="_item_row_677305">
<span id="parent-row-song677305" class="parentnode sourcelist_1" style="display:none;"> … </span>
<ul id="trackrow677305" class="playlist clearfix ">
<li class="playcol" data-value="677305">
<div>
<a class="songlist play_pause playicon677305 " title="Play" href="javascript:void(0)" data-value="song677305" data-type="playSong"></a>
</div>
</li>
<li class="songcol"> … </li>
<li class="artistcol"> … </li>
<li class="popularitycol popular"> … </li>
<li class="eventcol"> … </li>
</ul>
</div>
I cant figure out how to do this. Please help !
I'm assuming that you know which function this anchor will call. So you can simply use a WeViewClient to do this stuff.
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:here is the function's name you need to invoke");
}
}
And after this, just set your webview's webclient.
I am trying to understand the execution flow of angularjs/phonegap. I have 2 views: one is list view another is detail view. When the app is started the first time, the list view is shown first, user then selects which list item and show detail view which is recorded in localStorage. When the app is started next time, it should show the detail view directly without showing list view first. I use the following code and is working except when the app is started next time, the list view is shown first then quickly detail view is shown.
index.html:
<!-- Libs -->
<script type="text/javascript" src="phonegap.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="lib/underscore-min.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<!-- App -->
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/routers.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/services.js"></script>
<script type="text/javascript">
app.initialize();
</script>
index.js:
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
//handle backbutton to exit app when on homepage
document.addEventListener('backbutton', function(e){
if(window.location.hash == '#/users' || window.location.hash == '#' || window.location.hash == ''){
e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
onDeviceReady: function() {
//app.startPage(); //listview then detailview
angular.element(document).ready(function() {
//app.startPage(); //listview only
angular.module('userdemo', []);
//app.startPage(); //listview only
angular.bootstrap(document, ['userdemo']);
//app.startPage(); //listview only
});
app.startPage(); //listview then detailview. if remove "route otherwise clause", show blank listview then detail template view, backbutton working
},
// decide which page to start with
startPage: function() {
var userId = window.localStorage.getItem("userId");
if(!userId) window.location.hash = '/users';
else window.location.hash = '/users/' + userId;
}
};
routers.js:
angular.module('userdemo', ['userdemoFilters', 'userdemoServices']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/users',{
templateUrl: 'partials/user-grid.html',
controller: UserGridCtrl
}).
when('/users/:userId', {
templateUrl: 'partials/user-detail.html',
controller: UserDetailCtrl
}).
otherwise({redirectTo: //if removed, it shows black screen. backbutton working
'/users' //normal
//'/users/3' //show detail template only. backbutton not working
/*
function(routeParams, path, search) { //show detail template only. backbutton not working
var userId = window.localStorage.getItem("userId");
if(!userId) return '/users';
else return '/users/' + userId;
}*/
});
}])
.run(function($location) { //listview then detailview. if remove "otherwise" clause, blank screen, backbutton not working
//var userId = window.localStorage.getItem("userId");
//if(!userId) $location.hash('/users');
//else $location.hash('/users/' + userId);
});
UserDetailControl():
function UserDetailCtrl($rootScope, $scope, $routeParams, User) {
//handle the case when the app is started from the last saved userId
if(!$rootScope.users)
$scope.users = User.query(function() {
for (var i=0; i<$scope.users.length; i++) {
var user = $scope.users[i];
if(!user.id) user.id = i;
}
$rootScope.users = $scope.users;
});
else
$scope.users = $rootScope.users;
$scope.user = $rootScope.users[$routeParams.userId];
}
user-detail.html:
<div class="container-fluid">
<div class="row-fluid">
<div>
<b>Hello {{user.name}}</b><br>
</div>
</div>
</div>
I tried other possible alternatives:
remove "route otherwise clause". It shows blank listview then detail template view without scope applied(that is, literally, Hello {{user.name}}).
put app.startPage() in different places. around, inside, before, after document.ready or angular.bootstrap call. If around document.ready, it shows listview then detailview. If inside document.ready, it shows listview only.
write a custom "route otherwise redirectTo" function as shown in commented code. The result shows detail template only without scope applied. Also backbutton not working.
put initialization code inside module.run() as shown in commented code. It shows listview then detailview. If remove "otherwise" clause, blank screen, backbutton not working.
Not change others, just replace "route otherwise redirectTo" from "/users" to "/users/3", it shows detail template view only. backbutton not working.
None of them shows what I want. Can someone expert on Angular/Phonegap explain why these happen to better understand mechanism behind? What is the right solution for showing the detail view only for app's next start?
You may set the angular routs dynamically after loading phonegap and checking the local-storage, and before manually bootstraping angular..
otherwise({redirectTo:SOME_DYNAMIC_VALUE})
What happens when selected index is updated($('#idSelectControl').prop('selectedIndex', self.lastSelected);). Immediately the radio button is not getting refreshed, I need to close the select drop down when I reopen the control, it's showing the updated radio button checked with the current selected index.
Please find the code below.
HTML
<div id="idSelectCustomControl" data-bind="visible : searchVisibleFlag">
<select id="idSelectControl" class="float-left big-select" data-native-menu="true" data-corners="false" data-icon="search" data-iconpos="left" data-mini="true" data-bind="dataOptions: arrayList, optionsText : 'text', optionsValue : 'id'">
</select>
</div>
JS
// fired when user selects on drop down list
$(#idSelectControl).live("change", function (event) {
var selectedItem = $("#idSelectControl option:selected").val();
console.log("merchant subscription" + self.merchant());
self.lastSelected = $('#idSelectControl').prop('selectedIndex');
$('#idSelectControl').prop('selectedIndex', self.lastSelected);
//$("select").selectmenu("refresh");
var myselect = $("#idSelectControl");
myselect[0].selectedIndex =0;
myselect.selectmenu("refresh",true);
$('select').selectmenu('refresh', true);
$("select").selectmenu("close");
//$("#idSelectControl").val(selectedItem ).selectmenu("refresh");
if (selectedItem ) {
self.item((selectedItem);
}
else {
self.item("");
}
});
I have tried below also:
$("input[type='radio']").prop("checked",true).checkboxradio("refresh");
$('input[value='+$(this).find("HomeStatus").text()+']')
.attr('checked',true).checkboxradio('refresh');