Two pages are "merged" together if include jQuery Mobile in 1st page - jquery-mobile

I have a very simple HTML two page demo that ilustrates a very confusing behavior in jQuery Mobile 1.1.0. (The real app is much more complicated but I've been able to "massively" simplify the problem.)
Page 1 consists of a single href to jump to Page 2. If Page 1 does NOT include jQuery Mobile 1.1.0 we can click on the link and Page 2 is displayed with no errors. However, if Page 1 includes jQuery Mobile 1.1.0, a click on the link in Page 1 results in a Page that is a combination of the HTML in Page 1 and Page 2! That is, Page 1 is retained and Page 2 is "merged" into it. I have tried this with both the regular and the minified versions with the same result. The two pages are as simple as an HTML page can get so it should be very easy to reproduce this with the samples below. This is running with Tomcat 5.5 (and if it matters, being managed and laumched out of Eclipse). The two HTML files and the two jQuery Mobile files are all placed in a folder at the server's document root. (The browser output below is from running through Tomcat, but I just tried this by launching the browser directly off of the Page1.html file - no server involved at all - and the problem persists, so this can be reproduced without a server being involved.)
The following shows the file contents for Page1 and Page 2, along with the HTML that is seen in the desktop Firefox browser (in Firebug).
* PAGE 1 SOURCE HTML:
<!doctype html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!-- Remove jQuery Mobile and Page 2 is displayed properly. -->
<script src="jquery.mobile-1.1.0.min.js" ></script>
</head>
<body >
Click for Page 2
</body>
</html>
RESULTING PAGE 1 HTML IN THE BROWSER:
<html lang="en" class="ui-mobile"><head><base href="http://localhost/MyServer/DemoBadJQM/Page1.html">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="jquery.mobile-1.1.0.min.js"></script>
<title></title></head>
<body class="ui-mobile-viewport ui-overlay-c"><div data-role="page" data-url="/MyServer/DemoBadJQM/Page1.html" tabindex="0" class="ui-page ui-body-c ui-page-active" style="min-height: 521px;">
Click for Page 2
</div><div class="ui-loader ui-corner-all ui-body-a ui-loader-default"><span class="ui-icon ui-icon-loading"></span><h1>loading</h1></div></body></html>
PAGE 2 SOURCE HTML:
<!doctype html>
<html lang="en">
<head></head>
<body >
This is from PAGE 2 BODY!!!
</body>
</html>
RESULTING PAGE 2 HTML IN THE BROWSER:
<html lang="en" class="ui-mobile"><head><base href="http://localhost/MyServer/DemoBadJQM/Page2.html">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!-- Remove jQuery Mobile and Page 2 is displayed properly. -->
<script src="jquery.mobile-1.1.0.js"></script>
<title></title></head>
<body class="ui-mobile-viewport ui-overlay-c ui-mobile-viewport-transitioning viewport-fade"><div data-role="page" data-url="/MyServer/DemoBadJQM/Page1.html" tabindex="0" class="ui-page ui-body-c ui-page-active fade out" style="min-height: 521px; height: 522px;">
Click for Page 2
</div><div class="ui-loader ui-corner-all ui-body-a ui-loader-default"><span class="ui-icon ui-icon-loading"></span><h1>loading</h1></div><div data-role="page" data-url="/OpsServer/DemoBadJQM/Page2.html" data-external-page="true" tabindex="0" class="ui-page ui-body-c">
This is from PAGE 2 BODY!!!
</div></body></html>
Note that, with jQuery Mobile included in Page 1:
"Page 2", which had no content, contains the content of Page 1.
"Page 2" contains the href and the "loading" elements from Page 1.
"Page 2" finally includes the simple text from the in the Page 2 HTML file.
The page that results from clicking the link in Page 1 appears to be Page 1 with Page 2's appended. Drop jQuery Mobile from Page 1 and the problem is gone. It is purely a guess, but jQuery Mobile displays a "loading" message while the next page is being fetched and it appears that the act of doing this somehow prevents the browser from "disposing" of Page 1 and it instead merges the incoming Page 2 with the prior Page 1.
Can anyone explain what is happening here?
Thanks.

Using rel="external" along with the href in Page 1 fixes this problem.

This may be out dated but I just ran in to something similar. It looks like the reason is because jQuery Mobile will fetch the page, load it into the DOM, then transition between the pages like a slide. I'm assuming your viewable area was enough to hold the pages in such a way that it didn't even try to slide between the pages.
Our situation was that we had some pages with jQuery Mobile explicitly loaded and some without, and the ones with out were somehow getting the Mobile library's functions.
jQM loads itself and other pages into memory so that it can reduce the number of network requests and also to be able to transition nicely between pages. You can also tell it to preload images and pages in the background after you load your first page.
It's a slightly different beast than just regular html pages. Just try and think about optimizing the site for as few network requests as possible.
http://jquerymobile.com/demos/1.0b2/docs/pages/page-cache.html#/demos/1.0b2/docs/pages/page-anatomy.html

Related

jQuery mobile - Multiple page loads on change page

I am using a multiple page format with a persistent header. I can successfully change page either with a straight hyperlink or using $(':mobile-pagecontainer').pagecontainer('change'
The code works fine but it seems to "load" the page an additional time each time I click on the buttons to change page.
In this code the button changes the page and outputs a console.log message.
On click I would expect the page to change and to see one "#btn - page x" console.log message.
What happens is the page changes and I get a console message for each time I've loaded the page, not just one.
Even though my code is working, this can't be right - this will just go up and up with normal user usage.
What am I not understanding here?
I've created a jsfiddle to show what I mean. For example, if I click the "goto page x" button 6 times (that's 3 times for each page), I get an output of 3 "#btn - page x" messages, not just one.
Same with the header button - each time I change the page, number of responses from the header button goes up.
the html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>problem</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div data-role="header" data-position="fixed" data-theme="a">
header button
</div>
<div data-role="page" id="page1" data-title="Page 1">
<div data-role="content">
<h1>I am page 1</h1>
goto page2
</div>
</div>
<div data-role="page" id="page2" data-title="Page 2" data-theme="b">
<div data-role="content">
<h1>I am page 2</h1>
goto page1
</div>
</div>
<script src="problem.js"></script>
</body>
</html>
and the js:
$(document).on('pagebeforeshow','#page1',function(){
console.log('#page1 pagebeforeshow');
$('#btntest1').click(function(){
console.log('#btn - page1');
//$(':mobile-pagecontainer').pagecontainer('change', '#page2', { reloadPage: false});
});
});
$(document).on('pagebeforeshow','#page2',function(){
console.log('#page2 pagebeforeshow');
$('#btntest2').click(function(){
console.log('#btn - page2');
//$(':mobile-pagecontainer').pagecontainer('change', '#page1', { reloadPage: false});
});
});
$(function() {
$("[data-role='header']").toolbar();
});
$(document).on('pagebeforeshow',function(){
console.log('pagebeforeshow');
$('#headerbtn').click(function(){
console.log('headerbtn click');
});
})
UPDATE:
So I've been trying all sorts of things to try to fix this, including removing data-rel="back", trying data-ajax="false" (which defeats the point of what I'm trying to do), changing page with
$(':mobile-pagecontainer').pagecontainer('change', '#page2');
or
$(':mobile-pagecontainer').pagecontainer('change', '#page2', { reloadPage: false});
but no joy. Obviously, I've tried googling but can't find anything to help.
In the full app code the buttons communicate with a database, so as the clicks increase, I'm sending and retrieving the same data to the db multiple times on each click.
I really would appreciate some guidance if anyone has any ideas what I could do?
The problem is that each time you're entering the page, you are binding a listener on the element again. So you're binding multiple listeners. The listener should not be written inside the pagebeforeshowhandler.
Take it out like this:
$(document).on('pagebeforeshow','#page1',function(){
console.log('#page1 pagebeforeshow');
});
$('#btntest1').click(function(e){
e.preventDefault();
console.log('#btn - page1');
$(':mobile-pagecontainer').pagecontainer('change', '#page2', { reloadPage: false});
});
And for page 2 likewise.

Mobile Safari text selection after input field focus iOS 5 vs iOS 6

I have some legacy html that needs to work on old and new browsers (down to IE7) as well as the iPad. The iPad is the biggest issues because of how text selection is handled. On a page there is a textarea as well as some text instructions. The instructions are in a <div> and the user needs to be able to select the instructions.
The problem is that once focus is placed in the textarea, the user cannot subsequently select the text instructions in the <div>. This is because the text cannot receive focus.
According to the Safari Web Content Guide: Handling Events (especially, "Making Elements Clickable"), you can add a onclick event handler to the div you want to receive focus.
This solution works (although it is not ideal) in iOS 6x but it does not work in iOS 5x.
The question is, how can I select text on a page after an input control has focus. This needs to work on iOS 5.1+
Here is sample code that shows the problem.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<!--
Resources:
Safari Web Content Guide: Handling Events (especially, "Making Elements Clickable")
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW1
-->
</head>
<body>
<div style="width:550">
<div onclick='console.debug("Click!"); void(0);'>
<p>On the iPad, I want to be able to select this text after the textarea has had focus.</p>
</div>
<textarea rows="20" cols="80">After focus is in the textarea, can you select the text above?</textarea>
</div>
</body>
</html>

properly using jQuery Mobile event handling in version 1.7.1

I am at my wits end with jQuery Mobile events. I do not understand them, despite following the docs to the T. I am using the following code to initialize my pages. The problem is that some seem to fire multiple times and occasionally when I go back to a page nothing will appear, as though .live pageinit simply doesn't fire at all. I am quite confused. Is pageinit the way to go? is .live best practice? Do I need to clean up after myself and use something like pagehide to remove stuff from the DOM? Please help me understand. Thanks!
// page number 1
<header>
includes and stuff
<header>
<body>
<div data-role="page" data-theme="a" id="dashboardPage">
$('#dashboardPage').live('pageinit',function() {
});
// somewhere in here a page transition to anotherPage.html (not necessarily the id of the new page in the <div data-role-"page data-theme...> declaration
$.mobile.changePage("anotherPage.html",{transition : "slide"});
</div>
</body>
// page number 2
<header>
includes and stuff
<header>
<body>
<div data-role="page" data-theme="a" id="specialsPage">
$('#specialsPage').live('pageinit',function() {
});
</div>
</body>
You could try something like this:
<html>
<header>
<!-- BASIC INCLUDES -->
<link rel="stylesheet" href="./css/jquery.structure-1.1.0.min.css" />
<link rel="stylesheet" href="./css/jquery.mobile-1.1.0.min.css" />
<link rel="stylesheet" href="./css/jquery.mobile.theme-1.1.0.min.css" />
<script type="text/javascript" src="./js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="./js/jquery.mobile-1.1.0.min.js"></script>
<!-- END - BASIC INCLUDES -->
</header>
<body>
<!-- PAGE 1 -->
<div data-role="page" data-theme="a" id="dashboardPage">
<script>
// INITIALIGE PAGE 1 - dashboardPage
$("#dashboardPage").live('pageinit',function(event){
alert( '"initializing" page 1: dashboardPage');
});
</script>
HERE YOU ARE AT PAGE 1 (dashboardPage)!!!<br><br>
CLICK HERE TO GO TO PAGE 2 (specialsPage)
</div>
<!-- PAGE 2 -->
<div data-role="page" data-theme="a" id="specialsPage">
<script>
// INITIALIGE PAGE 2 - specialsPage
$("#specialsPage").live('pageinit',function(event){
alert( '"initializing" page 2: specialsPage');
});
</script>
HERE YOU ARE AT PAGE 2 (specialsPage)!!!<br><br>
CLICK HERE TO GO TO PAGE 1 (dashboardPage)
</div>
</body>
</html>
Hope it helps.
When using JQuery mobile you should consider you have a single page which content is updated dynamically. You do not navigate from one page to the other as you normally would.
Because of this, any code present in a page you navigate to with JQM simply be ignored (tyr changing the header of page number 2, and navigate to this page from page number 1 with changepage, you will not see any difference).
Because of that, all your js code should be directly available within the page in which your user will arrive.
If you add the following code in the scripts of page 1, you will proeperly detect the initialization of of page2 when it is loaded with changepage.
$("#specialsPage").live('pageinit',function(event){
alert( '"initializing" page 2: specialsPage');
});
An important thing to keep in mind is that you user might also directly access your page2, which means that all the code should also be available for page 2. Because of this I would strongly recommend including all your code in a js file referenced in the headers of all your page, and NOT directly in script tags within your pages.

Printing in IE8 Has #href contents inline

Can someone tell me how to stop IE8 printing the value of the href for an A tag next to the text. For example this markup
Some Link
When printed comes out as
Some Link(/site/page.html)
when printed. How can I stop this?
This doesn't happen for me in IE8 and I've never spotted it. I also can't find it in the Internet Options anywhere.
It is possible that you have some software on your computer that does this, for example AVG Anti-Virus adds content to web pages to tell you that it has checked the links being displayed for potentially harmful content - so your system-security software may be expanding all links to show you where they actually point, to prevent phishing attacks.
If you do have some anti-phishing software on your machine, you'll have to find the option within that.
Update - It is almost certainly some clever CSS.
I have created the following test page to demonstrate how you can add the URL to a link using CSS generated content. If this was used within a print stylesheet, this would explain how the URL is getting added to the link when you are printing the page. To stop this, you would have to save a copy of the web page, remove the style rule from the print-only style sheet and then open your copy and print it!
<html>
<head>
<title>Test</title>
<style type="text/css">
a:after {
content: " [" attr(href) "] ";
}
</style>
</head>
<body>
<h1>Test</h1>
<p>This is a test to see if this
Link Shows A URL</p>
</body>
</html>

JQuery SimpleModel Plugin and MVC

Has anyone ever been successful at getting the SimpleModel jquery pluggin to work in asp.net mvc? If so how did you implement it, I can't seem to get the dialog to even display.
I am assuming you are talking about the SimpleModel jquery plugin found at http://www.ericmmartin.com/projects/simplemodal/ and that you've already got a basic ASP.NET MVC application setup.
I am going to run through how you can get the Basic Modal Dialog example working.
Get the plugin files into your ASP.NET MVC application
Download the example from the demos link on the link above and unzip it.
Copy the basic.css and basic_ie.css files into the Content folder of your ASP.NET MVC application.
Also copy the img folder into the Content folder of your ASP.NET MVC application.
Lastly, copy the javascript files in js folder into the Scripts folder of your ASP.NET MVC application.
Reference the stylesheet and javascript files in your application
Open your Site.Master file under Views\Shared and paste the code below before the </head> tag
<link type='text/css' href='../../Content/basic.css' rel='stylesheet' media='screen' />
<!-- IE 6 "fixes" -->
<!--[if lt IE 7]>
<link type='text/css' href='../../Content/basic_ie.css' rel='stylesheet' media='screen' />
<![endif]-->
<script type='text/javascript' src='../../Scripts/jquery.js'></script>
<script type='text/javascript' src='../../Scripts/jquery.simplemodal.js'></script>
<script type='text/javascript' src='../../Scripts/basic.js'></script>
Finally, call the dialog in your view
For example in Index.aspx, you can paste the following code:
<div id='basic-modal'><h2>Basic Modal Dialog</h2>
<p>A basic modal dialog with minimal styling and without any additional settings. There are a few CSS attributes set internally by SimpleModal, however, SimpleModal relies mostly on external CSS for the look and feel.</p>
<input type='button' name='basic' value='Demo' class='basic demo'/> or <a href='#' class='basic'>Demo</a>
</div>
<div id="basic-modal-content">
<h3>Basic Modal Dialog</h3>
<p>For this demo, SimpleModal is using this "hidden" data for its content. You can also populate the modal dialog with standard HTML or with DOM element(s).</p>
<p>Examples:</p>
<p><code>$('#basicModalContent').modal(); // jQuery object; this demo</code></p>
<p><code>$.modal(document.getElementById('basicModalContent')); // DOM</code></p>
<p><code>$.modal('<p><b>HTML</b> elements</p>'); // HTML</code></p>
<p><a href='http://www.ericmmartin.com/projects/simplemodal/'>More details...</a></p>
</div>
Hope that helps.
Matrich

Resources