Project

General

Profile

Change bootstrap3 theme on the fly

Added by Emeric Poupon almost 4 years ago

Hello,

I managed to customize my bootstrap3 theme using a specialized Wt::WBootstrapTheme class that overiddes the styleSheets method.

In this method I just return "resources/themes/bootstrap/3/wt.css" and a custom "bootstrap.css" file.

This is working fine, but I wonder if there is a way to change this during runtime?

Setting the theme once the application has been rendered does not seem to work.

Regards,


Replies (8)

RE: Change bootstrap3 theme on the fly - Added by Emeric Poupon almost 4 years ago

Well, I tried to use the WApplication interface directly (useStyleSheet and removeStyleSheet) to swap themes, but it does not work as expected: there are a lot of visual glitches.

As a workaround, I was thinking about loading a theme by default, and storing a user selected theme in local storage from the settings page.

Then when the user reconnects, we can retrieve the selected theme and apply it. But I am not sure it is compatible with the bootsrap load method...

RE: Change bootstrap3 theme on the fly - Added by Roel Standaert almost 4 years ago

It seems that we're not documenting that fact, but you can indeed not normally change themes on the fly. The theme applies certain properties to your widgets that are different for WCssTheme and WBootstrapTheme.

So you may be able to use useStyleSheet / removeStyleSheet tricks to switch between custom Bootstrap themes, but that's not going to work for switching between WCssTheme and WBootstrapTheme.

You could store the preferred theme in a cookie, and then look at the cookie when the WApplication is being created. Changing the theme would then still require a refresh of the page, though.

But I am not sure it is compatible with the bootsrap load method...

I'm not sure what you're referring to there? You mean progressive bootstrap? If the local storage is in the form of a cookie, it should work.

RE: Change bootstrap3 theme on the fly - Added by Emeric Poupon almost 4 years ago

Roel Standaert wrote:

It seems that we're not documenting that fact, but you can indeed not normally change themes on the fly. The theme applies certain properties to your widgets that are different for WCssTheme and WBootstrapTheme.

This is bad news :'(

So you may be able to use useStyleSheet / removeStyleSheet tricks to switch between custom Bootstrap themes, but that's not going to work for switching between WCssTheme and WBootstrapTheme.

I don't manage to switch from one bootstrap style to another. They are very similar though (https://bootswatch.com/3/darkly/ -> https://bootswatch.com/3/flatly/). Maybe I do something wrong. Do I have to remove/reset all the css files, included wt's ones?

You could store the preferred theme in a cookie, and then look at the cookie when the WApplication is being created. Changing the theme would then still require a refresh of the page, though.

> But I am not sure it is compatible with the bootsrap load method...

I'm not sure what you're referring to there? You mean progressive bootstrap? If the local storage is in the form of a cookie, it should work.

Yes, that was I was referring to. The tricky part is that I have a login page (with a remember me option), and I would like this theme preference be tied to the user and not to the browser.

If the "remember me" option is set, I can read the user settings during the WApplication creation and set the correct theme, but it is somewhat clunky (does not work if the user has not used the remember me option).

RE: Change bootstrap3 theme on the fly - Added by Roel Standaert almost 4 years ago

I think then instead of overriding styleSheets to provide the correct stylesheets, you'd have to use useStyleSheet / removeStyleSheet for all of them. You would make styleSheets() return an empty vector then, or maybe just the wt.css. The order in which stylesheets are defined may matter if one stylesheet overrides the other, so maybe you'd also need to add/remove wt.css, but I'm cautiously optimistic that that shouldn't make a difference.

RE: Change bootstrap3 theme on the fly - Added by Emeric Poupon almost 4 years ago

Thanks for the suggestion!

It seems to work quite better this way. I still have some very small visual glitches but I think I can work around them.

RE: Change bootstrap3 theme on the fly - Added by Emeric Poupon almost 4 years ago

Some remarks:

  • I have to removeStyleSheet in the reverse order (otherwise I get really bad rendering)
  • It looks like both styleSheets overlap. In chrome I can see both files being used (see attached picture), which is causing some visual glitches. However, another loop of remove/use during the next event seems to fix that.
    is that a problem on my side?

RE: Change bootstrap3 theme on the fly - Added by Roel Standaert almost 4 years ago

I don't seem to experience the same issue with the little bit of test code I wrote. Note: in this test code I put the bootstrap.min.css for darkly and flatly in two directories in the docroot, one named darkly, one named flatly.

I have to removeStyleSheet in the reverse order (otherwise I get really bad rendering)

What do you mean by that? Are you loading multiple stylesheets?

Regards,

Roel

RE: Change bootstrap3 theme on the fly - Added by Emeric Poupon almost 4 years ago

Find attached my current code, it may be easier to understand.

Yes, I actually have 4 files.

Here is the output:

Startup:
[2020-Apr-16 15:59:17.150] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/bootstrap-flatly.min.css'
[2020-Apr-16 15:59:17.150] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'resources/themes/bootstrap/3/wt.css'
[2020-Apr-16 15:59:17.150] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/lms.css'
[2020-Apr-16 15:59:17.150] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/lms-flatly.css'
Switch:
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Removing css file 'css/lms-flatly.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Removing css file 'css/lms.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Removing css file 'resources/themes/bootstrap/3/wt.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Removing css file 'css/bootstrap-flatly.min.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/bootstrap-darkly.min.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'resources/themes/bootstrap/3/wt.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/lms.css'
[2020-Apr-16 15:59:20.303] 28789 [/ ePkEju2GogIzL2Ha] [debug] - [UI] Adding css file 'css/lms-darkly.css'

I still get both files loaded in chrome

    (1-8/8)