AnglerJS switch css theme for user select

I have downloaded themes from bootswatch and I am trying to allow the user to switch the theme. When the theme is switched, all bootstap css is temporarily gone until the new theme is loaded. How can I prevent changing before css is loaded, or revert to default theme before new one is loaded?

index.ejs (in the head)

<link rel="stylesheet" href="/external/bootstrap/css/bootstrap_yeti.min.css"
      ng-if="myTheme == ''">
<link rel="stylesheet" ng-href="/external/bootstrap/css/bootstrap_{{myTheme}}.min.css"
      ng-if="myTheme != ''">

      

Choice

<select class="form-control"
        id="theme"
        name="theme"
        ng-model="theme"
        ng-change="newTheme()">
  <option value="" disabled>Select Theme</option>
  <option ng-repeat="(key, val) in availableThemes" value="{{val}}">{{key}}</option>
</select>

      

controller by index

$scope.myTheme = '';
$rootScope.$watch('myTheme', function(value) {
  if (value != undefined) {
    $scope.myTheme = value;
  }
});

      

to choose

$scope.availableThemes = {
  Cerulean: 'cerulean',
  Cosmo:    'cosmo',
  Yeti:     'yeti'
};
$scope.newTheme = function() {
  console.log($scope.theme);
  if ($scope.theme != undefined) {
    $rootScope.myTheme = $scope.theme;
  }
}

      

Any help is appreciated! Thanks you

+3


source to share


4 answers


I think this is not an AngularJS problem. I think your approach should be different.

As I know, the functionality of a theme is usually done as shown below.



  • Create one CSS file for each theme (cerulean, cosmo, Yeti). You must edit the CSS files so that they don't conflict with each other. (put.cerulean, .cosmo, .yeti in front of all CSS selectors. If you use sass or less it will be much easier.)

  • Load all CSS files from HTML header.

    <link rel="stylesheet" href="/bootstrap/css/bootstrap_cerulean.min.css">
    <link rel="stylesheet" href="/bootstrap/css/bootstrap_cosmo.min.css">
    <link rel="stylesheet" href="/bootstrap/css/bootstrap_yeti.min.css">
    
          

  • If the user selects a theme, change the class of the body or root element to the appropriate theme name.

    <body class="cerulean">
    <body class="cosmo">
    <body class="yeti">
    
          

+5


source


I find it better to keep it simple and there is no need to preload all themes as others have suggested.

Stick to one tag with ng-href:

<link rel="stylesheet" ng-href="/external/bootstrap/css/bootstrap_{{myTheme}}.min.css">

      



And initialize myVar in your scope for "Yeti" in the index controller:

$scope.myTheme = 'yeti';
$rootScope.$watch('myTheme', function(value) {
  if (value != undefined) {
    $scope.myTheme = value;
  }
});

      

The rest remains unchanged.

+8


source


try this approach, it will work.

<link href="css/style1.css" ng-if="load">
<link href="css/style2.css" ng-if="!load">

<body>
<input type="button" ng-click="changeTheme()" value="Change Theme"/>
</body>
<script>
$scope.load=true;
$scope.changeTheme=function(){
$scope.load=!$scope.load;
}
<script>

      

+4


source


If you enabled all of your themes on first load, they should all be loaded by the browser. And it's not even clear if the user will switch themes. So why should you download all of them. So here are a few options.

1. Ng-if

Try to declare ng-if

beforelink

<link ng-if="theme" ng-href="{{theme}}">

      

I'm not sure if this will work, but I read somewhere that it worked for some people

2. Visibility

I am typing from ipad so bad.

Create a css file with something like this

Body .container {display:none}
Body .loader {display:block}

      

Place all content in a container class container. create a div class loader and place loader.

Download / concatenate this file first in your head. Then link your topic in each topic, add an override for those rules.

Body .container {display:block}
Body .loader {display:none}

      

So, at the moment of css reload you will have a loader animation.

+1


source







All Articles