Tom
Tom

Reputation: 16256

ExtJs 4.2 Swap Style Sheet doesn't work correctly for me

Here is the part of my code related to theme changing.

in my javascript file:

loadTheme: function (theme) {
    document.getElementById('extjs-theme-css').href = "css/ext-all" + (theme == '' ? '' : '-') + theme + ".css";
    //OR (tried both ways, same issue)
    Ext.util.CSS.swapStyleSheet('extjs-theme-css', "css/ext-all" + (theme=='' ? '' : '-') + theme + ".css");
},

and in html file:

<link rel="stylesheet" type="text/css" href="js/extjs/v4.2/resources/css/ext-all-notheme.css" id="extjs-theme-css" />

When I first load up the web, all the windows and panels styles and positions are messed up. After a browser refresh OR a mouse drag component resize, the styles and positions become correct again. (see pictures for what I mean). It happens every time I change a theme.

Same for IE, FF or Chrome. Tried on Default, Gray, Access, Neptune themes.

first time (messed up, notice panel shifted out of window to right side)

enter image description here

Reload browser (looks fine, notice panel and window are positioned properly)

enter image description here

Have I done anything wrong?

I have no luck fixing it. Please Help~

Upvotes: 2

Views: 1951

Answers (2)

Dave
Dave

Reputation: 21924

Edit:

Rixo had it exactly right -- you cannot change Ext themes on the fly for already rendered components.

The work-around is load the theme when the app starts. To do this you need to store the chosen theme name somewhere where it can survive page refreshes. ExtJS examples pages use query parameters, but I chose a cookie instead. Inside my index.jsp I placed the following:

<script type="text/javascript">
    var consoleLogEnabled = true;
    var contextPath = "${pageContext.request.contextPath}";
    var theme = 'default';

    if (document.cookie) {
        index = document.cookie.indexOf('theme');
        if (index !== -1) {
            f = (document.cookie.indexOf("=", index) + 1);
            t = document.cookie.indexOf(";", index);
            if (t === -1) {
                t = document.cookie.length;
            }
            theme = (document.cookie.substring(f, t));
        }
    }

    if ((theme === 'default') || (theme !== 'gray' && theme !== 'access' && theme !== 'neptune'))
        document.write('<link rel="stylesheet" type="text/css" href="js/ext-js/resources/css/ext-all-debug.css" />');
    else
        document.write('<link rel="stylesheet" type="text/css" href="js/ext-js/resources/css/ext-all-' + theme + '-debug.css" />');

    document.write('<script type="text/javascript" src="js/ext-js/ext-all-debug-w-comments.js"></scr'+'ipt>');

    if (theme === 'neptune')
        document.write('<script type="text/javascript" src="js/ext-js/ext-theme-neptune.js"></scr'+'ipt>');
</script>

<link rel="stylesheet" type="text/css" href="resources/css/myapp-style.css" />
<script type="text/javascript" src="js/myapp/myapp.js"></script>

Now when I want to change my theme I just do the following inside my controller:

changeTheme : function(theme) {
    if (theme !== Ext.util.Cookies.get('theme')) {
        Ext.util.Cookies.set('theme', theme);
        location = location; // Refresh of page cannot be avoided as its an Ext-JS limitation
    }

Viola - it Just Works.

Upvotes: 1

rixo
rixo

Reputation: 25021

You cannot change Ext themes on the fly for already rendered components. The reason is that during the rendering process, Ext will read the style properties of generated DOM elements like border size, margins, etc., and use that information to determine the size of each elements. In most cases, this size is set in style property of the elements, and so it won't be affected by the change of the CSS rules.

So, if the rendered elements size is not the same for two different themes, the already rendered component will break in the way you've observed.

You can test this explanation by swapping between two themes that differs only by their colors, for example "Classic" and "Gray" themes. Components size won't be affected in this case.

Upvotes: 1

Related Questions