PDA

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


rkrishna_1975
11-30-2007, 10: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
11-30-2007, 03: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
12-11-2007, 12:14 AM
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-12-2007, 05: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
02-07-2008, 06: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
02-07-2008, 10:01 AM
Nice tool!
Thanks a lot!

garraS

NBRed5
02-08-2008, 07: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
02-18-2008, 06: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
02-18-2008, 09: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
02-18-2008, 10:32 AM
Thx ! It's working now.