This is a migrated thread and some comments may be shown as answers.

SkinSelector to choose Kendo CSS templates

26 Answers 2194 Views
Templates
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Codeanimal
Top achievements
Rank 1
Codeanimal asked on 26 Aug 2011, 07:38 PM

First off I'd just like to say how wonderful KendoUI is.  I got it working on my site in a matter of minutes thanks to your great docs and demos.

One thing I can't figure, and maybe I missed something obvious.  I find it easy enough to set one of the inlcuded CSS styles, and I can insert the style selector drop box with <select id="skinSelector" class="skinSelector"></select>

 So how do I populate it with the available styles such as you have in most of your demos?

Thanks.

 

26 Answers, 1 is accepted

Sort by
0
Todd Anglin
Top achievements
Rank 2
answered on 26 Aug 2011, 10:23 PM
Hello CodeAnimal-

I'm glad you like Kendo UI! Thanks for checking-out the beta.

The Skin Selector you see in the demos is simply a Kendo UI DropDownList populated with the 3 available beta skins. The configuration is available in the demo source code (available when you download the beta), and it looks something like this:

$("#skinSelector").kendoDropDownList({
      dataSource: [
            { text: "Kendo", control: "Menu", value: "kendo" },
            { text: "Blue Opal", control: "Menu", value: "blueopal" },
            { text: "Black", control: "Menu", value: "black" }
      ],
      template: //Template configuration (with images and text) - omitted for clarity
});

This initializes the DropDownList with the available values. We then bind the change event to handle the theme swapping:

$("#skinSelector").bind("change", function(e) {
      var newSkin = skinSelector.val().toLowerCase(); //Get skin key name
 
      Application.fetchSkin(newSkin, true);
 
      try {
            //Save a user picked theme in HTML5 browser SessionStorage
            //(for reloading on navigation)
            sessionStorage.setItem("kendoSkin", newSkin);
       } catch(err) {}
});

Inside of Application.fetchSkin (which you can find in kendo.examples.js) we do the heavy lifting necessary to do the fade-out/fade-in swap of the loaded CSS styles without refreshing the page. For now, the Skin Selector is not a "formal" UI widget in the toolset, but hopefully this code and guidance shows you how you can do something similar in your own app.

Hope that helps.

-Todd
0
Codeanimal
Top achievements
Rank 1
answered on 27 Aug 2011, 05:07 AM
See? I knew I was missing something! Thanks so much!

- Having been involved with computers since the Atari 400 I'd just like to compliment you on the fact that what you call 'beta'... an awful lot of companies over the years would have been have been proud to call what you guys have so far as 'production'.   
0
Mike
Top achievements
Rank 1
answered on 19 Jan 2012, 09:37 PM
Hello,
I cannot seem to get the code Todd provided to create a functioning SkinSelector. I am working with the actual release of Kendo UI, not the beta. I am able to create the dropdown box and populate its values dynamically via this bit:
$("#skinSelector").kendoDropDownList({
      dataSource: [
            { text: "Kendo", control: "Menu", value: "kendo" },
            { text: "Blue Opal", control: "Menu", value: "blueopal" },
            { text: "Black", control: "Menu", value: "black" }
      ],
      template: //Template configuration (with images and text) - omitted for clarity
});

It looks like this:
 

But I want it to look like this:

(It displays like this if I switch out the skinSelector id's with dropdownlist)

Also, the second part of the code:
$("#skinSelector").bind("change", function(e) {
      var newSkin = skinSelector.val().toLowerCase(); //Get skin key name
 
      Application.fetchSkin(newSkin, true);
 
      try {
            //Save a user picked theme in HTML5 browser SessionStorage
            //(for reloading on navigation)
            sessionStorage.setItem("kendoSkin", newSkin);
       } catch(err) {}
});
Doesn't allow me to swap out the themes.

Here is what I have:

<input id="skinSelector" />

<script>
$("#skinSelector").kendoDropDownList({
      dataSource: [
            { text: "Kendo", control: "Menu", value: "kendo" },
            { text: "Blue Opal", control: "Menu", value: "blueopal" },
            { text: "Black", control: "Menu", value: "black" }
      ],

});

$("#skinSelector").bind("change", function(e) {
      var newSkin = skinSelector.val().toLowerCase(); //Get skin key name
 
      Application.fetchSkin(newSkin, true);
 
      try {
            //Save a user picked theme in HTML5 browser SessionStorage
            //(for reloading on navigation)
            sessionStorage.setItem("kendoSkin", newSkin);
       } catch(err) {}
});


</script>

What am I doing wrong?

Thanks!!

Mike
0
Alex Gyoshev
Telerik team
answered on 23 Jan 2012, 01:45 PM
Hello Mike,

Here is a theme chooser demo that isolates only the required code from the examples. Hope this helps!

Regards,
Alex Gyoshev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mike
Top achievements
Rank 1
answered on 23 Jan 2012, 04:49 PM
Thank you very much, it worked like a charm!
0
Matthew
Top achievements
Rank 1
answered on 19 Sep 2012, 01:58 PM
Not sure I need to open a new thread for this. I've done exactly this and it worked great.

I'm trying to update graph themes as well, but it's not budging at all. I've added the following code 

$('.k-chart').each(function () {
                var chart = $(this).data('kendoChart');
                chart.options.theme = skinName;
                chart.refresh();
            });

Is there a way to get this to work please?
0
Todd Anglin
Top achievements
Rank 2
answered on 19 Sep 2012, 03:39 PM
Hello Matthew-

Unfortunately, to change themes with the chart, you need to reconstruct the Chart widget.

Since the theme is used throughout the SVG generated when a Chart is initialized, changing the theme is a big more difficult than with other HTML/CSS widgets. The Chart's refresh() method will reload and repaint the data series, but it does not reinitialize the chart (and thus apply a new SVG theme).

If you need to change the Chart theme on demand, simply reinitialize the Chart.

In fact, we do this very same thing in the Chart online demos. If you review the JavaScript on the following demo, you'll see that we rebuild the chart when the "ThemeChooser" changes themes in the demo. Hopefully this helps give you a pattern to follow:

http://demos.kendoui.com/dataviz/area-charts/index.html

-Todd
0
Matthew
Top achievements
Rank 1
answered on 19 Sep 2012, 03:41 PM
Hi Todd,

Thanks for that. Is this possible when using your MVC wrappers by any chance? Or should I just build the theme with javascript and use your demo method?
0
Todd Anglin
Top achievements
Rank 2
answered on 19 Sep 2012, 04:17 PM
If your goal is to provide an interactive experience for users, I would suggest using the JavaScript approach to handle the theme changing. To do the same with the MVC wrappers would require an extra trip to the server, which may not be the experience you're trying to provide.

Hope this helps!

-Todd
0
Matthew
Top achievements
Rank 1
answered on 20 Sep 2012, 07:39 AM
Javascript it is :)

Thank you Todd.

0
Andrew
Top achievements
Rank 1
answered on 19 Jun 2013, 04:13 AM
Anyone know how to update this sample to work with jquery 1.9 and IE 10?
I know if i take the:
if ($.browser.msie) {
            newLink = doc.createStyleSheet(url);
        } else {
            newLink = skinLink.eq(0).clone().attr("href", url);
        }
and replace it with simply:
newLink = skinLink.eq(0).clone().attr("href", url);
It works with Chrome and FireFox but that does not work with IE10

For testing i also tried only having 
newLink = doc.createStyleSheet(url);
To see if it would work in IE10, but it does not.

So even if i replace the $.browser.msie with a different way of detecting IE, it still would not work in IE 10.

Any ideas?
0
Dimo
Telerik team
answered on 20 Jun 2013, 11:05 AM
Hello,

An updated demo including jQuery 1.9.1 and Kendo UI 2013.1.514 is available at

http://jsfiddle.net/Gxpfy/114/


Regards,
Dimo
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Andrew
Top achievements
Rank 1
answered on 20 Jun 2013, 11:54 AM
Nice!
Weird thing happens though. In IE10 the drop-down appears to be opening in the wrong place, somehow off set to the middle of the page. 
0
Dimo
Telerik team
answered on 21 Jun 2013, 07:41 AM
Hello Andrew,

I do not observe such a problem, as the attached screenshot shows.

Regards,
Dimo
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
jalpesh.vadgama
Top achievements
Rank 2
answered on 12 Aug 2013, 04:19 PM
Hi Dimo,

We have tried same thing with asp.net mvc controls but we're not able to have same kind of functionality there. Does it also works fine with asp.net mvc kendo ui controls?

Regards,
Jalpesh

0
Petyo
Telerik team
answered on 15 Aug 2013, 11:26 AM
Hello,

the same approach should work with the Kendo UI ASP.NET MVC wrappers, as they are using the same client-side implementation. 

Regards,
Petyo
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Will
Top achievements
Rank 1
answered on 07 Mar 2014, 04:38 PM
Just to possibly save others some time (referring to the fiddle above (Posted 23 Jan 2012) for those needing to support IE 11:

1) $.browser has been removed from jQuery 1.9.  The suggestion is to use Modernizr.  Mine is an intranet app with homogenous browser environment so I haven't pursued that.

2) In IE 11, the createStyleSheet() method has been replaced with createElement('style').  Once created, you have to set the attributes e.g. href with the setAttribute() method.  Haven't got everything working yet but my code looks like this:

newLink = doc.createElement('style');
newLink.setAttribute("type", "text/css");
newLink.setAttribute("rel", "stylesheet");
newLink.setAttribute("href", url);

 
0
Will
Top achievements
Rank 1
answered on 07 Mar 2014, 07:27 PM
Just a follow-up: 

Regarding the loss of the $.browser object from jQuery 1.9+, I noticed that in $(doc.documentElement)[0].classList there were two classes included: "k-ie" and "k-ie11".  Looks like Kendo has already figured that information out.
0
Anthony
Top achievements
Rank 1
answered on 01 May 2014, 12:39 PM
I had the same question, hit the same obstacles (time passing, jQuery changing), so here is a version of the js that works in chrome/IE/mobile as of may 2014.
I stripped out the IE/chrome dependent parts as they didn't seem to be needed in the latest versions.
May not work in all versions, etc


// theme chooser drop-down
$(".themeChooser").kendoDropDownList({
dataSource: [
        { text: "Black", value: "black" },
        { text: "Blue Opal", value: "blueopal" },
        { text: "Default", value: "default" },
        { text: "Metro", value: "metro" },
        { text: "Silver", value: "silver" }
],
dataTextField: "text",
dataValueField: "value",
change: function (e)
{
var theme = (this.value() || "blueopal").toLowerCase();

changeTheme(theme);
}
});

// loads new stylesheet
function changeTheme(skinName, animate)
{
var doc = document;
var kendoLinks = $("link[href*='kendo.']", doc.getElementsByTagName("head")[0]);
var commonLink = kendoLinks.filter("[href*='kendo.common']");
var skinLink = kendoLinks.filter(":not([href*='kendo.common'])").filter(":not([href*='kendo.mobile'])");
var href = location.href;
var skinRegex = /kendo\.\w+(\.min)?\.css/i;
var extension = skinLink.attr("rel") === "stylesheet" ? ".css" : ".less";
var url1 = commonLink.attr("href").replace(skinRegex, "kendo." + skinName + "$1" + extension);
var url2 = commonLink.attr("href").replace(skinRegex, "kendo.dataviz." + skinName + "$1" + extension);
var exampleElement = $("#example");

function preloadStylesheet(file, callback)
{
var element = $("<link rel='stylesheet' media='print' href='" + file + "'").appendTo("head");

setTimeout(function ()
{
callback();
element.remove();
}, 100);
}

function replaceTheme()
{
var oldSkinName = $(doc).data("kendoSkin");

var newLink1 = doc.createElement('link');
newLink1.setAttribute("rel", "stylesheet");
newLink1.setAttribute("href", url1);

var newLink2 = doc.createElement('link');
newLink2.setAttribute("rel", "stylesheet");
newLink2.setAttribute("href", url2);

var head = document.head;

head.insertBefore(newLink2, skinLink[0]);
head.insertBefore(newLink1, skinLink[0]);
skinLink.remove();

$(doc.documentElement).removeClass("k-" + oldSkinName).addClass("k-" + skinName);
}

if (animate)
{
preloadStylesheet(url, replaceTheme);
} else
{
replaceTheme();
}
};
0
Anthony
Top achievements
Rank 1
answered on 01 May 2014, 12:41 PM
That was for this jsFiddle

http://jsfiddle.net/gyoshev/Gxpfy/
0
Saeed
Top achievements
Rank 1
answered on 28 Jan 2015, 05:52 PM
Hi,
The post from Anthony on 01 May 2014 works fine for me in IE/Chrome/FF until I publish to IIS.
I have identified that it seems to be an issue when setting Compilation Debug=True in the Web.Config
using jquery 2.1.1 (or later).

Has anyone found this problem or found a fix for this?

To reproduce the problem:
You can modify your BundleConfig so that the last line is

            // enforce bundling even in debug mode
             BundleTable.EnableOptimizations = true;

This will reproduce the error within VS2013.

The specific error is "Uncaught TypeError: Cannot read property 'replace' of undefined" (Chrome Developer tools console log)
and it refers to the following line for the exception:

var url1 = commonLink.attr("href").replace(skinRegex, "kendo." + skinName + "$1" + extension);

If someone knows of a work around (other than publishing with Debug=True), then please let me know.

Many thanks,
Andy
0
Anthony
Top achievements
Rank 1
answered on 29 Jan 2015, 07:56 AM
Hi
  In the end I didn't need to use that code so I can't check, however when I've had similar problems it's been because the 'min' files have been out of step with the non minified files.

Regards
Anthony
0
Anthony
Top achievements
Rank 1
answered on 29 Jan 2015, 08:20 AM
Actually I think I can guess this

When you have that optimisation the kendo files will be bundled together so it won't be able to find 'kendo.common' anymore, hence commonLink will be length zero and the crash.
If you want to go this way you can probably just not bundle the kendo files but just link to them directly, or you could make bundles for each of the theme files and give the bundles names with 'kendo.common' in it.
0
Saeed
Top achievements
Rank 1
answered on 04 Feb 2015, 09:45 AM
Many thanks for the reply Antony.

I will try what you suggested about not bundling kendo but adding manually and will let you know how it goes.

All the best,
Andy
0
Saeed
Top achievements
Rank 1
answered on 05 Feb 2015, 05:03 PM
Just to confirm, removing the kendo common.min, rtl.min and dataviz.min from being bundled, and instead just render them in the layout.cshtml will now allow rendering of the theme change in javascript.

All the best,
Andy
0
mark
Top achievements
Rank 1
answered on 29 Jul 2015, 11:53 PM
Perfecto!  Just what I needed...Can't wait to implement this.  Users will be stoked(I hope)...  Nice job...
Tags
Templates
Asked by
Codeanimal
Top achievements
Rank 1
Answers by
Todd Anglin
Top achievements
Rank 2
Codeanimal
Top achievements
Rank 1
Mike
Top achievements
Rank 1
Alex Gyoshev
Telerik team
Matthew
Top achievements
Rank 1
Andrew
Top achievements
Rank 1
Dimo
Telerik team
jalpesh.vadgama
Top achievements
Rank 2
Petyo
Telerik team
Will
Top achievements
Rank 1
Anthony
Top achievements
Rank 1
Saeed
Top achievements
Rank 1
mark
Top achievements
Rank 1
Share this question
or