Skip to content

Instantly share code, notes, and snippets.

@mkkeck
Last active April 9, 2016 14:25
Show Gist options
  • Save mkkeck/af8d93a348fb10faa4b8bd9267327611 to your computer and use it in GitHub Desktop.
Save mkkeck/af8d93a348fb10faa4b8bd9267327611 to your computer and use it in GitHub Desktop.
ThemeSwitch for jQuery UI v 1.11.x
/**
* ui themeswitch 1.1
* ThemeSwitch for jQuery UI
*
* Copyright: (c) 2015-2016 Michael Keck
* (https://github.com/mkkeck/jquery-ui-icons)
* License: http://www.gnu.org/licenses/gpl.html
* Modified: Michael Keck, 2016-03-02
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.selectbox.js
*
*
* Usage:
*
* $('selector').themeswitch({
*
* attach: {
* stylesheet: 'href/to/stylesheet/where/to/attach',
* // or $('link[href$="stylesheet/where/to/attach"]', $('head'))
* before: false // false insert after, true insert before attach.stylesheet
* },
* // Using Cookie (requires $.cookie)
* // cookie: true | false | null
* // or define
* cookie: {
* domain:'domain.tld',
* path:'/path/to/site',
* expires: 3600, // int secconds; 0 is session cookie and default if not defined
* raw: false | true,
* secure: false | true
* },
*
* // Label for the selectmenu
* // label: false | null
* // or define
* label: 'Theme',
*
* // Default Theme
* // theme: null | 'theme-name'
* // or define
* theme: {
* name: 'base',
* title: 'Default'
* },
*
* // Available Themes, if not set all themes from the
* // jquery-ui-themeroller will be added
* themes: [
* {
* name: 'theme-name',
* title: 'Description',
* url: 'http://domain.tld/path/theme-name.css', // optional
* thumb: 'http://domain.tld/path/theme-name.png' // optional
* }
* // , { ... }
* ],
*
* // Thumbnails for themes selectmenu
* // thumbs: null | false | 'path'
* // or define:
* thumbs: {
* path: 'images',
* type: 'png'
* },
*
* // Available userdefined Themes
* userthemes: [
* {
* name: 'user-theme-name',
* title: 'Description',
* url: 'http://domain.tld/path/user-theme-name.css',
* thumb: 'http://domain.tld/path/user-theme-name.png' // optional
* }
* // , { ... }
* ],
*
* // Version for download from google libs
* version: '1.11.4'
* });
*/
(function($, document) {
if (!$.fn) {
$.fn = {};
}
var head = document.getElementsByTagName('head')[0] ? $('head').first() : null,
plugin = 'themeswitch',
themes = [
{ 'name': 'black-tie', 'title': 'Black Tie' },
{ 'name': 'blitzer', 'title': 'Blitzer' },
{ 'name': 'cupertino', 'title': 'Cupertino' },
{ 'name': 'dark-hive', 'title': 'Dark Hive' },
{ 'name': 'dot-luv', 'title': 'Dot Luv' },
{ 'name': 'eggplant', 'title': 'Eggplant' },
{ 'name': 'excite-bike', 'title': 'Excite Bike' },
{ 'name': 'flick', 'title': 'Flick' },
{ 'name': 'hot-sneaks', 'title': 'Hot Sneaks' },
{ 'name': 'humanity', 'title': 'Humanity' },
{ 'name': 'le-frog', 'title': 'Le Frog' },
{ 'name': 'mint-choc', 'title': 'Mint Choc' },
{ 'name': 'overcast', 'title': 'Overcast' },
{ 'name': 'pepper-grinder', 'title': 'Pepper Grinder' },
{ 'name': 'redmond', 'title': 'Redmond' },
{ 'name': 'smoothness', 'title': 'Smoothness' },
{ 'name': 'south-street', 'title': 'South Street' },
{ 'name': 'start', 'title': 'Start' },
{ 'name': 'sunny', 'title': 'Sunny' },
{ 'name': 'swanky-purse', 'title': 'Swanky Purse' },
{ 'name': 'trontastic', 'title': 'Trontastic' },
{ 'name': 'ui-darkness', 'title': 'UI Darkness' },
{ 'name': 'ui-lightness', 'title': 'UI Lightness' },
{ 'name': 'vader', 'title': 'Vader' }
];
$.fn[plugin] = function(props) {
if (!head) {
return null;
}
var element = $(this), that = this, value;
props = $.extend(true, {
attach: { before: false, stylesheet: null },
cookie: true,
label: 'Theme',
theme: { name: 'base', title: 'Default' },
themes: [],
thumbs: { path: 'images', type: 'png' },
userthemes: [],
version: '1.11.4'
}, props);
props.loadtheme = null;
props.themefile = 'jquery-ui.min.css';
props.themepath = ['//ajax.googleapis.com/ajax/libs/jqueryui', props.version, 'themes'].join('/');
if (props.themes.length === 0) {
props.themes = themes;
}
if (props.userthemes.length > 0) {
props.themes = $.extend(props.themes, props.userthemes);
}
if (props.thumbs) {
if (typeof props.thumbs === 'string') {
props.thumbs = {'path': props.thumbs, 'type': 'png'};
}
}
if (typeof $.cookie === 'function' && props.cookie) {
value = {};
value.name = 'jquery-ui-' + plugin;
value.domain = (!props.cookie.domain || location.hostname.indexOf(props.cookie.domain) === -1) ? '' : props.cookie.domain;
value.expires = (!props.cookie.expires ? 0 : props.cookie.expires);
value.path = (!props.cookie.path ? location.pathname : props.cookie.path);
props.cookie = value;
}
else {
props.cookie = null;
}
if (props.attach) {
if (!props.attach.hasOwnProperty('stylesheet')) {
props.attach = { 'stylesheet': props.attach, 'before': false };
}
if (typeof props.attach.stylesheet === 'string') {
props.attach.stylesheet = $('link[href$="'+props.attach.stylesheet+'"][rel="stylesheet"]', head) || null;
}
if (props.attach.stylesheet && props.attach.stylesheet.length > 0) {
props.attach.stylesheet = props.attach.stylesheet[props.attach.after ? 'last' : 'first']();
}
}
this._find = function(theme) {
var result = null;
if (!theme) {
return result;
}
theme = (''+theme).toLowerCase();
$.each(props.themes, function(key, item) {
if (item.name.toLowerCase() === theme || item.title.toLowerCase() === theme) {
result = item;
return false;
}
});
return result;
};
this._cookie = function(value) {
if (props.cookie) {
$.cookie(props.cookie.name, value, props.cookie);
}
};
this._load = function(theme) {
var link = $('link[href^="'+props.themepath+'"][rel="stylesheet"]', head);
if (typeof theme === 'string') {
theme = this._find(theme);
}
if (!theme || !head) {
return;
}
if (!theme.url) {
if (link) {
link.remove();
}
this._cookie(null);
return;
}
if (link.length > 0) {
link.first().attr('href', theme.url);
this._cookie(theme.name);
return;
}
link = $('<link type="text/css" rel="stylesheet" href="' + theme.url + '" />');
if (props.attach.stylesheet) {
link['insert'+(props.attach.before ? 'Before' : 'After')](props.attach.stylesheet);
this._cookie(theme.name);
return;
}
head[(props.attach.before ? 'prepend' : 'append')](link);
this._cookie(theme.name);
};
$.each(props.themes, function(key, item) {
if (!item.url) {
props.themes[key].url = [
props.themepath,
item.name,
props.themefile
].join('/');
}
if (!item.thumb && props.thumbs && props.thumbs.path) {
props.themes[key].thumb = [
[props.thumbs.path, item.name].join('/'),
(props.thumbs.type || 'png')
].join('.');
}
});
if (typeof props.theme === 'string') {
props.theme = this._find(props.theme, props.themes);
}
if (props.theme.name) {
if (!this._find(props.theme.name, props.themes)) {
props.themes.unshift({
'name' : props.theme.name,
'title' : props.theme.title || props.theme.name.substr(0,1).toUpperCase()+props.theme.name.substr(1),
'thumb': (!props.theme.hasOwnProperty('thumb') && props.thumbs && props.thumbs.path
? [[props.thumbs.path, props.theme.name].join('/'), (props.thumbs.type || 'png')].join('.')
: (props.theme.thumb ? props.theme.thumb : null)
)
});
}
props.loadtheme = this._find(props.theme.name);
}
if (props.cookie) {
value = $.cookie(props.cookie.name);
if (value) {
props.loadtheme = this._find(value);
}
}
$.widget('ui.'+plugin+'menu', $.ui.selectmenu, {
_renderItem: function(ul, item) {
var li = $('<li>'), html = item.label;
if (item.disabled) {
li.addClass('ui-state-disabled');
}
if (item.element.attr('selected')) {
li.addClass('ui-state-focus');
}
if (props.thumbs && item.element.data('thumb')) {
html = ['<img src="', item.element.data('thumb'), '" class="thumb" /><span class="title">', item.label, '</span>'].join('');
}
li.html(html);
return li.appendTo(ul);
}
});
this.wrapper = $('<div>')
.addClass('ui-'+plugin+' ui-front ui-widget ui-helper-clearfix')
.appendTo(element);
if (props.label) {
this.wrapper
.append(['<label for="',plugin,'-select">',props.label,': </label>'].join(''));
}
this.menu = $('<select>')
.attr('id',plugin+'-select')
.on('change.'+plugin, function() { that._load($(this).val()); })
.appendTo(this.wrapper);
$.each(props.themes, function(key, item) {
var option = $('<option>').text(item.title);
option.attr({'value': item.name });
option.data(item);
if (props.loadtheme && props.loadtheme.name === item.name) {
option.attr({'selected':'selected'});
}
that.menu.append(option);
});
if (!(document.all && !document.querySelector)) {
this.menu[plugin + 'menu']({
'change': function(event, ui) {
that._load(ui.item.value);
}
});
this.menu[plugin + 'menu']('menuWidget').addClass('ui-menu-overflow');
}
if (props.loadtheme) {
this._load(props.loadtheme);
}
return this;
};
})(jQuery, document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment