Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change theme dynamically in jquery mobile?

I am creating a mobile web applications using jQuery Mobile.

I am using theme-b for every page and I would like to change to another theme dynamically for every page. How can I change the theme dynamically?

like image 511
Ramasamy Kanna Avatar asked Dec 28 '11 13:12

Ramasamy Kanna


3 Answers

You can target specific classes that relate to specific widgets, reset their classes, and then add the themed class of your choosing:

    //set your new theme letter
    var theme = 'e';

    //reset all the buttons widgets
    $.mobile.activePage.find('.ui-btn')
                       .removeClass('ui-btn-up-a ui-btn-up-b ui-btn-up-c ui-btn-up-d ui-btn-up-e ui-btn-hover-a ui-btn-hover-b ui-btn-hover-c ui-btn-hover-d ui-btn-hover-e')
                       .addClass('ui-btn-up-' + theme)
                       .attr('data-theme', theme);

    //reset the header/footer widgets
    $.mobile.activePage.find('.ui-header, .ui-footer')
                       .removeClass('ui-bar-a ui-bar-b ui-bar-c ui-bar-d ui-bar-e')
                       .addClass('ui-bar-' + theme)
                       .attr('data-theme', theme);

    //reset the page widget
    $.mobile.activePage.removeClass('ui-body-a ui-body-b ui-body-c ui-body-d ui-body-e')
                       .addClass('ui-body-' + theme)
                       .attr('data-theme', theme);

http://jsfiddle.net/VNXb2/1/

This is by no means a fully functional code snippet, you will need to find any other widgets that you want updated when you switch the theme and add them to the code above. You can find what classes each widget has easily by using FireBug or another Developer Console.

UPDATE

When you take into account the data-role="list-divider elements this gets a little tricky:

var theme = 'c';

//the only difference between this block of code and the same code above is that it doesn't target list-dividers by calling: `.not('.ui-li-divider')`
$.mobile.activePage.find('.ui-btn').not('.ui-li-divider')
                   .removeClass('ui-btn-up-a ui-btn-up-b ui-btn-up-c ui-btn-up-d ui-btn-up-e ui-btn-hover-a ui-btn-hover-b ui-btn-hover-c ui-btn-hover-d ui-btn-hover-e')
                   .addClass('ui-btn-up-' + theme)
                   .attr('data-theme', theme);

//target the list divider elements, then iterate through them to check if they have a theme set, if a theme is set then do nothing, otherwise change its theme to `b` (this is the jQuery Mobile default for list-dividers)
$.mobile.activePage.find('.ui-li-divider').each(function (index, obj) {
    if ($(this).parent().attr('data-divider-theme') == 'undefined') {
        $(this).removeClass('ui-bar-a ui-bar-b ui-bar-c ui-bar-d ui-bar-e')
               .addClass('ui-bar-b')
               .attr('data-theme', 'b');
    }
})

/*The rest of this code example is the same as the above example*/

Here is a demo: http://jsfiddle.net/VNXb2/7/

like image 77
Jasper Avatar answered Nov 09 '22 20:11

Jasper


The above answer helped me a lot, I modified it a little for my need, as I am using themeroller and expect to have more than 20 themes. Here is what I have done

function updateTheme(newTheme) {
//alert("In refresh");
var rmbtnClasses = '';
var rmhfClasses = '';
var rmbdClassess = '';
var arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"  ];

$.each(arr,function(index, value){
    rmbtnClasses = rmbtnClasses + " ui-btn-up-"+value + " ui-btn-hover-"+value;
    rmhfClasses = rmhfClasses + " ui-bar-"+value;
    rmbdClassess = rmbdClassess + " ui-body-"+value;
});

// reset all the buttons widgets
 $.mobile.activePage.find('.ui-btn').not('.ui-li-divider').removeClass(rmbtnClasses).addClass('ui-btn-up-' + newTheme).attr('data-theme', newTheme);

 // reset the header/footer widgets
 $.mobile.activePage.find('.ui-header, .ui-footer').removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme', newTheme);

 // reset the page widget
 $.mobile.activePage.removeClass(rmbdClassess).addClass('ui-body-' + newTheme).attr('data-theme', newTheme);

 // target the list divider elements, then iterate through them and
 // change its theme (this is the jQuery Mobile default for
 // list-dividers)
 $.mobile.activePage.find('.ui-li-divider').each(function(index, obj) {
 $(this).removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme',newTheme);

 })

Now when I get the new Theme from the server via json I just call this method with the new theme as param.

Regards Rajesh J

like image 42
Rajesh Avatar answered Nov 09 '22 21:11

Rajesh


Rajesh's answer helped me a lot... But Rajesh, you missed an important class ---- 'ui-page-theme-*', so I modified your answer and now it's perfect for jQuery Mobile 1.4.5 (again)...

var updateTheme = function(newTheme) {
    var rmbtnClasses = '';
    var rmhfClasses = '';
    var rmbdClassess = '';
    var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's']; // I had themes from a to s

    $.each(arr, function(index, value) {
        rmbtnClasses = rmbtnClasses + ' ui-btn-up-' + value + ' ui-btn-hover-' + value;
        rmhfClasses = rmhfClasses + ' ui-bar-' + value;
        rmbdClassess = rmbdClassess + ' ui-body-' + value + ' ui-page-theme-'+ value;
    });

    // reset all the buttons widgets
    $.mobile.activePage.find('.ui-btn').not('.ui-li-divider').removeClass(rmbtnClasses).addClass('ui-btn-up-' + newTheme).attr('data-theme', newTheme);

    // reset the header/footer widgets
    $.mobile.activePage.find('.ui-header, .ui-footer').removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme', newTheme);

    // reset the page widget
    $.mobile.activePage.removeClass(rmbdClassess).addClass('ui-body-' + newTheme + ' ui-page-theme-'+ newTheme).attr('data-theme', newTheme);

    // target the list divider elements, then iterate through them and
    // change its theme (this is the jQuery Mobile default for
    // list-dividers)
    $.mobile.activePage.find('.ui-li-divider').each(function(index, obj) {
        $(this).removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme', newTheme);
    });
};
like image 1
kenberkeley Avatar answered Nov 09 '22 20:11

kenberkeley