I’ve created this test page to bring out the issue I’m encountering.
The first time I click on ‘Form’ tab, the browser shows jQuery Mobile check boxes. Then if I click on ‘Home’ tab and again ‘Form’ tab, it shows browser’s native check boxes!
What am I doing wrong here? How to fix it?
Thanks in advance!
index.html:
<!doctype html>
<html>
<head>
<title>Form Test</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script>
var value1;
var value2;
// remap jQuery to $
(function($) {
})(window.jQuery);
/* trigger when page is ready */
$(document).ready(function() {
initialize();
});
/**
* Initialize the page.
*
*/
function initialize() {
// get server parameters befor making ajax call
getFormValues();
// add click handler to the application navigation menu options
$("nav li").live('click', function(e) {
});
}
/**
* Gets server parameters from the application's configuration file.
*
*/
function getFormValues() {
// get the server URL from external XML file
$.ajax({
type : "GET",
url : "assets/config/formValues.xml",
cache : false,
async : false,
timeout : 5000,
dataType : "xml",
success : function(xml) {
$(xml).each(function() {
value1 = $(this).find('value1').text();
value2 = $(this).find('value2').text();
});
}
});
}
// Listen for any attempts to call changePage()
$(document).bind("pagebeforechange", function(e, data) {
// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
if( typeof data.toPage === "string") {
// We are being asked to load a page by URL, but we only
// want to handle URLs that request the data for a specific
// category.
var u = $.mobile.path.parseUrl(data.toPage);
if(u.hash.search(/^#formSection/) !== -1) {
currentContentSection = "formSection";
// We're being asked to display the items for a specific category.
// Call our internal method that builds the content for the category
// on the fly based on our in-memory category data structure.
displayValueFilters();
// Make sure to tell changePage() we've handled this call so it doesn't
// have to do anything.
e.preventDefault();
}
}
});
/**
* Sets up and displays values.
*
*/
function displayValueFilters() {
var pageSelector = "#formSection";
// Get the page we are going to dump our content into
var $page = $(pageSelector);
// get the div that's expected to have the search fields
var $searchFields = $page.children(":jqmData(role=sclRole)")
// Get the content area element for the page.
var $content = $page.children(":jqmData(role=content)");
// The markup we are going to inject into the content area of the page.
var markup = "";
markup += "<label for='value1'>" + value1 + "</label>";
markup += "<input type='checkbox' name='value1' id='value1' />";
markup += "<label for='value2'>" + value2 + "</label>";
markup += "<input type='checkbox' name='value2' id='value2' />";
$content.empty();
$(markup).appendTo($content).trigger("create");
// Pages are lazily enhanced. We call page() on the page
// element to make sure it is always enhanced before we
// attempt to enhance the listview markup we just injected.
// Subsequent calls to page() are ignored since a page/widget
// can only be enhanced once.
$page.page();
// Now call changePage() and tell it to switch to the page we just modified.
$.mobile.changePage($page, options);
}
</script>
</head>
<body>
<!-- home page section -->
<section id="homePageSection" data-role="page" data-title="Form Test - Home">
<div data-role="header">
<h1>Form Test</h1>
<nav data-role="navbar">
<ul>
<li>
<a href="#" class="ui-btn-active ui-state-persist" >Home</a>
</li>
<li class="formLineItem">
<a href="#formSection">Form</a>
</li>
</ul>
</nav>
</div><!-- /header -->
<div data-role="content" class="container">
<h1>Form - Home Page</h1>
</div><!-- /content -->
<div data-role="footer"></div><!-- /footer -->
</section><!-- /homePageSection -->
<!-- form section -->
<section id="formSection" data-role="page" data-title="Form Test - Form">
<div data-role="header">
<h1>Form Test</h1>
<nav data-role="navbar">
<ul>
<li>
<a href="#homePageSection">Home</a>
</li>
<li class="formLineItem">
<a href="#" class="ui-btn-active ui-state-persist" >Form</a>
</li>
</ul>
</nav>
</div><!-- /header -->
<div data-role="content" class="container">
</div><!-- /content -->
<div data-role="footer"></div><!-- /footer -->
</section><!-- /formSection -->
</body>
</html>
assets/config/formValues.xml:
<formValues>
<value1>Videos</value1>
<value2>Images</value2>
</formValues>
Updated code that works:
<!doctype html>
<html>
<head>
<title>Form Test</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script>
// data used to generate checkboxes
var value1;
var value2;
// flag that determines the page has already been initialized
var pageInitialized = false;
// flag that determines if the dynamic form has already been created from the loaded data
var formCreated = false;
// remap jQuery to $
(function($) {
})(window.jQuery);
// trigger when page is ready
$(document).ready(function() {
initialize();
});
/**
* Initialize the page.
*
*/
function initialize() {
// get server parameters befor making ajax call
getFormValues();
// set the flag indicating that the page has already been initialized
pageInitialized = true;
}
/**
* Gets server parameters from the application's configuration file.
*
*/
function getFormValues() {
// get the server URL from external XML file
$.ajax({
type : "GET",
url : "assets/config/formValues.xml",
cache : false,
async : false,
timeout : 5000,
dataType : "xml",
success : function(xml) {
$(xml).each(function() {
value1 = $(this).find('value1').text();
value2 = $(this).find('value2').text();
});
}
});
}
// Listen for any attempts to call changePage()
$(document).bind("pagebeforechange", function(e, data) {
// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
if( typeof data.toPage === "string") {
// We are being asked to load a page by URL, but we only
// want to handle URLs that request the data for a specific
// category.
var u = $.mobile.path.parseUrl(data.toPage);
if(u.hash.search(/^#formSection/) !== -1) {
currentContentSection = "formSection";
// if the form has not yet been created, proceed to creat it
if(!formCreated) {
// if the page hasn't been initialized (data not loaded), proceed to initialize
// this happens when the user refreshes the page when on 'Form' tab
if(!pageInitialized) {
initialize();
}
// generate the form controls from the loaded data and add them to the page
displayValueFilters();
formCreated = true;
// Make sure to tell changePage() we've handled this call so it doesn't
// have to do anything.
e.preventDefault();
}
}
}
});
/**
* Sets up and displays values.
*
*/
function displayValueFilters() {
var pageSelector = "#formSection";
// Get the page we are going to dump our content into
var $page = $(pageSelector);
// The markup we are going to inject into the content area of the page.
var markup = "";
markup += "<label for='value1'>" + value1 + "</label>";
markup += "<input type='checkbox' name='value1' id='value1' />";
markup += "<label for='value2'>" + value2 + "</label>";
markup += "<input type='checkbox' name='value2' id='value2' />";
$("#valueCheckboxes").empty();
$(markup).appendTo("#valueCheckboxes").trigger("create");
// Pages are lazily enhanced. We call page() on the page
// element to make sure it is always enhanced before we
// attempt to enhance the listview markup we just injected.
// Subsequent calls to page() are ignored since a page/widget
// can only be enhanced once.
$page.page();
// Now call changePage() and tell it to switch to the page we just modified.
$.mobile.changePage($page, options);
}
</script>
</head>
<body>
<!-- home page section -->
<section id="homePageSection" data-role="page" data-title="Form Test - Home">
<div data-role="header">
<h1>Form Test</h1>
<nav data-role="navbar">
<ul>
<li>
<a href="#" class="ui-btn-active ui-state-persist" >Home</a>
</li>
<li class="formLineItem">
<a href="#formSection">Form</a>
</li>
</ul>
</nav>
</div><!-- /header -->
<div data-role="content" class="container">
<h1>Form - Home Page</h1>
</div><!-- /content -->
<div data-role="footer"></div><!-- /footer -->
</section><!-- /homePageSection -->
<!-- form section -->
<section id="formSection" data-role="page" data-title="Form Test - Form">
<div data-role="header">
<h1>Form Test</h1>
<nav data-role="navbar">
<ul>
<li>
<a href="#homePageSection">Home</a>
</li>
<li class="formLineItem">
<a href="#" class="ui-btn-active ui-state-persist" >Form</a>
</li>
</ul>
</nav>
</div><!-- /header -->
<div data-role="content" class="container">
<form method="get" action="">
<div data-role="fieldcontain">
<!-- input field for toc search -->
<label id="searchLabel" for="searchInput"><strong>Search terms:</strong></label>
<input type="search" name="searchInput" id="searchInput" value="" />
</div>
<div style="text-align: left">
<fieldset id="valueCheckboxes" data-role="controlgroup" data-type="horizontal"></fieldset>
</div>
<div data-role="fieldcontain">
<a href="#" id="searchButton" data-role="button" data-inline="true">Search</a>
</div>
</form>
</div><!-- /content -->
<div data-role="footer"></div><!-- /footer -->
</section><!-- /formSection -->
</body>
</html>
You are including a mess of assets. You need to decide between jQuery Mobile 1.0.1 and 1.1.0 (currently you’re including 1.1.0 CSS and 1.0.1 JS).
For jQuery Mobile 1.1.0 your includes should look something like this:
And for jQuery Mobile 1.0.1 your includes should look something like this:
Since your code includes jQuery Mobile 1.0.1 it should be including jQuery Core 1.6.4.
I’m not convinced this will fix your problem. So make sure to check your JS console for any errors that occur. If you try to initialize a jQuery Mobile widget after it’s already been initialized, you will receive an error.