jQuery Mobile swipe navigation exception - jquery-mobile

I have a series of pages inside one document, I navigate from page to page making use of swipe in touch devices.
What I dont know how to do, is to stop the swipe event once I reach certain page id.
This is the code I am using form my navigation:
$('div.ui-page').live("swipeleft", function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.changePage(nextpage, "slide", false, true);
}
});
$('div.ui-page').live("swiperight", function(){
var prevpage = $(this).prev('div[data-role="page"]');
if (prevpage.length > 0) {
$.mobile.changePage(prevpage, {transition: "slide",
reverse: true}, true, true);
}
});
I am using JQM 1.3
Thank you for your help

Here's a working example: http://jsfiddle.net/Gajotres/GXex5/
$(document).off('swipeleft').on('swipeleft', '[data-role="page"]', function(event){
if($(this).attr('id') == 'article2') {
event.preventDefault();
return false;
}
var nextpage = $.mobile.activePage.next('[data-role="page"]');
// swipe using id of next page if exists
if (nextpage.length > 0) {
$.mobile.changePage(nextpage, {transition: "slide", reverse: false}, true, true);
}
event.handled = true;
});
$(document).off('swiperight').on('swiperight', '[data-role="page"]', function(event){
var prevpage = $(this).prev('[data-role="page"]');
if (prevpage.length > 0) {
$.mobile.changePage(prevpage, {transition: "slide", reverse: true}, true, true);
}
event.handled = true;
});
Basically all you need is this code:
if($(this).attr('id') == 'article2') {
event.preventDefault();
return false;
}
This code will check if some page has a certain name and if it is so it will prevent default action (event). Also dont forget to pass a event object in your code, so
change this:
$('div.ui-page').live("swiperight", function(){
to this:
$('div.ui-page').live("swiperight", function(event){

Use the below to define next and previous page ID, if it equals to the page you don't want to show, do nothing.
var DoNothing = 'DoNothing';
// fetch ID of next page in DOM
var nextpage = $.mobile.activePage.next('[data-role=page]')[0].id;
// fetch ID of previous page in DOM
var prevpage = $.mobile.activePage.prev('[data-role=page]')[0].id;
// logic
if(nextpage == DoNothing || prevpage == DoNothing) {
// Do nothing!
}

Related

jQuery-Mobile: Page does not load completely when swiped to

Today I prepared some PHP pages with jQuery-Mobile. It should enable for swiping from one page to another.
In general the swiping works but there is one problem: When I've swiped to a new page swiping doesn't work on that page first. Only when I reload the page it works again. The page source before reloading is OK.
It seems to me that not all inclusions are executed when I have swiped to a new page. How can this be fixed? E.g.: Ref link
$(document).ready(function () {
var urlup, urlleft, urlright;
$('img').on('dragstart', function (event) {
event.preventDefault();
});
$('img').each(function (i) {
if (this.src.indexOf("buttonup.png") >= 0) {
urlup = this.parentNode.href;
this.id = "buttonup";
} else if (this.src.indexOf("buttonleft.png") >= 0) {
urlleft = this.parentNode.href;
this.id = "buttonleft"
} else if (this.src.indexOf("buttonright.png") >= 0) {
urlright = this.parentNode.href;
this.id = "buttonright";
} else {};
});
//$.mobile.loadPage(urlup);
//$.mobile.loadPage(urlleft);
//$.mobile.loadPage(urlright);
$(":mobile-pagecontainer").pagecontainer("load", urlup);
$(":mobile-pagecontainer").pagecontainer("load", urlleft);
$(":mobile-pagecontainer").pagecontainer("load", urlright);
$(document).on("swipeup", function () {
$.mobile.changePage(urlup);
});
$(document).on("swipeleft", function () {
$.mobile.changePage(urlright);
});
$(document).on("swiperight", function () {
$.mobile.changePage(urlleft, {
reverse: true
});
});
$("#buttonup").click(function () {
$.mobile.changePage(urlup, {
transition: "slideup"
});
});
$("#buttonleft").click(function (event) {
event.stopPropagation();
});
$("#buttonleft").click(function () {
$.mobile.changePage(urlleft, {
reverse: true
});
});
$("#buttonright").click(function () {
$.mobile.changePage(urlright);
});
});
In the meantime I was able to fix this problem: I used the document-ready-event and this one is not fired when jQuery Mobile loads a new page. Thus the javascript code that binds the swiping events was not executed. I had to use JMs pageinit event instead. After fixing some other problems swiping works fine on my pages now:
http://www.ulrichbangert.de/orchid/odm_rawdonjester.php
Best regards - Ulrich

JQueryMobile: pagecontainershow on a particular page not working

JQueryMobile 1.4 has deprecated the pageshow event and instead recommends using pagecontainershow; however, while I'm able to get the pagecontainershow event at a document level, I can't bind a function to a particular page.
<div id="page1" data-role="page">
...
<script>
$( "#page1" ).on( "pagecontainershow", function( event, ui ) {
console.log("page1 pagecontainershow");
} );
</script>
</div>
Demonstration: http://jsbin.com/IFolanOW/22/edit?html,console,output
I also considered using the alternative form of the jQuery "on" function where we use a selector, but that would need to be a parent of the page div, and that might include other pages, so that doesn't work.
As a workaround, I've done this, but it is very inefficient:
function registerOnPageShow(pageId, func) {
var strippedPageId = pageId.replace("#", "");
var e = "pagecontainershow." + strippedPageId;
// TODO why isn't it working to use $(pageId) instead of $(document)?
$( document ).off(e).on(e, null, {page: strippedPageId, f: func}, function(e, ui) {
if ($(":mobile-pagecontainer").pagecontainer("getActivePage")[0].id == e.data.page) {
e.data.f(e, ui);
}
});
}
You can get the page ID like this.
$(document).on('pagecontainershow', function(e, ui) {
var pageId = $('body').pagecontainer('getActivePage').prop('id');
});
There is currently no way to have a show/hide event on a specific page.
Here is what I'm using (jqmobile >1.4):
$(document).on("pagecontainershow", function () {
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
var activePageId = activePage[0].id;
switch (activePageId) {
case 'loginPage':
...
break;
case 'homePage':
...
break;
case 'groupPage':
...
break;
default:
}
});
$(document).on("pagecontainershow", function(event, ui) {
var pageId = $('body').pagecontainer('getActivePage').prop('id'),
showFunc = pageId+'_show';
if (typeof MobileSite[showFunc] == 'function') {
MobileSite[showFunc]();
}
});
MobileSite is contained in an external .js file with all the show() functions.
$(document).on("pagecontainerbeforeshow", function (event, ui) {
if (typeof ui.toPage == "object") {
var crrentPage = ui.toPage.attr("id")
}
});
and you must use this code before calling Index.js !!

changing a page in jqm after a fetch - view not displaying backbone

I am trying to change a page and display a view with JQM and backbone.
My home page loads ok but when I try and go to the second page - this is when I have a few questions. the page loads but nothing is showing
so my app has a router
var AppRouter = Backbone.Router.extend({
//define routes and mapping route to the function
routes: {
'': 'showHome', //home view
'home': 'showHome', //home view as well
'products/productList' : 'showProducts',
},
initialize:function () {
// Handle back button throughout the application
$('.back').live('click', function(event) {
window.history.back();
return false;
});
this.firstPage = true;
},
defaultAction: function(actions){
this.showHome();
},
showHome:function(actions){
// will render home view and navigate to homeView
var homeView=new HomeView();
homeView.render();
this.changePage(homeView, 'fade');
},
showProducts:function(){
var productList=new Products();
var self = this;
productList.fetch({
success:function(data) {
self.changePage(new ProductListView({collection:data}));
}
});
},
changePage:function (view, transition) {
//add the attribute 'data-role="page" ' for each view's div
if (transition != "slidefade") {
transition = "pop";
}
view.$el.attr('data-role', 'page');
$('.ui-page').attr('data-role', 'page');
//append to dom
$('body').append(view.$el);
if(!this.init){
$.mobile.changePage($(view.el), {changeHash:false, transition: transition});
}else{
this.init = false;
}
}
});
$(document).ready(function () {
console.log('App Loaded');
app = new AppRouter();
Backbone.history.start();
});
return AppRouter;
here is also my view page for product
var ProductListView = Backbone.View.extend({
template: _.template(productViewTemplate),
initialize: function () {
_.bindAll(this, "render");
this.collection.bind("reset", this.render);
},
render: function () {
var self = this;
this.collection.each(function(model) {
self.$el.append(self.template(model.toJSON()));
console.log("here");
});
}
});
return ProductListView;
So from within the homeView I can change the page and that's fine the issue what am i doing wrong on the products view for it not to return a thing.. no errors are returned.
thanks
so I have done some more work and made my show products function
showProducts:function(){
var productList=new Products();
var self = this;
var productListView =new ProductListView({collection:productList});
productList.fetch(self.changePage(productListView));
}
this works when the view is
var ProductListView = Backbone.View.extend({
template: _.template(productViewTemplate),
initialize : function () {
_.bindAll(this, "render");
this.collection.bind("reset", this.render, this);
},
render: function() {
var self = this;
this.collection.each(function(model) {
self.$el.append(self.template(model.toJSON()));
console.log("here");
});
}
});
return ProductListView;
but now jQueryMobile doesnt add on its code so it has no styling..
any suggestions?
Both Backbone.js's router and jQuery Mobile use the hashtag and don't work so well together. There are ways to get them to work but unless you have specific reason to do so I'm not sure its worth it, instead I'd recommend using jQuery-Mobile-router which is a plugin for jQuery mobile, that was created for this very reason (that is to work with Backbone.js). As a bonus the jQuery Mobile Router ties in with the special JQM Page events.

jquery mobile $.mobile.showpageloadingmsg() is not working

I wish to show loading message during page transition in jQM and backbone. But the showPageLoadingMeassage isnt working.
Following is my code:
collection.js
findById : function(artistId, page, limit, sort) {
$.mobile.showPageLoadingMsg('a', 'Loading......', false);
var self = this;
if (limit == undefined) {
limit = 10;
}
$.mobile.showPageLoadingMsg('a', 'Loading......', false);
console.log("hello");
$.ajax({
type: "GET",
url: siteURL + 'artists/artist_detail/artist_id' + artistId + '.json',
}).done(function(msg) {
var response = JSON.parse(msg);
if (response.status == true) {
var dataArray = response.data;
console.log(dataArray);
self.reset(dataArray);
if (self.length > 0) {
$.mobile.hidePageLoadingMsg();
}
//return dataArray;
} $.mobile.showPageLoadingMsg($.mobile.pageLoadErrorMessageTheme, 'Sorry! No records found', true);
setTimeout(function() {
$.mobile.hidePageLoadingMsg();
}, 1500);
}
});
}
where am i getting wrong?
edited:
it works when for search page:
... findByTitle : function(keyword, genre, language, page, limit, sort, collection, fan, featured) {
//~ console.log(page);
var self = this;
if (limit == undefined) {
limit = 10;
}
$.mobile.showPageLoadingMsg('a', 'Searching......', false);
$.ajax({....
found the answer on stackoverflow itself- jQuery Mobile - Problems getting showPageLoadingMsg to work with pagebeforeshow or pagebeforeceate.
It says that sometimes jQM doesn't adds the ui-loading class to the body so we have to do it manually.
$('body').addClass('ui-loading');
$.mobile.showPageLoadingMsg('a', 'Searching......', false);
and while hiding the loading msg:
setTimeout(function() {
$('body').removeClass('ui-loading'); //remove class
$.mobile.hidePageLoadingMsg();
}, 1000);
This function was also deprecated and in the current versions is not at all.

Changing link destination with the pagebeforechange event and keeping it out of the history?

I am working on a PhoneGap application that uses jQuery Mobile (jQM). This application has areas that will require the user to be authenticated. So I'm using jQM's pagebeforechange to determine if the user needs to authenticate before viewing the page they have requested. If so, I send them to a login page.
I want to keep the login page out of jQM's history tracking. That is, if the user is presented with the login page, but decides to press "cancel," I want the application to go back to the previous page and not have a "next" page in the history; the "previous page" would be at the top of the history stack.
Here's how I am handling the login page redirection:
$(document).bind('pagebeforechange', function(e, data) {
if (typeof data.toPage !== 'string') {
return;
}
if (data.toPage.match(/someRestrictedPage/)) {
data.options.transition = "pop";
data.options.changeHash = false;
data.toPage = "myLogin.html";
}
});
For the cancel button of my login page I am doing:
$loginCancelButton.bind('click', function() {
var prevPage = $.mobile.urlHistory.getPrev();
if (typeof prevPage !== 'undefined') {
$.mobile.changePage(prevPage.url, {
changeHash: false,
reverse: true,
transition: "pop"
});
}
});
However, when I do this, I end up with a $.mobile.urlHistory.stack with three elements:
[ {"index"}, {"login"}, {"index"} ]
How do I manage intercepting page changes to redirect to a login form when necessary, but not create an "invalid" navigation history?
looking at the jquery docs it mentions that pagebeforeload event needs to be stopped. and then call the data.deferred (resolve or reject).
try changing it to:
$(document).bind('pagebeforechange', function(e, data) {
if (typeof data.toPage !== 'string') {
return;
}
if (data.toPage.match(/someRestrictedPage/)) {
e.preventDefault()
data.options.transition = "pop";
data.options.changeHash = false;
data.toPage = "myLogin.html";
}
data.deferred.resolve(/* url */, data.options)
});
A solution for the initial problem could be something like:
$(document).bind('pagebeforechange', function(e, data) {
if (typeof data.toPage !== 'string') {
return;
}
if (data.toPage.match(/ your regex /gi))
{
if (!check_login())
{
e.preventDefault();
data.options.transition = "pop";
data.options.changeHash = false;
data.toPage = "#SignIn";
$.mobile.changePage("#SignIn");
}
//data.deferred.resolve('#SignIn', data.options);
}
});
That worked for me just fine.
VeXii's solution seemed to work for me. By simply removing
data.deferred.resolve('#SignIn', data.options);
and
e.preventDefault();
On jquery mobile 1.3...
$(document).bind('pagebeforechange', function(e, data) {
if (typeof data.toPage !== 'string') {
return;
}
if (data.toPage.match(/index/)) {
data.options.transition = "pop";
data.options.changeHash = false;
data.toPage = "#login";
}
});

Resources