How to create External Panels in jQuery mobile? - jquery-mobile

I am trying to create a multi page application and am using JQuery mobile, I have couple of Panels using jQuery mobile:
<div data-role="panel" id="left-panel" data-theme="b" data-display="overlay"></div>
<div data-role="panel" id="right-panel" data-display="overlay" data-position="right" data-theme="b"></div>
However, It would be cumbersome to add these panels to every page I create.
So I need help in using these panels in all the pages I'm about to create.
Thanks in advance!

This script worked for me
$(document).on("pagecreate", ".demo-page", function() {
var panell = '<div data-role="panel" id="left-panel" data-position="left" data-display="reveal" data-theme="a"><ul data-role="listview" data-inset="true"><li>Home</li><li>About</li><li>News</li></ul></div>';
$.mobile.pageContainer.prepend(panell);
$("#left-panel").panel().enhanceWithin();
var panelr = '<div data-role="panel" id="right-panel" data-position="right" data-display="reveal" data-theme="a"><ul data-role="listview" data-inset="true"><li>Home</li><li>About</li><li>News</li></ul></div>';
$.mobile.pageContainer.prepend(panelr);
$("#right-panel").panel().enhanceWithin();
});

Related

Jquery Mobile Panel hides flexslider when opened

I am trying to use jquery mobile panels and it hides the slider when I open the panel, it removes/hides the slider. Adding rel="external" to the button for panel doesn't do anything as it is not a link to physical page.
Here is an example given in fiddle:
http://jsfiddle.net/dhavaljani/zZKhT/
Html for panel
<div data-role="panel" id="rightpanel2" data-position="right" data-display="push" data-theme="d" data-content-theme="d">`
<ul data-role="listview" data-theme="d" data-icon="false">
<li>Home</li>
<li>Services</li>
<li>Case Studies</li>
<li>About Us</li>
<li>Contact Us</li>
</ul>
123-456-7890
</div>
This is a bug in jQuery Mobile 1.4, as panel when first opened, it wraps it's siblings in a <div class="ui-panel-wrapper"> other than header and footer.
This problem isn't present in previous versions of jQuery Mobile.
<section class="slider ui-panel-wrapper">
<!-- elements -->
</section>
Demo

Use external panel from dynamically injected page

A new thing in version 1.4.0 alpha 2 of jQuery-Mobile is that panels no longer have to be inside the page that uses them. Instead, external panels can be siblings to the pages.
This works fine with static pages:
<div id="panel" data-role="panel" data-theme="b" data-position="left"
data-display="push">
<h3>This is a panel</h3>
</div>
<div data-role="page" id="staticPage">
<div data-role="header" data-position="fixed">
Panel
<h1>Static page</h1>
</div>
<div data-role="content">
<div class="content-primary">
Go to dynamic page
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#panel').panel();
});
</script>
However, when I generate and inject a page dynamically, the link to the panel no longer works as it is supposed to:
<script type="text/x-template" id="dynamicPageTemplate">
<div data-role="page" id="staticPage">
<div data-role="header" data-position="fixed">
Panel
<h1>Dynamic page</h1>
</div>
<div data-role="content">
<div class="content-primary">
<a href="#staticPage" data-role="button" data-inline="true">
Go to static page
</a>
</div>
</div>
</div>
</script>
<script type="text/javascript">
$(document).bind("pagebeforechange", function (e, data) {
if (typeof data.toPage === "string") {
var url = $.mobile.path.parseUrl(data.toPage);
if (url.hash.search(/^#dynamicPage$/) !== -1) {
$('#dynamicPage').remove();
var template = $("#dynamicPageTemplate").html();
var $page = $(template);
$page.attr('id', 'dynamicPage');
$('body').append($page);
$page.page();
$.mobile.changePage($page, {changeHash: false});
e.preventDefault();
}
}
});
</script>
When I click the "Panel" button in header of the dynamic page, the URL changes to …#panel and nothing is shown. I suspect that jQuery-Mobile tries to show the panel as a page rather than a panel. Am I doing something wrong, or is this a bug?
Fiddle with complete example
jQuery Mobile 1.4 panel (and a lot of other widgets) implementation still don't work correctly. Several new components are not even implemented yet. Not to mention, demo site was not updated since they announced alpha version 1.
Let me get back to pane implementation. It is still under heavy development. Any panel inner content (except buttons) is not properly styled. Just add a listview and see a final result.
Only thing you can do is wait for RC1 versions, or maybe just maybe first beta version (but I wouldn't hold my breath for the beta release).

Jquery Mobile panel dynamic listview does not render correctly

I have a searchresults.php page which shows several users that have been found. Also on the searchresults.php page is a panel
<div data-role="panel" id="mypanel" data-display="overlay" data-theme="a">
<div id="loadedprofile">
</div>
</div><!-- /panel -->
When I click on one of the "user divs" the following Jquery function fires to open the panel:
a panel on select of a search result.
The JQuery code:
$('[id=profile]').on("click", function(e) {
e.preventDefault();
var userid = $(this).attr('userid');
//window.location.href = "userdetails.php?userid=" + userid;
$("#mypanel").panel("open");
$("#loadedprofile").load("userdetailspanel.php?userid=" + userid);
$("#mypanel").trigger("updatelayout");
$('#commandlist').listview('refresh');
$('[data-role=page]').trigger('pagecreate');
$.mobile.activePage.trigger('pagecreate');
$('#commandlist').listview().listview('refresh');
});
Ok, so the panel opens up correctly and the dynamic page (userdetailspanel.php) is loaded correctly (see image). But ALSO on the userdetailspanel.php is a listview.
<ul data-role="listview" data-inset="true" id="commandlist">
<li>
<a href="#" id="mylink" name="mylink" >
<img src='bolt.png' class="ui-li-icon" />Link
</a>
</li>
</ul>
This listview is not rendered correctly. I just see blue hyperlinks.
After appending items dynamically into panel, call .trigger('pagecreate');
$('[data-role=page]').trigger('pagecreate');
or
$.mobile.activePage.trigger('pagecreate');
Demo - jQM 1.3.2 and below
For jQuery Mobile v 1.4, it is different
$('.target').trigger('create')
Demo - jQM v 1.4 Aplha
OK so the trick was to add the refresh at the bottom of the userdetailspanel part.
So, after the UL, add:
<script type="text/javascript">
$('#commandlist').listview().listview('refresh');
</script>

How to inject the same panel into multiple pages using jquery mobile

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>

How to get alert to only appear once in jQuery Mobile multiple page html

I have a multipage html (using "div data-role="page") that displays 4 pages of a document that can be swiped left or right to move between the pages back and forth.
I have an alert that I want to pop-up only when the page first loads (telling the user they can swipe to move back and forth between pages).
My problem is that it keeps popping up again every time a swipe to a new page is made and I only want it to alert them once when the page loads.
I've tried moving the script from the head to inside the element, and I've tried binding it to all the different pagecreate, pagebeforecreate, pageinit, etc. events and can't seem to figure it out.
I appreciate any advice or direction.
Here's the alert code that is currently showing on every page when swiped:
<script type="text/javascript">
$('div').live("pagecreate",function(event){
alert('Swipe left and right to move between the 5 pages of this lead sheet');
});
</script>
You can bind to the id for the page DIV (ex: div#home).
<script type="text/javascript">
$('div#home').live("pagecreate", function (event) {
alert('Swipe left and right to move between the 5 pages of this lead sheet');
});
</script>
...
<div data-role="page" id="home">
Live Example:
http://jsfiddle.net/FcjNR/1/
JS
var $alerted = false;
$('div').live('pageshow',function(event, ui) {
// Check for secure token here
if($alerted == false) {
$alerted = true;
alert('Can you see me now?');
}
});
HTML
<div data-role="page" id="home">
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="f">
<li data-role="list-divider">Alert once</li>
<li>Alert Page</li>
</ul>
</div>
</div>
<div data-role="page" id="alert">
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="f">
<li data-role="list-divider">The Alert</li>
<li>Home</li>
</ul>
</div>
</div>

Resources