PDA

View Full Version : Ext.ux.ThemeChanger - Way to change themes(or any css) without reloading the page.



rkrishna_1975
30 Nov 2007, 7:57 AM
I just developed a new ThemeChanger Extension. it extends Ext.form.ComboBox. I was useful to me. I am sharing this if it is of any use to others.

Here is a sample code to use this There are other hidden features that can be explored:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="scripts/ext/ext-base.js"></script>
<script type="text/javascript" src="scripts/ext/ext-all.js"></script>
<script type="text/javascript" src="scripts/extux/Portal.js"></script>

<script type="text/javascript" src="scripts/extux/ThemeChanger.js"></script>

<script type="text/javascript">
var myThemeChanger = new Ext.ux.ThemeChanger({
renderTo:'theme-selector', // or use as a component in your layout
preThemes: 'css/ext/ext-all.css',
postThemes: ['css/app/corp.css','css/extux/Portal.css'],
extThemes: [
['Aero', 'css/ext/xtheme-none.css'], // some non existent or blank file.
['Black', 'css/ext/xtheme-black.css'],
['Gray', 'css/ext/xtheme-gray.css'],
['Slate', 'css/ext/xtheme-slate.css']
],
defaultTheme: 3,
cssId: 'myThemeId'
});

// All other page layout setup scripts here.
</script>

</head>
<body>
<div id="theme-selector" style="width:100%;height:100%;"></div>

</body>
</html>Here is the code for the ThemeChanger component itself.



/**
* @author ramki_r
*/
Ext.ux.ThemeChanger = Ext.extend(Ext.form.ComboBox, {
extThemes: [
['Aero', 'xtheme-none.css'],
],

defaultTheme: 0,
typeAhead: true,
triggerAction: 'all',
mode: 'local',
editable: false,
cssId: Ext.id(),

loadCssFile: function(filename, theCssId){
if (theCssId)
var elem = document.getElementById(theCssId);
if (elem && elem!=null){
elem.setAttribute("href", filename);
} else {
elem=document.createElement("link");
elem.setAttribute("rel", "stylesheet");
elem.setAttribute("type", "text/css");
elem.setAttribute("href", filename);
if (theCssId)
elem.setAttribute("id", theCssId);
document.getElementsByTagName("head")[0].appendChild(elem);
}
},

changeTheme: function ( obj, rec, themeChoice){
this.defaultTheme = themeChoice;
this.loadCssFile(rec.get(this.valueField),this.cssId);
},

loadPreThemes: function() {
if (this.preThemes) {
if (this.preThemes instanceof Array) {
for(var i = 0, len = this.preThemes.length; i < len; i++){
this.loadCssFile(this.preThemes[i]);
}
} else {
this.loadCssFile(this.preThemes);
}
}
},

loadPostThemes: function() {
if (this.postThemes) {
if (this.postThemes instanceof Array) {
for(var i = 0, len = this.postThemes.length; i < len; i++){
this.loadCssFile(this.postThemes[i]);
}
} else {
this.loadCssFile(this.postThemes);
}
}
},

initComponent: function() {
Ext.ux.ThemeChanger.superclass.initComponent.call(this);
if (!this.store) {
this.store = new Ext.data.SimpleStore({
fields: ['displayname', 'cssFile'],
data: this.extThemes
});
}
if (!this.displayField)
this.displayField = 'displayname';
if (!this.valueField)
this.valueField = 'cssFile';
if (!this.value)
this.value = this.store.getAt(this.defaultTheme).get(this.valueField);

this.on('select',this.changeTheme);

this.loadPreThemes();
this.changeTheme(this, this.store.getAt(this.defaultTheme),this.defaultTheme);
this.loadPostThemes();
}

});Try it out and enjoy.

I have uploaded some screenshots for context.

DigitalSkyline
30 Nov 2007, 12:56 PM
I know its hard to keep track of all that Ext goodness but this one is easy:

Ext.util.CSS.swapStyleSheet('theme', combo.getValue());

mxu
10 Dec 2007, 9:14 PM
after changing theme selection from the Combo box, the theme change takes effect on
FF, Sofari and Opera. but on IE &.* I use, the theme won't take effect unless I re-click combo box or click panels, does anyone else have the same issue ?

rkrishna_1975
12 Dec 2007, 2:04 PM
I have tried this on IE. The only reason this may not take effect on IE is the way IE loads its css. By default this will load the css at the end. This may be the case for you. You may want to put a dummy link tag with an id where the css should sit in the hierarchy and then set that as the cssId. Try a few combinations and it will work. That is specifically the reason I put in pre and post themes.

ScorpioMan
7 Feb 2008, 3:50 AM
Hi,

Thanks nice tool....really appreciate the effort.
One problem though...as i navigate to another page the theme is getting reset. Can anyone suggest why?

I am using ExtJS 2.0 with Struts 2.0.

I think the problem is somewhere in store the value but can't figure out where.

Thanks,

garraS
7 Feb 2008, 7:01 AM
Nice tool!
Thanks a lot!

garraS

NBRed5
8 Feb 2008, 4:16 AM
I have been doing this for ages.

See the following code snippets and an example on my site shown in my signature




themeData = new Ext.data.SimpleStore({
fields: ['display', 'value'],


data: [

['Default (Blue)', ''],
['Black', '../css/xtheme-black.css'],
['Dark Gray', '../css/xtheme-darkgray.css'],
['Olive', '../css/xtheme-olive.css'],
['Pink', '../css/xtheme-pink.css'],
['Purple', '../css/xtheme-purple.css'],
['Slate', '../css/xtheme-slate.css']
]


});


this.comboTheme = new Ext.form.ComboBox({
store: themeData,


displayField:'display',

typeAhead: true,
mode: 'local',
triggerAction: 'all',
selectOnFocus:true,
resizable:false,
listWidth: 100,
width: 100,
valueField: 'value',
value: ''
});
this.comboTheme.on('select', function(combo){
Ext.util.CSS.swapStyleSheet('theme', combo.getValue());
}, this);
this.northToolbar.setHeight(32);
this.northToolbar.addFill();
this.northToolbar.addText('Theme:');
this.northToolbar.addSpacer();
this.northToolbar.addSpacer();


this.northToolbar.addField(this.comboTheme);



Where northToolbar can be any toolbar (it is added to the right).


Also add the following to the header of the html page.



<link id="theme" rel="stylesheet" type="text/css" href="" />[/left]



The blank href means the default theme is used by default.

DeeZ
18 Feb 2008, 3:09 AM
Hi,
I try to use the code of NBRed5 but on IE 6 I have a pb:
- the default blue theme is used.
- I can switch to any other theme without pb.
- but when I select back to the default theme is not working (the previous theme is always used)

How to avoid this problem ?

Thx.

NBRed5
18 Feb 2008, 6:21 AM
DeeZ,

I hadn't tested in IE (does not work in IE6 or IE7), however I think the problem is with IE and not the code.

To resolve create a blank css file xtheme-default.css and set that as the value for the Blue (default) theme



themeData = new Ext.data.SimpleStore({
fields: ['display', 'value'],
data: [
['Default (Blue)', '../css/xtheme-default.css'],
['Black', '../css/xtheme-black.css'],[/left]
['Dark Gray', '../css/xtheme-darkgray.css'],[/left]
['Olive', '../css/xtheme-olive.css'],[/left]
['Pink', '../css/xtheme-pink.css'],[/left]
['Purple', '../css/xtheme-purple.css'],[/left]
['Slate', '../css/xtheme-slate.css'][/left]
]
});


It seems as if IE is having problems with setting the value of the stylesheet href to '', although not a problem with firefox.

DeeZ
18 Feb 2008, 7:32 AM
Thx ! It's working now.

webdev2111
2 Feb 2012, 8:21 PM
How can I go about changing the default blue theme to the gray thems that comes with the extjs download?