Reputation: 541
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?
Upvotes: 10
Views: 18081
Reputation: 4572
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="">
<a href="#navigation" id="navi_toggle" class="ui-btn ui-corner-all ui-icon-grid ui-btn-icon-notext"></a>
</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="">
<a href="#navigation" id="navi_toggle" class="ui-btn ui-corner-all ui-icon-grid ui-btn-icon-notext"></a>
</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">
<a href="#demo-links" data-rel="close" class="ui-btn ui-corner-all ui-icon-delete ui-btn-icon-notext" id="navi_ref"></a>
<ul class="">
</ul>
</div>
</div>
Upvotes: 3
Reputation: 2091
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" >
<a href="#mainMenu" data-rel="main-menu-panel">Open main menu panel</a>
<!-- .... -->
</div>
<div data-role="page" id="page2" >
<a href="#mainMenu" data-rel="main-menu-panel">Open main menu panel</a>
<!-- .... -->
</div>
Upvotes: 0
Reputation: 31732
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).
<a href="#mypanel" class="ui-btn ui-btn-right ui-btn-icon-notext ui-icon-grid ui-corner-all"></a>
Note: When using External Panel data-theme
should be added to panel div, as it doesn't inherit any styles/theme.
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 = '<a href="#mypanel' + b + '" class="ui-btn ui-btn-right ui-btn-icon-notext ui-icon-grid ui-corner-all"></a>'
$(this).append(panelBtn);
b++;
});
});
Note: Make sure you use .one()
not .on()
, if you use the latter, panels will be added whenever a page is created.
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.
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);
}
});
There are two alternative methods to inject "External Panel" dynamically.
Upvotes: 28
Reputation: 520
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>
Upvotes: 4