Working on my first jQuery Mobile app. There is a localStorage value that must have a value throughout the application, so I tapped into the pageshow event to check this value:
$(function () {
$("div[data-role='page']").on("pageshow", function (event, ui) {
if (getValue() == null) {
// show the dialog
$.mobile.changePage("#dialog");
}
});
});
This works when navigating through the various pages, but never gets called when the first page loads. I tried to copy the above If statement again below the part where I add the pageshow listener, but it has the effect of showing the dialog, hiding it, then showing it again.
On that first page, it seems like opening the dialog is triggering pageshow (which is strange, considering my selector), which in turn triggers another dialog. Does anyone have advice on how to get around this, or a better way to go about the whole thing?
UPDATE #1: I tried
$.mobile.changePage( "#mypage", { allowSamePageTransition: true, transition: "none" } );
but it had the same effect as my original problem where it launches the dialog, then hides it, then shows it again. It seems like somehow launching the dialog is firing the pageshow event, even though I tried to filter that out in my selector. Note that if you remove the transition: "none" option, the dialog does not appear at all.
UPDATE #2: I also tried to create a blank initial page, then do a simple page transition
$.mobile.changePage("#mypage");
but it still does not have the correct behavior. In this scenario, it does take me to the next page, but the pageshow event does not fire, because my dialog does not appear. I know it is not firing because I can select another page from my navigation menu and the dialog does appear.
UPDATE #3: I changed my selector where I attach the pageshow listener. Instead of selecting where data-role="page", I am selecting the specific pages by their id. Then I re-tried both of the approaches I described in my previous two updates, but it still works incorrectly. First, when I try to refresh the initial page using allowSamePageTransition, it seems that pageshow fires twice, because the dialog launches twice. Then, when I try using a blank initial page, and then do a redirect immediately after I attach the pageshow listener, nothing happens and the dialog never appears. If I navigate to any other page, the dialog works as expected. I don't understand why this first page is so troublesome.
Set a time interval to show the dialog, rather than call it once the page is shown.
$(document).on('pageshow', '#myPage' ,function () {
if (getValue() == null) {
setTimeout(function () {
$.mobile.changePage('#dialog');
}, 100); // delay above zero
}
});
This way, the dialog will popup on pageshow event and only once.
update
I found this interesting jQueryMobile events diagram on this blog. It explains why a dialog or a popup is fired twice on the first page and not on the rest of the pages in case of multi-pages structure. It seems it fires once the page is ready into DOM and again when on pageshow. Setting a timeout prevents the dialog from firing on pageinit, and therefore skips that event until pageshow is triggered.
Image / diagram source: http://bradbroulik.blogspot.co.nz/2011/12/jquery-mobile-events-diagram.html
Most probably is that on first page, that event is already fired when your piece of code is executed. Which explains why you get nothing only on the first page.
About your second point, it's normal since, changePage will "change" the page to the dialog, and once you close the dialog, it will return to your previous page. Thus, the if is executed 2 times.
My suggestion is that for the first time you enter the first page, you can re-transition to the same page just after you register the callback for the pageshow event.
I used "pagecreate" and that seems to solve my problem (so far...)
$(document).on('pagecreate', "#page-formyID", function () {
//whatever
});
Related
We have a basket page, where there are the products, and then the shipping methods. This is a jQuery mobile site.
What I want to achive, that if a shipping method selected, then if there is a page reload, jQuery mobile jumps to a div to the shipping methods.
Here is the code, what scrolls to the shipping methods. This is an inline script.
$(document).on("pageshow", function (e, ui) {
$.mobile.silentScroll($('#kosar').offset().top);
});
Expected result: on page refresh, the window scroll to the #kosar div.
Current result: page scrolls to the #kosar div, but immediatly scroll to the top of the page.
What we discovered, if some error is occures after the silentScroll, the window is not jump back to the top of the page. So it seems, something after the pageshow scrolls it to back, but we do not know, what.
For example:
$(document).on("pageshow", function (e, ui) {
$.mobile.silentScroll($('#kosar').offset().top);
undefined_function(); //This function is not exists
});
Here are the non working, and "working" examples:
Here is a live example. When you refresh the page, you will see for a second the big red text, and immediatly after that you will be taken to the top of the page.
Here is the example with error.
I've tested it in FF Developer Edition. With Chrome, you need to resize your browser to a littlebit smaller, and refresh some times to see the scrollbar how jumping to bottom and up.
How can I prevent this annoying scroll to top?
I think, this is a bug in the jQuery mobile js, I've reported it to them.
Finally I figured it out.
Version:
http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js
I've made a breakpoint in the jQuery mobile js silentScroll definition, and what I've see, for some reason it run twice. The first is a good call, ypos is a number, where I want to jump, this is why it jump to the right place.
But, later, at line 15432 here are these lines of codes, what is running on document ready:
// window load event
// hide iOS browser chrome on load if hideUrlBar is true this is as fall back incase we were too early before
if ( $.mobile.hideUrlBar ) {
$window.load( $.mobile.silentScroll );
}
And when it's happens, on the second call, the ypos for silentScroll will be an object, not a number, as the function expects, and if it not a number, then jQuery mobile set the ypos to $.mobile.defaultHomeScroll what is actually 1 if you do not modified. This is why it jumps back to home.
Warning: If you think, you just need to set the $.mobile.hideUrlBar to false, you are wrong. I've tried it, but it had side effects, because in line 15416 there are another reference for this variable, and if you turn off, then when you go from a page to another, you wont be redirected to the top of your second page.
So the solution was to comment out this $window.load( $.mobile.silentScroll ); and now everything is working as I expected.
I'm using jqueryUI for a datepicker to pick birthdays. Turns out in IE if the person tries to type in the box instead of using the picker, and hits the backspace, they get kicked off the form and to a previous page. Can anyone explain or propose a fix? Also not sure why the red asterisk is showing up inside the box when it shows outside in firefox and when all the others display correctly.
Looking at the eighth field:
http://www.craftonhills.edu/Degrees_and_Certs/Divs_and_Depts/Career_Education_and_Human_Development/Public_Safety_and_Services/Fire_Technology/Firefighter_Academy/Firefighter_Academy_Info/Application
Backspace key in the browser defaults to triggering the Back button. You can try to intercept the keystroke (See here: Intercepting all key presses with jQuery before they are processed) to stop it from firing, but a better solution might be to add a "Clear" button to the jQuery UI Element to remove the field so the back button still works as intended.
Try the following:
$(document)
.on('keypress keydown keyup', '.datepicker', function(e) {
if ( e.keyCode == 8 ) e.stopPropagation();
});
Replace .datepicker with whatever selector you are using.
This should allow the backspace to work as expected in the text block but still prevent the backspace (from bubbling up the DOM) from triggering the browser back action.
I want to load some data with ajax and manipulate the DOM of a given "detail page". BEFORE the page is being shown. Important is that nothing of the "detail page" should be visible till all of the loading and manipulating of this page has finished. During the loading process the loading widget should also appear.
I tried this with:
$( '#page_series_detail' ).live( 'pageinit',function(event)
{
AjaxSeriesDetail();
});
But in this case all of the loading and manipulating happens after the page is being shown.
Has anyone a hint for me ?
You should try the pagebeforeshow event of jQuery Mobile. This event will fire before showing the page to the user.
As per the documentation
Triggered on the "toPage" we are transitioning to, before the actual
transition animation is kicked off.
Using jQuery Mobile (jquery.mobile-1.0b3.min.js). If i apply a click event to a form, the back button seems to get the click event binding as well. It does this no matter how specifically targeted to an element the selector is. For example:
Using this to set the back button:
Copy code
<div id="pagename-page" data-role="page" data-add-back-btn="true" data-back-btn-theme="b">
And this in a script file:
Copy code
$('#awards-details-page').live('pagecreate', function(event){
$('#awards-details-page input[name=submit]').bind('vclick', function() {
console.log('I'm going to be hijacked by the back button.');
});
});
Clicking on the back button will produce the message in the console when tested in a browser.
Every time you visit the page with the script, it will add another duplicate binding. Attempts to unbind the click event on the pagehide event worked with the targeted element, but back button's bindings persisted.
Can anyone shed some light on this?
Thank you in advance.
dont use vclick you will ge ghost, they have improved CLICK so just use that
also live is not bind... bind is to an element that exist, live is for all elements that have that shared property, before after and during. you past pages exist so you have a set of binded items now not just one for the page you are on. i would scrap the whole back button element and have your own clickable item, for this you can do your own back code and add attributes like data-backto = "#page1", you can then control better what happens when a back button is clicked, especially as android phones have there own back button too.
I have a textarea element inside of a jquery modal dialog that has an attached blur handler. The blur handler code is triggered correctly in Chrome and Internet Explorer when the click of the button on the dialog, which calls $('#mydialog).dialog('destroy').remove(); occurs.
Unfortunately, in Firefox this is not happening!
Why might this be?
I was able to eventually resolve the issue by utilizing setTimeout to wrap the click handler code in, which allowed enough time for the blur event on the textarea to fire properly.
The resulting code was as follows:
var c = $('#mydialog');
setTimeout(function() {c.dialog('destroy').remove();}, 1);
As it turns out so far, a 1ms timeout is just enough to force the appropriate context switch in the browser to allow for the blur event to occur before the element is removed from the DOM.