Skip to content Skip to sidebar Skip to footer

Do I Have To Create A New Panel For Every Page?

I would like to use a Panel in a jqm site for my Choose Language component. So that component will need to be present on every page. Here is the setup for a single-page panel. from

Solution 1:

Your best course of action is to dynamically create a panel for every page.

I made you a working example: http://jsfiddle.net/Gajotres/pZzrk/

$(document).on('pagebeforeshow', '[data-role="page"]', function(){                
    $('<div>').attr({'id':'mypanel','data-role':'panel'}).appendTo($(this));
    $('<a>').attr({'id':'test-btn','data-role':'button'}).html('Click me').appendTo('mypanel');
    $.mobile.activePage.find('#mypanel').panel();
    $(document).on('click', '#open-panel', function(){   
         $.mobile.activePage.find('#mypanel').panel("open");       
    });    
});

Few descriptions:

  • $.mobile.activePage is needed because we will have same panel in every page, and all of them will have same id. If we open it without active page we will open its first occurrence inside the DOM.

jQuery Mobile developers have stated that in next major version panel widget will no longer need to be part of a page, instead it will be placed in a same level as a page div. So one panel will ne needed. Unfortunately you will need to dynamically create it.

Solution 2:

Here's the solution I came up with. I store the panel contents in a hidden div, and defer the jquery mobile initialization. When the document loads, I append the panel contents to each of the (jqm) page elements and then initialize jqm. The only performance hit occurs when the page first loads.

HTML:

<divdata-role='page'class='page'><divdata-role='content'><h1>One</h1><ahref='#nav'data-role='button'>show nav</a></div></div><divdata-role='page'class='page'><divdata-role='content'><h1>Two</h1><ahref='#nav'data-role='button'>show nav</a></div></div><divid='panel-content'style='display:none'><divdata-role='panel'class='panel-holder'data-position="right"data-display="reveal"id='nav'><divdata-role="content"><ul><li><ahref="#first"data-link="first">first</a></li><li><ahref="#second"data-link="first">second</a></li></ul></div></div></div>

Script:

$.mobile.autoInitializePage = false;
$(document).on("ready"function(evt) {
    var panelHtml = $("#panel-content").html();
    var pages = $(".page");
    for (var i = 0; i < pages.length; i++)
    { //done synchronously so we can initialize jquery mobile after the DOM is all setup
       $(pages[i]).append(panelHtml);
    }

    $("#panel-content").remove(); // this doesn't need to be in the DOM anymore
    $.mobile.initializePage();
});

Solution 3:

I've been wrestling with this myself, and here's the solution I'm using:

$( ".page" ).on(
    "pageshow",
    function ( event, prevPage ) {
        var $page = $( this ),
            $prevPage = $( prevPage.prevPage ),
            $menuPanel = $( "#panel-menu", $prevPage );

        $menuPanel
            .remove()
            .prependTo( $page );

        $page.trigger( "create" );
    }
);

The trick seems to be to use .remove() instead of .detach() to pick up the panel you want to move - without any stored jQuery objects - so that jQuery Mobile doesn't make assumptions about the markup. Also, it strikes me that this solution adds considerable overhead from DOM manipulation. It's not ideal, but it does work.

EDIT: Note that it's set up to work for every page, and is fired on loading the first page, where you presumably have the menu to start with and where there is no previous page object. But you probably could keep the menu elsewhere and look for it there too as a fallback.

Solution 4:

with inspiration from Gajotres and the way AppFramework handles panels I've made this. It works by copying defined panels to the active page, the panels are defined by id in right-panel and left-panel attributes for the page div:

$(document).on('pagebeforeshow', '[data-role="page"]', function(){
    // remove unused tmp panels from DOM
    $("#tmpRightPanel").remove();
    $("#tmpLeftPanel").remove();

    // Hide buttons by default (I'm using a static header and footer on every page too)
    $("#openRightPanel").css("display", "none");
    $("#openLeftPanel").css("display", "none");

    // check if right-panel attribute is set on the pageif ($(this).attr("right-panel")) {
        // if it is, it should append the defined right-panel to the page
        $("#"+$(this).attr("right-panel")).clone().appendTo($(this));

        // rename it to tmpRightPanel
        $.mobile.activePage.find('#'+$(this).attr("right-panel")).attr("id", "tmpRightPanel");

        // make it a panel
        $.mobile.activePage.find('#tmpRightPanel').panel();

        // make it visible (the original right panel is set to display: none)
        $.mobile.activePage.find('#tmpRightPanel').css("display", "block");

        // make the button to open the panel visible
        $("#openRightPanel").css("display", "block");
    }

    // same as right-panel aboveif ($(this).attr("left-panel")) {
        $("#"+$(this).attr("left-panel")).clone().appendTo($(this));
        $.mobile.activePage.find('#'+$(this).attr("left-panel")).attr("id", "tmpLeftPanel");
        $.mobile.activePage.find('#tmpLeftPanel').panel();
        $.mobile.activePage.find('#tmpLeftPanel').css("display","block");
        $("#openLeftPanel").css("display", "block");
    }
});

// make the open panel buttons clickable
$(document).on('click', '#openRightPanel', function(){   
    $.mobile.activePage.find('#tmpRightPanel').panel("open");
});

$(document).on('click', '#openLeftPanel', function(){
    $.mobile.activePage.find('#tmpLeftPanel').panel("open");
});

Make a page like this:

<divid="main"data-role="page"data-title="Main"right-panel="right-panel"left-panel="left-panel"><divclass="ui-content">
              some page
         </div></div>

and place the panels somewhere outside a page, and hide them like this:

<!-- leftpanel --><divdata-role="panel"id="left-panel"data-display="push"data-position="left"data-theme="a"style="display:none;">
         something something something
    </div><!-- /leftpanel --><!-- rightpanel --><divdata-role="panel"id="right-panel"data-display="push"data-position="right"data-theme="a"style="display:none;">
         something something something
    </div><!-- /rightpanel -->

Solution 5:

Panel is a new concept introduced in 1.3. So lets hope more tutorials will show up soon. As of your problem, I guess its better you code a panel in each of your pages. You can make changes to your page real time but make sure to call following method as documented in the documentation.

$( "#mypanel" ).trigger( "updatelayout" );

I'm not sure other ways would be feasible.

Post a Comment for "Do I Have To Create A New Panel For Every Page?"