SkinSelector to choose Kendo CSS templates

Thread is closed for posting
27 posts, 0 answers
  1. Codeanimal
    Codeanimal avatar
    3 posts
    Member since:
    Aug 2011

    Posted 26 Aug 2011 Link to this post

    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.

     

  2. Todd Anglin
    Todd Anglin avatar
    2040 posts
    Member since:
    Aug 2005

    Posted 26 Aug 2011 Link to this post

    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
  3. Kendo UI is VS 2017 Ready
  4. Codeanimal
    Codeanimal avatar
    3 posts
    Member since:
    Aug 2011

    Posted 27 Aug 2011 Link to this post

    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'.   
  5. Mike
    Mike avatar
    2 posts
    Member since:
    Feb 2011

    Posted 19 Jan 2012 Link to this post

    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
  6. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2500 posts

    Posted 23 Jan 2012 Link to this post

    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!
  7. Mike
    Mike avatar
    2 posts
    Member since:
    Feb 2011

    Posted 23 Jan 2012 Link to this post

    Thank you very much, it worked like a charm!
  8. Matthew
    Matthew avatar
    3 posts
    Member since:
    Sep 2012

    Posted 19 Sep 2012 Link to this post

    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?
  9. Todd Anglin
    Todd Anglin avatar
    2040 posts
    Member since:
    Aug 2005

    Posted 19 Sep 2012 Link to this post

    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
  10. Matthew
    Matthew avatar
    3 posts
    Member since:
    Sep 2012

    Posted 19 Sep 2012 Link to this post

    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?
  11. Todd Anglin
    Todd Anglin avatar
    2040 posts
    Member since:
    Aug 2005

    Posted 19 Sep 2012 Link to this post

    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
  12. Matthew
    Matthew avatar
    3 posts
    Member since:
    Sep 2012

    Posted 20 Sep 2012 Link to this post

    Javascript it is :)

    Thank you Todd.

  13. Andrew
    Andrew avatar
    171 posts
    Member since:
    Jun 2009

    Posted 18 Jun 2013 Link to this post

    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?
  14. Dimo
    Admin
    Dimo avatar
    8330 posts

    Posted 20 Jun 2013 Link to this post

    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!
  15. Andrew
    Andrew avatar
    171 posts
    Member since:
    Jun 2009

    Posted 20 Jun 2013 Link to this post

    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. 
  16. Dimo
    Admin
    Dimo avatar
    8330 posts

    Posted 21 Jun 2013 Link to this post

    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!
  17. jalpesh.vadgama
    jalpesh.vadgama avatar
    7 posts
    Member since:
    Jul 2007

    Posted 12 Aug 2013 Link to this post

    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

  18. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 15 Aug 2013 Link to this post

    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!
  19. Will
    Will avatar
    34 posts
    Member since:
    Oct 2013

    Posted 07 Mar 2014 Link to this post

    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);

     
  20. Will
    Will avatar
    34 posts
    Member since:
    Oct 2013

    Posted 07 Mar 2014 in reply to Will Link to this post

    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.
  21. Anthony
    Anthony avatar
    122 posts
    Member since:
    Jun 2013

    Posted 01 May 2014 Link to this post

    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();
    }
    };
  22. Anthony
    Anthony avatar
    122 posts
    Member since:
    Jun 2013

    Posted 01 May 2014 in reply to Anthony Link to this post

    That was for this jsFiddle

    http://jsfiddle.net/gyoshev/Gxpfy/
  23. Saeed
    Saeed avatar
    3 posts
    Member since:
    Oct 2013

    Posted 28 Jan 2015 Link to this post

    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
  24. Anthony
    Anthony avatar
    122 posts
    Member since:
    Jun 2013

    Posted 29 Jan 2015 in reply to Saeed Link to this post

    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
  25. Anthony
    Anthony avatar
    122 posts
    Member since:
    Jun 2013

    Posted 29 Jan 2015 in reply to Anthony Link to this post

    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.
  26. Saeed
    Saeed avatar
    3 posts
    Member since:
    Oct 2013

    Posted 04 Feb 2015 in reply to Anthony Link to this post

    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
  27. Saeed
    Saeed avatar
    3 posts
    Member since:
    Oct 2013

    Posted 05 Feb 2015 in reply to Saeed Link to this post

    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
  28. mark
    mark avatar
    50 posts
    Member since:
    Mar 2009

    Posted 29 Jul 2015 in reply to Alex Gyoshev Link to this post

    Perfecto!  Just what I needed...Can't wait to implement this.  Users will be stoked(I hope)...  Nice job...
Back to Top
Kendo UI is VS 2017 Ready