Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Mobile 1.3 Panel Not Working After Page Change

I seem to be having issues with programmatic opening and closing of a JQM 1.3 Panel.

EDIT: This is for JQM 1.3.x not 1.4+

It is somewhat hard to explain, so I just made a fiddle :)

There is a lot going on in the fiddle, but it is just a sample of a much larger app and conveys the issue.

How to replicate:

  1. Go to Fiddle
  2. On Fiddle open the Panel and go to Page Two
  3. On Page Two open Panel and go to Page One
  4. Try to Open the Panel now on page one, it does nothing.

Browsers Affected:

EDIT: This seems to be fixed in Chrome 30.0.1599.101 m

  • Chrome 28.0.1500.95 m
  • IE 10.0.9200.16635
  • Safari // Latest Ver
  • Android WebView (4.2.2)

Browsers NOT Affected:

  • Firefox 23
  • Opera 12.16

Link to Fiddle:

http://jsfiddle.net/q2YH3/

Link to Other Posts

https://github.com/jquery/jquery-mobile/issues/6308

http://forum.jquery.com/topic/panel-not-responding-after-page-change

EDIT: So Firefox gives me an error that neither Chrome or IE do.

When I click to go back to page one, I get:

Type Error: elem is undefined

The error is thrown by JQ 1.9.1, I trace it back to this:

A method for determining if a DOM node can handle the data expando
    acceptData: function( elem ) {
        // Do not set data on non-element because it will not be cleared (#8335).
        if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
            return false;
        }

        var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];

        // nodes accept data unless otherwise specified; rejection can be conditional
        return !noData || noData !== true && elem.getAttribute("classid") === noData;
    }
`

Note the :

Do not set data on non-element because it will not be cleared (#8335).

Github Issue Link: https://github.com/jquery/jquery/pull/1232

OG Code:

$('.showMenu').on('click', function(){
$.mobile.loading('hide');
$.mobile.activePage.find('#'+$.mobile.activePage.attr('id')+'P').panel("toggle");
});

$('.btnMenuItem').on('click', function(event){
myPgActions.nav(event, function(target){
    $.mobile.changePage(target);
}, false);
});   

var myPgActions = {};

myPgActions = {
nav: function(event, callback, manualHash){
    var PID = $.mobile.activePage.attr('id'),
    target = (!!event) ? event.target.name : manualHash;    
    $("#"+PID+"P").panel( "close" );
    if(PID != 'loading') $("#"+PID+"Iframe").hide();        

    if(PID == target){
        $("#"+PID+"Iframe").hide('fast', function(){
            $("#"+PID+"Iframe").attr('src', "");

            myPgActions.update(PID, target, 'refresh', function(target){
                callback(target)
            });
        }); 

    }else{

        this.update(PID, target, 'change', function(target){
            callback(target);
        });

    }

},// end get

update: function(PID, target, type, updateCallback){

    var ifReady = $.Deferred();

    if(type == 'refresh'){

        this.buildUrl(PID, function(url){

            $('#'+PID+'Iframe').attr( 'src', url);
            ifReady.resolve();          

            $.when(ifReady).then(function(){
                updateCallback('#'+PID+'Iframe')        
            });
        });

    }else if(type == 'change'){

        this.buildUrl(target, function(url){
            $('#'+target+'Iframe').attr( 'src', url);
            ifReady.resolve();
        });

        $.when(ifReady).then(function(){
            updateCallback('#'+target); 
        });
    }
}, // end set
buildUrl: function(page, buildCallback){
    switch(page){
        case 'dash':        
            var mobileSiteUrl = 'URL with options for iframe'
            setTimeout(function(){buildCallback(mobileSiteUrl);},25);
        break;
        case 'local':
            var mobileSiteUrl = 'URL with options for iframe'
            setTimeout(function(){buildCallback(mobileSiteUrl);},25);   
        break;


    }// End Switch
}
}// End Obj
like image 724
Red2678 Avatar asked Aug 06 '13 19:08

Red2678


2 Answers

Had the same problem, panel not showing after page changes.

Two small changes can fix that:

what I did was to change the panel from id="myPanel" to class="myPanel", then changed the call to the panel to open: $('.myPanel:visible').panel('open'); - that's it!

The problem is that the panel has to be inside of a jQuery "page", and after the transition, if you have the panel set in the target page, you actually have two (or more) panels with the same id which is wrong or same class which is fine. So you just change the id to a class and call the visible one.

Took me too long, Hope it saves time to someone else.

like image 128
RoyBS Avatar answered Oct 23 '22 08:10

RoyBS


I played around with your code a bit. I noticed that If I put an alert inside your update function, that it fixes everything. So I researched why an alert would make a program work, and found this page. http://ubuntuforums.org/archive/index.php/t-930002.html

"You should probably know that JavaScript evaluation is of the 'look ahead' type: the script already runs when it is still being evaluated (and while the page itself is still being evaluated). Now that is why it is recommended to dump all references to scripts in the section of your page, as it will cause the JavaScript to be fully evaluated before you (usually) can call a function (event handlers), and hence avoid silly 'undefined' errors.

Now the alert(); call has 2 effects: (1) it pops up the message box (so far, so good);.but (2) it halts the thread the JavaScript is using! However the browser's other threads will still continue to go on (HTML rendering...). So it may be one of those cases that you would benefit from a more elegant halting method, which is to only execute this (part of the) script when the document has been fully loaded;"

The solution they suggest is putting your script inside of the . Or using "stateChanged() function of the ajax http request".

like image 1
A.sharif Avatar answered Oct 23 '22 07:10

A.sharif