So I'm fairly new to AJAX, I have a simple 3 page project which I am using AJAX to transition between pages.
I have an index.html page which loads all the html / body / scripts etc:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax practice</title>
<link rel="stylesheet" href="styles/index.processed.css">
</head>
<body>
<div class="" id="wrapper">
<div class="overlay"></div>
<header>
<nav>
<ul>
<li><a class="aboutBtn" href="main.html">Home</a></li>
<li><a class="aboutBtn" href="about.html">About</a></li>
<li><a class="aboutBtn" href="#">Menu</a></li>
<li><a class="aboutBtn" href="#">Contact</a></li>
</ul>
</nav>
</header>
<div class="page wrapper" id="page">
<div class="circle" id="black"></div>
<div class="circle" id="red"></div>
<div class="circle" id="blue"></div>
<section class="mainSplash main">
<div class="mainSplash__content" id="content">
</div>
</section>
</div> <!-- page -->
</div> <!-- wrapper -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="scripts/index.js"></script>
</body>
</html>
and my 2 pages are:
main.html:
<h1 class="mainSplash__header--h1">Main</h1>
about.html:
<h1 class="mainSplash__header--h1">About</h1>
Here is the AJAX which transitions the pages:
$(document).ready(function() {
var pathname = window.location.pathname; // Returns path only
console.log(pathname);
// $('.mainSplash').css('height',$(window).height() - 60);
$(".aboutBtn").click(function(e) {
e.preventDefault();
var pageTitle = $(this).text();
var pageUrl = $(this).attr('href');
changePage(pageUrl, true, pageTitle);
}); // click
function changePage(url, bool, pageTitle){
$('#page').addClass('fadeOut');
loadContent(url, bool, pageTitle);
}
function loadContent(url, bool, pageTitle){
$.ajax({
url: './' + url,
type: 'get',
contentType: 'html',
success: function(data){
$('#page').one('animationend',
function(e) {
// load content
$('#page').removeClass('fadeOut');
$('#page').addClass('fadeIn');
$('#content').html(data);
//$("html").html(data);
// Change url
if(url != window.location){
window.history.pushState({path: url}, pageTitle, url);
}
});
}
});
}
function removeAnimation(){
$('#page').removeClass('animate');
}
});
So my transitions work fine when I have come from index.html, though when I refresh main.html or about.html, they do not keep the code from index.html (obviously).
My question is:
How do I handle a refresh or back button from my pages without losing the index.html content? Any help or advice is appreciated - thank you in advance.
PS: If anyone knows of any AJAX html page transition examples I would love to know so I can improve my code, as I'm looking for best practice for AJAX transitions!
multi way available to do this but best way is use hash routing. see this plugin 'Routei '.set param in hash route then and get it when click on back button and handel ajax whit this param.
I would suggest using the browser page hash and on navigation check for the given hash and load the corresponding page.
let hash = window.location.hash;
When the hash changes, your browser adds a new history for that page.
On the load of the Site you need to add entry in the history with the command history.pushState and to go back to use the buttons of the browser you will need the EventListener onpopstate
Related
I have a Flask setup serving a template. The data for this can be nicely split across a few different "sets" which can all be rendered with the same template. I have inserted Bootstrap tabs which I would like to handle displaying the data for each separate set. The data my be non-existent or incomplete initially, but will be filled in over time. The hope is that when the user clicks a new Bootstrap tab, it triggers a request for Flask to return the most recent data pertaining to whichever tab was selected.
I have boiled it down to the small example below. I can successfully generate the Flask request when the tab is changed, but the result isn't triggering a new rendering of the template.
Flask route:
#app.route('/test_route', methods=['GET'])
def get_simple():
set_number_str = request.args.get('set', "mydata-1", type=str)
set_number = int(set_number_str.split('-')[-1])
ready = bool(random.getrandbits(1))
if ready:
# get_data_for_set(set_number)
return render_template('simple_template.html',valid=1, data_set=set_number, data_points=[1,2,3])
else:
return render_template('simple_template.html', valid=0, data_set=set_number, data_points=[0, 0, 0])
Html:
<html>
<head>
<link href="{{url_for('static', filename='js/bootstrap-3.3.7-dist/css/bootstrap.min.css')}}" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="{{url_for('static', filename='js/jquery-3.3.1.min.js')}}"></script>
<script type="text/javascript" src="{{url_for('static', filename='js/bootstrap-3.3.7-dist/js/bootstrap.min.js')}}"></script>
</head>
<body>
<div class="my-tabs">
<ul class="nav nav-tabs" id="set-tabs">
<li class="active" id="data-1">
Set 1
</li>
<li class="" id="data-2">
Set 2
</li>
</ul>
<div id="my-tab-content" class="tab-content">
<div class="tab-pane" id="mydata-1">
<p>Placeholder 1</p>
</div>
<div class="tab-pane" id="mydata-2">
<p>Placeholder 2</p>
</div>
</div>
</div>
<script type="text/javascript">
if ({{valid}} == 0) {
$('#mydata'+'{{data_set}}').html("Waiting on scenario to start...");
} else {
$('#mydata'+'{{data_set}}').html("Have some data: " + "{{data_points}}");
}
</script>
<script type="text/javascript">
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var set_id = $(e.target).attr("href");
$.ajax({
url: "/test_route",
type: "get",
data: {set: set_id},
success: function(response) {
$('#mydata-'+set_id).replaceWith(response);
},
error: function(xhr) {
console.log(xhr)
}
});
return false;
});
</script>
When I run, the only thing I see is the "Placeholder _" text.
Is this a limitation of Flask/Jinja2 templating or something I'm doing wrong? If it's the former, do you have any alternative approaches you would recommend? My key constraint is needing to re-retrieve the data from the server each time as it will change.
I am building an e-commerce site. Right now it's basically one HTML page that filters in based on page loads and clicks. I did it this because the entire site needed to be dynamic, as I'll be tying in a show shortly.
Everything seems to work fine now that I have placed the script on the actual pages instead of in a main .js file. I get a few hiccups here and there, and I'm hoping this issue will help fix some of them.
Sometimes when I click on the view cart button it throws back a type error saying that $a.mobile.document.on is not a function. This doesn't happen all the time. I can just click the button with the shopping cart open and the cart just refreshes. As I am clicking the button, nothing in the code should be changing, everything should be flowing the exact same. Why do I get the error sometimes? There is no pattern as to how often the error occurs (i.e. every 3rd click, etc...)
My code:
<head>
<meta charset="UTF-8"/>
<title>DATique</title>
<link rel="stylesheet" href="styles.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="lib/jqm-icon-pack-fa.css">
<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 id="container" data-role="page" data-theme="b">
<div id="header" data-role="header">
<div id="headerGraphic"><img class="menu" src="img/products/DATique.png" alt="" align=center></div>
<!-- todo add tagline back in -->
<div data-role="footer" id="headerTagLine">an adult novelty company</div>
</div>
<div id="mainNavBar">
<div id="mainNav" data-role="navbar">
<ul>
<li class="home ui-icon-home">Home</li>
<li class="about ui-icon-question-circle">About</li>
<li class="contact ui-icon-envelope">Contact</li>
<li class="request ui-icon-lightbulb-o">Requests</li>
<li class="find ui-icon-location-arrow">Find</li>
</ul>
</div>
</div>
<div id="content" data-role="main">
<!-- todo add facebook plugin -->
<div id="sideBar">
<div id="sideNav">
<script>
</script>
</div>
</div>
<div id="productWindow">
<script>
</script>
</div>
</div>
<div data-role="footer" id="footer">
<ul>
<li id="addingItem"></li>
<li id="cartHolder">
<div class="view">View Cart</div>
<div class="cartImg"><img src="lib/png/shopping-cart.png"></div>
<div class="badge ui-corner-all"></div>
</li>
</ul>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var initialLoad = $.post('lib/aboutUs.php');
initialLoad.done(function (data) {
$('#productWindow').html(data);
});
var sideBar = $.post('lib/sideNav.php');
sideBar.done(function (data) {
$('#sideNav').html(data);
});
$('#cartHolder').unbind().click(function (data) {
var url = 'lib/cart.php';
var getCart = $.post(url);
console.log(data);
getCart.done(function (data) {
$('#content').html(data);
});
getCart.fail(function (data) {
console.log(data);
});
});
})
</script>
</body>
Here's my cart.php. The only file affected by the click event is the show cart button.
<link rel="stylesheet"
href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<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>
<?php
session_start();
#$_SESSION = array();
$items = $_SESSION;
echo "<div id='showCart' class='ui-corner-all' style='max-width:400px;'>
<div data-role='header' data-theme='a' class='ui-corner-all' style='margin-top:20px;'>
<h1>Your Cart</h1>
</div>
<div role='main' class='ui-content ui-corner-all'>
<ul data-role='listview' data-split-icon='delete' data-split-theme='d'>";
foreach ($items['cart'] as $list) {
echo "<li ><a href='#'>
<img src = 'img/products/" . $list['itemNum'] . ".png'>
<h3 > " . $list['itemName'] . " </h3 >
<h1 style='text-align:right'> " . $list['price'] . "
</h1 ></a>
<a href='#' class='removeItem' name='" . $list['itemNum'] . "'>Remove Item</a>
</li >";
}
echo "</ul>
</div>
</div>"
?>
<script>
$(document).ready(function() {
console.log ("error ready");
function showCart() {
console.log("showCart Function");
var url = 'lib/cart.php';
var getCart = $.post(url);
getCart.done(function (data) {
console.log("cart received");
$('#content').html(data);
});
}
$('.removeItem').unbind().click(function () {
console.log("remove clicked");
var itemNum = {'itemNum': ($(this).attr('name'))};
var sent = $.post("lib/removeFromCart.php", itemNum);
sent.done(function () {
console.log("item removed from cart");
showCart();
});
});
});
</script>
I also have 2 other pages that have script on them that are loaded onto the home page by $.post.
Sorry if this question is easy, I just hope it isn't a period or brace somewhere. It's almost always a period or a brace. Again, looking to see if someone can tell me why this sometimes throws an error when I hit the view cart button. It seems to be doing it right after the console.log call in the cart.php.
Just a note not an answer
i had all my javascript in a myScript.js file that loaded at the bottom of the html of the main page. but none of the other pages with scipts would read the javascript on the main page for some reason until i loaded the .js file into each page.
$(document).ready(function() {
code 1
....});
$(document).ready(function() {
code 2
....});
code 1 is not able to access code 2 and vice versa, in php this is akin to this
function one(){
code 1
}
function too(){
code 2
}
One way around that is to globalize stuff, by using window. although it's not usually recommended.
var one;
var window.one;
for example( scope resolution ). Other ways involve using the DOM, by attaching to a object on the page, such as how a plugin works. for example using $(element).data('mydata', {foo:'bar'});
not sure if this was what you were saying but the explanation is way to long for a comment.
Ok I'm reposting this from the start. I'm just so frustrated with this I'm about to just give up on JQM all together. This shouldn't be this hard.
My site structure:
OUI/
index.php
js/
pages/
images/
On my index.php page I have just a two line form for login I'm at http://localhost/~me/OUI/:
<? session_start();
?><!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=false,initial-scale=1;">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="js/jquery.mobile-1.4.0.min.css">
<link rel="stylesheet" type="text/css" href="css/jqm-datebox.min.css" />
<script src="js/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="js/jquery.mobile-1.4.0.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/jqm-datebox.comp.datebox.min.js"></script>
<script src="js/mainsite.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/main.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>OUI CHEF</title>
</head>
<body style="background-image:url(media/kitchen.jpg)">
<div data-role="page" id="loginarea">
<div data-role="content" id="maincontentarea2">
<img src="media/OUIChef.png" style="margin-top:75px" id="mainimage">
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" style="text-align:center" placeholder="Username"/><BR>
<label for="username">Password:</label>
<input type="password" name="password" id="password" value="" style="text-align:center" placeholder="Password"/>
</div>
<div style="text-align:center">
DO LOGIN
</div>
</div><!-- /page -->
</div>
</body>
</html>
So when I hit the login button it take me to my options.php page vi the following function:
function doLogin(){
$.ajax({
type: "POST",
url: "functions/checklogin.php",
data: {
usrnm: $('#username').val() , passwd: $('#password').val()
}
})
.done(function( msg ) {
if(msg.match(/YES/)){
$('#username').val('');
$('#password').val('');
$("body").pagecontainer("change","pages/options.php",{ });
}
else
{
alert(msg);
}
});
}
In the URL bar I now have http://localhost/~me/OUI/pages/options.php and everhthing in the page is working well. I have the signout button. in the code which calls
OPTIONS.PHP:
<div data-role="page" id="optionspage">
<div data-role="header">
Sign Out
<h1>MAIN</h1>
</div>
<div data-role="content" id="options1">
<? if($_SESSION['role']=='A'){?>
ADMIN PAGE
ORDER SETUP PAGE
<? } ?>
PRODUCTION
MENU / RECIPE PAGE
</div><!-- /content -->
</div>
this calls the JS:
function doSignout(){
$.ajax({
type: "POST",
url: "../functions/signout.php",
data: { }
})
.done(function( msg ) {
$('body').pagecontainer( "change", "#loginarea",{});
});
}
I can never get the link to the signout page to link correctly. If I put the double dots which should be correct from the "pages" folder I get it trying to link to
http://localhost/~me/functions/signout.php
and if I remove the double dots I get
http://localhost/~me/OUI/pages/functions/signout.php
both which are 404 errors.......this is BUNK in my book. the ".." is actually removing two directories..not just one.
What is happening? PLease help
As we don't see you log-in function, I'm assuming it looks something like the following?
$.ajax({
type: "POST",
url: "../functions/signin.php",
data: {}
})
If that is the case how does "../functions/signin.php" find it's mark when you are residing at /OUI/ initially — surely it would need to be "functions/signin.php" when you are on your home page.
Simply put I'm guessing your sign-in code is different on the homepage initially, and then after loading subsequent pages via ajax your sign-in code is getting overwritten or modified with code that is designed to work with a "../" prefix on deeper pages... and this isn't getting rectified when you switch back to the home page.
Basically you need to rewrite your code to detect how many folders deep the current URL is at and request your ajax files accordingly... either that or set one global variable (that is easily updatable) that keeps a full domain path to prefix all ajax urls with. i.e.:
var ROOT_URL = 'http://localhost/OUI/';
Depending on what you want to use this path can be generated by either PHP or JavaScript, PHP is more reliable — as in the end user does not require JavaScript — but it can be confused when hosted behind proxies and shared hosts.
var ROOT_URL = 'http://<?php echo $_SERVER["HTTP_HOST"]; ?>/OUI/';
var ROOT_URL = 'http://' + window.location.host + '/OUI/';
I'm new to Jquery Mobile and I've tried everything to solve this issue. I have the first page which is index.php, this page loads buttons from a js that gets the information from json.
The second page (FichaTecnica.php) shows the information of that wine (everithing is in spanish, sorry). The problem is that I have to refresh the page in the browser to load the information and if I go back to the first page I also have to refresh to load the buttons.
Any help would be appreciated.
Thanks.
Index.php
<div data-role="page" id="main">
<div data-role="header">
<h1>
Page 1
</h1>
</div>
<div data-role="content">
<div>
<img src="images/Vinos separador [Negro].png" />
</div>
<div data-role="controlgroup" data-role="controlgroup" id="buttonGroup">
</div>
<div>
<img src="images/P Venta Separador [Negro].png" />
</div>
<div data-role="controlgroup" data-role="controlgroup" id="buttonGrouploc">
</div>
</div>
<div data-role="footer">
</div>
</div>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script src="js/variedadeslist.js"></script>
Js File that loads the buttons in first page
var url="http://localhost/CavaOnline/json_variedades.php";
var buttonHtmlString = "", pageHtmlString = "";
var jsonResults;
$.getJSON(url,function(data){
jsonResults = data.items;
displayResults();
});
function displayResults() {
for (i = 0; i < jsonResults.length; i++) {
buttonHtmlString += '<a data-transition="slide" href="FichaTecnica.php?id=' + jsonResults[i].id + '" id="'+ jsonResults[i].id +'" data-role="button">' + jsonResults[i].nombre + '</a>';
}
$("#buttonGroup").append(buttonHtmlString);
$("#buttonGroup a").button();
}
Second Page "FichaTecnica.php"
<div data-role="page" id="pagina2">
<div data-role="header">
<h1>
Header
</h1>
</div>
<div data-role="content">
<div>
<div data-role="collapsible" data-collapsed="false">
<h1>El Vino</h1>
<div id="descripcion">
</div>
</div>
<div data-role="collapsible" data-collapsed="false">
<h1>Cata</h1>
<div id="cata">
</div>
</div>
</div>
<a data-role="button" id="botonMarcas"></a>
</div>
<div data-role="footer">
<h1>
footer
</h1>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script src="js/descripcionlist.js"></script>
Js that loads the information in the second page
$('#pagina2').live('pageinit',function(event){
var id = getUrlVars()["id"];
$.getJSON('http://localhost/CavaOnline/json_variedades.php?id='+id, function(variedades) {
$.each(variedades, function(index, variedad) {
$('#descripcion').append('<p>'+variedad[id - 1].descripcion+'</p>');
$('#cata').append('<p>'+variedad[id - 1].cata+'</p>');
$('#botonMarcas').append().attr("href", 'FichaTecnica.php?id=' + variedad[id - 1].id);
});
});
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
It would be better to have your pageinit code wired up before you bring in the page. Therefore, make sure you include the JS as part of your first page.
Wire up the paginit, like so:
$(document).on('pageinit', '#pagina2', function(e) {
/* TODO: Page 2 init code */
});
Your initial page is not loading correctly because you're building the page incorrectly (by including the JS at the bottom after the other elements load). Therefore, the JavaScript only takes effect after the page is refreshed since at that point the JS already exists in the DOM.
Here's the basic page markup:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0-rc.2/jquery.mobile-1.2.0-rc.2.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.2.0-rc.2/jquery.mobile-1.2.0-rc.2.min.js"></script>
</head>
<body>
...content goes here...
</body>
</html>
Also, if you're including any custom JS that will alter the page (like your pageint) they should be loaded AFTER jQuery is loaded, but BEFORE jQuery Mobile is loaded (so insert that JS file between the two in the head).
I've had similar problems and just fixed them by adding data-ajax=false in the link.
ref: http://api.jquerymobile.com/pagecontainer/
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">
Form
</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>
Home
</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">
Form
</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>
Home
</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">
Search
</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:
<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.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
And for jQuery Mobile 1.0.1 your includes should look something like this:
<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>
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.