1. #1
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default Unpredictable behavior of Ext.History and back button on IE

    Unpredictable behavior of Ext.History and back button on IE


    Last 3 days I'm trying to fix the problem of Ext.History behavior on IE, but with no result. The case is following.
    We use Ext.History in the application to allow users for navigation across screens with browser buttons. The application is quite big and complicated, but history code is rather simple and is based on the code from Ext samples. We have a container that caches some panels, and the visible panel is swapped during history navigation. This works properly when you follow the links in the application: panels are swapped, the hash in URLs changes, the hidden iframe gets updated (I changed its style to make its content visible for debugging). When you press back button once, it reverts to previous state. But then if you try to press it second time, or try to press forward button, it doesn't work. The forward button is not enabled, which is strange (you just moved one step back, so you should be able to go one step forward from here - but you can't). Pressing back also doesn't work correctly: sometimes url gets refreshed, but hidden iframe content doesn't, and application is not updated. Generally application works completely unpredicable: your url hashes are no longer synchronized with application state, nor with iframe state.
    After lots of debugging, it seems to me that the IE bahavior is following: when you press back button, it moves back the iframe content to previous state. Ext timer discovers this change, so it calls the onchange listeners and updates the URL hash to synchronize it with new state. It seems that sometimes Internet Explorer spots this URL hash change and treats it as user navigation to the new history state (forward). Because of this, it disables the forward button (because it thinks you just clicked some link and moved forward with history, so you can't move forward anymore).
    During debugging, after pressing the back button I see both buttons (back and forward) enabled for a while, but then after updating the url hash by Ext.History code, the forward button gets disabled, and history gets broken.
    It's the same in IE6, IE7 and IE8 (in quirks mode).
    The strange thing is that Ext sample works correctly. My code is similar, and it doesn't work. The only difference is the amount of work which happens in history change listeners, and the size of application. What's more, it seems to me that if I simplify the handler code (e.g. just show some empty panel) it mostly (means usually, 90% of time) works. When I add more ogic, and the panels are complicated, it breaks (almost always).
    Has anybody observed similar behavior? What's the explanation of this behavior?

  2. #2
    Sencha - Architect Dev Team aconran's Avatar
    Join Date
    Mar 2007
    Posts
    9,240
    Vote Rating
    121
    aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold

      0  

    Default


    I haven't seen this type of behavior.

    Do you think you would be able to isolate this enough that you could create a testcase that we could troubleshoot?
    Aaron Conran
    @aconran
    Sencha Architect Development Team

  3. #3
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default


    I'll try, though it can be not that easy. I'll see what I can do.

  4. #4
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default


    Here is a test case, based on our code. I was able to reproduce the problem both on IE 7 and IE 8. Click all the links on the page one by one, and then press back button. The forward button usually doesn't work then.
    Code:
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title id='title'>Title</title>
     
            <!-- ** CSS ** -->
            <!-- base library -->
            <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
     
            <!-- overrides to base library -->
     
     
            <!-- ** Javascript ** -->
            <!-- base library -->
            <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../../ext-all-debug.js"></script>
     
     
            <!-- overrides to base library -->
     
            <!-- extensions -->
     
            <!-- page specific -->
     
            <script type="text/javascript">
            Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif';
     
    Ext.namespace('FN.COMMON');
    
    FN.COMMON.Templates = {
        menuListTpl: new Ext.XTemplate(
            '<ul id="baseTasks" >',
            '<tpl for=".">',
            '<li><img src="' + Ext.BLANK_IMAGE_URL + '" class="{cls}"/><a href="#{href}" class="navigation-link"><span id="{id}">{label}</span></a></li>',
            '</tpl>', '</ul>')
    };
    
    
    
    
    FN.COMMON.Util = {
        tokenDelimiter : ':' // Should be something that won't be in component ids.
    }
    
    
    
    
    
    //"buffered container"
    FN.COMMON.ContentContainer = Ext.extend(Ext.Container, {
        autoEl : 'div',
        layout : 'card',
        defaults : {
            frame : true
        },
        /**
         * How many panels should be cached
         */
        bufferSize : 4,
        swapToDefaultPanel : function() {
            this.swapPanel('A');
        },
        initComponent : function() {
            // private, instance-scoped variable: the queue which keeps the most recently used components
            var mruQueue = [];
            this.swapPanel = function(id) {
                //local reference which can be inspected with firebug
                //(I wasn't able to inspect directly mruQueue in firebug)
                var queue = mruQueue;
                var layout = this.getLayout();
                var component;
                if (this.items) {
                    component = this.getComponent(id);
                }
                if (component) {
                    layout.setActiveItem(id);
                    if (queue[0] !== id) {
                        queue.remove(id);
                        queue.unshift(id);
                    }
                } else {
                    component = Ext.ComponentMgr.create({xtype: "panel", id: id, title: id});
                    this.add(component);
                    layout.setActiveItem(id);
                    queue.unshift(id);
                    if (this.items.getCount() > this.bufferSize) {
                        var itemToRemove = queue.pop();
                        this.remove(itemToRemove);
                    }
                }
                document.title = component.title;
            };
            FN.COMMON.ContentContainer.superclass.initComponent.apply(this, arguments);
        }
    });
    
    Ext.reg('contentcontainer', FN.COMMON.ContentContainer);
    
    
    
    
    
    
    
    
    
    
    
    FN.COMMON.FNApp = function() {
    
        var getActionPanelItems = function() {
            var items = [{
                xtype : 'panel',
                frame : true,
                title : 'Menu',
                collapsible : true,
                html : FN.COMMON.Templates.menuListTpl.applyTemplate([{
                    id : 'timesheetsLink',
                    label : 'Item A',
                    href : 'A'
                },{
                    id : 'reportsLink',
                    label : 'Item B',
                    href : 'B'
                },{
                    id : 'reportsHolidayRequestLink',
                    label : 'Item C',
                    href : 'C'
                },{
                    id : 'changeLogLink',
                    label : 'Item D',
                    href : 'D'
                },{
                    id : 'currentActivityLink',
                    label : 'Item E',
                    href : 'E'
                },{
                    id : 'editUserLink',
                    label : 'Item F',
                    href : 'F'
                }]),
                titleCollapse : true
            }];
            return items;
        }
    
    
        var buildViewport = function() {
    
            new Ext.Viewport({
                layout : 'border',
                id : 'viewport',
                items : [
                {
                    region : 'west',
                    xtype : 'panel',
                    split : true,
                    width : 220,
                    id : 'action-panel',
                    collapsible : true,
                    collapseMode : 'mini',
                    border : false,
                    baseCls : 'x-plain',
                    items : getActionPanelItems()
                },{
                    xtype : 'contentcontainer',
                    region : 'center',
                    id : 'contentContainer',
                    ref : 'contentContainer'
                }]
            });
    
            selectContentPanel();
        };
    
        var selectContentPanel = function(token) {
            token = token ? token : Ext.History.getToken();
            // Restore the UI to the appropriate history state
            var parts, subparts, xtype;
            var contentContainer = Ext.getCmp('viewport').contentContainer;
            var layout = contentContainer.getLayout();
            if(token){
                parts = token.split(FN.COMMON.Util.tokenDelimiter);
                //TODO: handle invalid tokens (malformed URLs)
                xtype = parts[0];
                contentContainer.swapPanel(xtype);
                subparts = parts.slice(1);
            } else {
                //no token means user opened page without hash in url or
                //navigated back to the first page, where there is no hash in url
                contentContainer.swapToDefaultPanel();
            }
        };
    
        return {
            // public members
            init : function() {
                Ext.History.init();
                Ext.History.on('change', selectContentPanel);
                buildViewport();
            }
        };
    
    }();
    
    Ext.onReady(FN.COMMON.FNApp.init, FN.COMMON.FNApp);
    
            </script>
     
        </head>
        <body>
                <!-- Fields required for history management -->
            <form id="history-form" class="x-hidden">
                <input type="hidden" id="x-history-field" />
                <iframe id="x-history-frame"></iframe>
            </form>
        </body>
    </html>

  5. #5
    Ext User
    Join Date
    Jul 2009
    Posts
    25
    Vote Rating
    0
    Plasma is on a distinguished road

      0  

    Default


    I've just hit this problem myself, ExtJS 3.0.0

  6. #6
    Ext User
    Join Date
    Nov 2009
    Posts
    1
    Vote Rating
    0
    gallinari.marco is on a distinguished road

      0  

    Default


    I'm trying to add history to my application and I'm spotting this issue, too.

    In my implementation, History token change triggers an Ajax call which results are used to create a new viewport for each call, overwriting the previous viewport.

    In FF it all works fine, but in IE 8 (and in compatibility mode, too) history is almost always closed in a sort of loop. Pressing back button once takes me to the previous viewport correctly, but forward button doesn't enable, and pressing back button once again, the browser acts like stepping FORWARD in history; further, clicking on back button lead to a back-forward loop.

    Anyone got clues about that?

  7. #7
    Ext User
    Join Date
    Nov 2009
    Posts
    13
    Vote Rating
    0
    mrpip is on a distinguished road

      0  

    Default


    I've also just run into this bug in IE8 and Ext JS 3.0.0, has anyone made any progress with it?

  8. #8
    Ext JS Premium Member
    Join Date
    Mar 2010
    Location
    Switzerland
    Posts
    24
    Vote Rating
    6
    g.sidler is on a distinguished road

      0  

    Default See the same

    See the same


    I observe similar issues. I tried the example application at http://www.extjs.com/deploy/dev/exam...y/history.html. That works well in FF and IE7.
    Then, I more or less copied that example code to my application. In FF everything works fine. In IE7 the back and forward button behave very strangely. I registered a 'change' event handler with Ext.History. Then, when I press the browser's back button sometimes the change event handler is called and sometimes not. Most of the time I need to press the back button three times to get one change event triggered. Furthermore, after I move back several steps, I cannot move forward anymore. The forward history is gone and the forward button disabled.

    Another strange thing in IE7: Inside the Ext.onReady() function I tried to add a history record using the Ext.History.add() function. This call to the add() function is ignored in IE7. There is no error message but nothing happens to the history. Only after the user starts interacting with the application, e.g. by clicking somewhere, can I successfully add a history step.

    Really puzzling is that the example application works well but the same code inside my application doesn't work. Other people seem to have made the same experience. Maybe the functioning of the Ext.History class in IE depends on other aspects of the application? What could that be??

    Best regards, Gabe

  9. #9
    Sencha User
    Join Date
    Aug 2008
    Posts
    38
    Vote Rating
    0
    ts-gbtec is on a distinguished road

      0  

    Default


    Is there any progress on this topic? I've the same problem in my application now.

    Using ExtJS 3.2.2

  10. #10
    Sencha User
    Join Date
    Aug 2008
    Posts
    38
    Vote Rating
    0
    ts-gbtec is on a distinguished road

      0  

    Default


    I've to ask again because this one is really bothering me. Has anyone a hint how to get the history work with IE?