Is there a way to remove the current page (page being navigated away from) from the Jquery Mobile history? Setting changeHash:false seems to remove the incoming page from the history.
Here is an example:
Page 1
<div data-role="page">
<div data-id="fixedheader" data-role="header" data-position="fixed">
<h1>Page 1</h1>
</div>
<div data-role="content">
<button onclick="$.mobile.changePage('page2.html',{changeHash:false});">Page 2</button>
</div>
</div>
Page 2
<div data-role="page">
<div data-id="fixedheader" data-role="header" data-position="fixed">
<h1>Page 2</h1>
</div>
<div data-role="content">
<button onclick="$.mobile.changePage('page3.html',{changeHash:true});">Page 3</button>
</div>
</div>
Page 3
<div data-role="page">
<div data-id="fixedheader" data-role="header" data-position="fixed" data-add-back-btn="true">
<h1>Page 3</h1>
</div>
<div data-role="content"></div>
</div>
What I want is that when on Page 3, clicking the back button goes to Page 2 and that it is not possible to go back to Page 1.
What happens is that clicking from Page 1 to Page 2 to Page 3, on Page 3 the back button goes directly back to Page 1.
Also if I put data-add-back-btn="true" on Page 2, it shows a back button but clicking it does nothing.
Assuming you are using jQuery Mobile > 1.4, you can directly access and modify the history stack with $.mobile.navigate.history.stack
If you only want to remove Page 1 from the history when you navigate from Page 1 -> Page 2, the following code should solve your issue. This function assumes jQuery Mobile 1.4.3
$(document).on('pagecontainerchange', function(e, ui) {
if ( ui.prevPage.attr('id') === 'first' && ui.toPage.attr('id') === 'second' ) {
var index = $.mobile.navigate.history.stack.length - 2;
$.mobile.navigate.history.stack.splice(index, 1);
}
});
Here is a fiddle which logs the state of the history stack
Related
I'm a touch lost - I have taken a popup example from the jquery demo page as a template...
If I put my popup within the first page, it works - I can call it from within js script to open.
Thus... the following does work
<div data-role="page" class="page" id="Menu">
<div data-role="header" data-position="fixed" class="ui-title center">
<div data-role="controlgroup" data-type="horizontal">
<span class='htitle'>Barserver.com</span>
</div>
</div>
<div id="MainContent">
<div id="MenuList"></div>
</div>
<div data-role="popup" id="popup" data-overlay-theme="b" data-theme="b" data-dismissible="false" style="max-width:400px;">
<div data-role="header" data-theme="a">
<h1>Delete Page?</h1>
</div>
<div role="main" class="ui-content">
<h3 class="ui-title">Are you sure you want to delete this page?</h3>
<p>This action cannot be undone.</p>
Cancel
Delete
</div>
</div>
I can dynamically open it via
$("#popup").popup("open");
However if I move the popup to another (data-role) page within the same document, it does not get displayed, nor errors in console.log. Can anyone steer me forward? The following does NOT work...
<div data-role="page" class="page" id="OrderList">
<div data-role="header" data-position="fixed" class="ui-title text-center">
<div data-role="controlgroup" data-type="horizontal">
<span class='htitle'>Barserver.com</span>
</div>
</div>
<div id="OrderListContent" class="productdhtml ui-content"></div>
<div data-role="popup" id="popup" data-overlay-theme="b" data-theme="b" data-dismissible="false" style="max-width:400px;">
<div data-role="header" data-theme="a">
<h1>Delete Page?</h1>
</div>
<div role="main" class="ui-content">
<h3 class="ui-title">Are you sure you want to delete this page?</h3>
<p>This action cannot be undone.</p>
Cancel
Delete
</div>
</div>
</div>
To avoid misunderstanding - the first code sample works, the second one does not work (meaning no errors, no modal like dialog box gets displayed).
Why?
(All help appreciated of course)
I got it (thanks to #Omar for direction). A coded answer is not easy but I will try draft and share in a few days (I'm behind on my work because of trying to fix this problem).
For the purpose of this note, when I say "this failed" I mean "no popup, no change in address bar, no console error."
I have a form. If operator attempted to navigate away, a test should be done to confirm all data was entered. All my a-href tags had page references, and jquery gives precedence to a-href tags over any other events I had applied. I had not considered the ramifications of this. The result? Form displayed, incompletely filled, operator selects to navigate elsewhere, popup call starts/ends but "failed" and jquery quickly navigates to the page named in the a-href page.
Solution:
When using popups, do not name pages in a-href tags. Thus, when using popups, avoid
<a href='#Page5'>Page 5</a>
and instead
<a href='#' id='page5'>Page 5</a>
and create an event that decides if a popup should be displayed, or if not, that page5 should be navigated to.
I hope that makes sense.
I have a page called "top up",
top up /a
page home
When I am done with the page "top up" and I go back to the page "home".
I click on the page "top up" again but I still see the parameters I have filled in earlier
How do I reset the "top up" page to its empty state?
page home
<div data-role="page" id="home">
<div data-role="header" ></div>
<div data-role="content">
</div>
<div data-role="footer" ></div>
</div>
page top up:
<div data-role="page" id="topup">
<div data-role="header" ></div>
<div data-role="content">
<input type="text" name="test"/>
</div>
<div data-role="footer" ></div>
</div>
details:
jquery.mobile-1.4.0.min.js
jquery-2.1.0.min.js
jQuery Mobile 1.3.1 has a very nice sliding panel feature, but the panel code must be placed within the same page it's used on.
I'm working on an app that needs to have the same panel on many pages. Instead of replicating code is there a way to dynamically inject the panel into these pages so that it will still retain the jqm panel functionality?
jQuery Mobile >= 1.4
Solution one:
Use an External panel that can be accessed from any page, this is in case you want to have the same panel contents in all pages.
Append panel to $.mobile.pageContainer once only on pagebeforecreate and then enhance the panel using $(".selector").panel().
var panel = '<div data-role="panel" id="mypanel" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.prepend(panel);
$("#mypanel").panel();
});
Add button to open the panel in each header (or wherever you want).
Note: When using External Panel data-theme should be added to panel div, as it doesn't inherit any styles/theme.
Demo
Solution two:
If you wish to do changes to panel before appending it, based on number of pages in DOM, add panel to each one with a different ID and a button to open that panel.
Note that you don't need to call any kind of enhancement, because you're adding panels on pagebeforecreate. Hence, panels will be auto-initialized once page is created.
var p = 1,
b = 1;
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.find("[data-role=page]").each(function () {
var panel = '<div data-role="panel" id="mypanel' + p + '" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
$(this).prepend(panel);
p++;
});
$.mobile.pageContainer.find("[data-role=header]").each(function () {
var panelBtn = ''
$(this).append(panelBtn);
b++;
});
});
Demo
Note: Make sure you use .one() not .on(), if you use the latter, panels will be added whenever a page is created.
jQuery Mobile <= 1.3
You can do it this way, using pagebeforecreate event and by checking if there is no Panel added already. Keeping in mind that panels markup should always be placed before [data-role=header] that's why I used .before().
There is no need to call any enhancement method since panels are added on pagebeforecreate. They will be initialized during that event.
Demo
Your panel
var panel = '<div data-role="panel" id="mypanel" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
Add panels dynamically
$(document).on('pagebeforecreate', '[data-role=page]', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
});
Update
There are two alternative methods to inject "External Panel" dynamically.
For some one coming across this issue, there is something called External Panels in JQuery Mobile 1.4+, which can make our life easier.
http://demos.jquerymobile.com/1.4.0/panel-external/
You can do something like this.
<div data-role="panel" id="mainPanel">
<!-- .... -->
</div>
<div data-role="page" id="page1" >
<!-- .... -->
</div>
<div data-role="page" id="page2" >
<!-- .... -->
</div>
You can also do one thing create a panel at the end or start of all pages and open that by Id and script code mentioned below.....its working fine for me.
$(function(){
$("#navigation").enhanceWithin().panel();
});
<div data-role="page" id="page1">
<div data-role="main" class="ui-content ui-body-a ui-responsive">
<div data-role="header">
<div data-role="navbar">
<ul>
<li class="">
</li>
</li>
</ul>
</div>
</div>
</div>
</div>
<div data-role="page" id="page2">
<div data-role="main" class="ui-content ui-body-a ui-responsive">
<div data-role="header">
<div data-role="navbar">
<ul>
<li class="">
</li>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="ui-panel ui-panel-position-left ui-panel-display-reveal ui-body-b ui-panel-animate ui-panel-open" data-role="panel" id="navigation" data-position="left" data-display="overlay" data-theme="b" data-dismissible="true" data-swipe-close="true">
<div class="ui-panel-inner">
<ul class="">
</ul>
</div>
</div>
In order for hashcoder his response to work you need to initialize the external panel. Also add .enhanceWithin() to make listviews etc render properly within the panel.
Als add a data-rel=... attribute to the link via which you want to open the external panel.
<script>
$(function () {
$("div[data-role='panel']").panel().enhanceWithin();
});
</script>
<div data-role="panel" id="mainMenu">
<!-- .... -->
</div>
<div data-role="page" id="page1" >
Open main menu panel
<!-- .... -->
</div>
<div data-role="page" id="page2" >
Open main menu panel
<!-- .... -->
</div>
I'm using jQM popup to 'alert' users of something. For example, I make a $.ajax() request and if there's something wrong with the response I shoot a popup.
Something like this:
<div data-role="popup" id="popup">
<p id="popupMsg"></p>
</div>
$("#popupMsg").html(msg);
$("#popup").popup({
history:false,
overlayTheme: "a"
}).popup('open');
It all works fine, but If I change the popup to include a button, this way:
<div data-role="popup" id="popup">
<p id="popupMsg"></p>
Ok
</div>
Then the link is not styled, and it will just show an 'Ok' link.
If I move the popup to a dialog then it all works, button and all, but since I want the page underneath to be seen, I'd like to keep it a popup.
Am I missing something? I saw a lot of questions about popups/dialogs, but they all refer to clicking a button to show them.
I use jquery-1.8.2 and jquery.mobile-1.2.0.
Edit: the solution to my case is that the popup div must go inside the page div, and not outside of it (as a dialog div would), like this:
Before (wrong):
<div data-role="page">
<div data-role="content">
...page stuff...
</div>
</div>
<div data-role="popup" id="popup">
<p id="popupMsg"></p>
Ok
</div>
After (right):
<div data-role="page">
<div data-role="content">
...page stuff...
<div data-role="popup" id="popup">
<p id="popupMsg"></p>
Ok
</div>
</div>
</div>
You need to refresh the jQM markup
http://jsfiddle.net/xvvCA/1/
http://jsfiddle.net/xvvCA/ ( inline button )
JS
var msg = 'Look! A new button!';
$("#popupMsg").html(msg);
$("#popup").popup({
history:false,
overlayTheme: "a"
}).popup('open');
$('#okButton').button('refresh'); // you need to refresh jQM markup
HTML
<div data-role="page">
<div data-role="content">
<div data-role="popup" id="popup">
<p id="popupMsg"></p>
Ok
</div>
</div>
</div>
Please help,
jquery mobile multipage wont work when a page is called from another page. It only displays the buttons but doesnt navigate to its internal pages when clicked. It works fine when the page is access directly.
<!-- Page 1-->
<div data-role="page" id="description" data-title="Description">
<div data-role="header" data-position="fixed" data-theme="d">
<!-- header 1-->`enter code here`
</div>
</div>
<div data-role="content">
<!--- content 1-->
</div>
<div data-role="footer" data-position="fixed" data-theme="d">
<div data-role="navbar" data-iconpos="bottom">
<ul>
<li>Description</li>
<li>Physicians</li>
</ul>
</div>
</div>
</div>
<!-- Page 2-->
<div id="Physicians" data-role="page" data-title="Physicians">
<div data-role="header" data-position="fixed" data-theme="d">
<!-- header 2 -->
</div>
<div data-role="content">
<!-- content 2 -->
</div>
<div data-role="footer" data-position="fixed" data-theme="d">
<div data-role="navbar" data-iconpos="bottom">
<ul>
<li>Description</li>
<li>Physicians</li>
</ul>
</div>
</div>
</div>
Try adding to the anchor the attribute rel="external".
Example:
Description
try giving <div data-role="page" first for your second page
When you call this page from another page, it ONLY loads the div[data-role="page"] of that page, not the other div in this multi-page file!
Actually to be precise, when you link to a page from another page, ONLY the code inside the div you are targeting is pulled in via AJAX, even if you had JS in the <head> that won't get loaded either.
Try linking to this page with an external link and you'll find it works fine.