mKane
mKane

Reputation: 982

Set Dark mode on an AngularJS project

I currently have an AngularJS project that I am setting up for Dark Mode.

This is a legacy app and is pretty complex and would not like to clone the css file.

Right now it works by listening for a media query from the OS and overrides some classes.

I have tried

document.documentElement.setAttribute('data-theme', 'light');

also

angular.element(document.documentElement).setAttribute("data-theme", "dark");;

But I do not see any changes.

I cannot seem to find a way to change the @media (prefers-color-scheme: dark) preference using JS.

Is there a way to override the OS inside if the scope of angular?

Upvotes: 3

Views: 2074

Answers (2)

Michail Markou
Michail Markou

Reputation: 41

You can actually do it pretty easily but its better to have some Database to store userSettingsTable colortheme information propertie as #000000 or #FFFFFF and get the information or set everytime that a user Click on color changetheme in order to keep it globally in all pages Changed !.

here is an example of what you can do

-------------inside HTML under body tag---------

first you must declare the controller + app ng-app="yourname" ng-controller="yourname" below that

<style ng-init=checkcolor()>
    body{
        background-color: {{colortheme}};
    }
</style>

---------Inside Controller------

$scope.changeTheme = function (colortheme){
if(colortheme == '#000'){
    $scope.colortheme = '#FFF';
      $http({
                method: "POST",
                url: "fetch_data_user_colortheme.php",
                data: {'user_profile':$scope.user_profile, 'color':$scope.colortheme,'action':'setcolor'}
            }).then(function(response) {
                console.log('changed to WHITE');
                console.log($scope.user_profile);
                console.log($scope.colortheme);
            })

} else if (colortheme == '#FFF') {
    $scope.colortheme = '#000';
      $http({
                method: "POST",
                url: "fetch_data_user_colortheme.php",
                data: {'user_profile':$scope.user_profile, 'color':$scope.colortheme,'action':'setcolor'}
            }).then(function(response) {
                console.log(response.data);
                console.log('changed to DARK');
                console.log($scope.user_profile);
                console.log($scope.colortheme);
            })
}
}

$scope.checkcolor = function (){
    $http({
                method: "POST",
                url: "fetch_data_user_colortheme.php",
                data: {'user_profile':$scope.user_profile, 'action':'getcolor'}
            }).then(function(response) {
                console.log(response.data);
                $scope.colortheme = response.data.toString();
                console.log($scope.colortheme.toString());
            })//user_profile is Database fetched user that i got it like this
              //<td><input type="hidden" ng-init="user_profile='<?php echo 
              //$user['email']; ?>'"></td>
}

-----------inside model/backend e.g PHP--------------

<?php

//fetch_data_user_colortheme.php

$connect = new PDO("mysql:host=localhost;dbname=cinema_db", "root", "");

$form_data = json_decode(file_get_contents("php://input"));

if ($form_data->action == 'getcolor') {
    $query = "SELECT colortheme FROM usersettingstable 
    WHERE user_fk='".$form_data->user_profile."'";

    $statement = $connect->prepare($query);

    if ($statement->execute()) {
        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
            $data[] = $row['colortheme'];
        }
    }
}
//database RELATIONAL that why i update user_fk as well has constraints 
//foreign key entry name usersettingstable with id A.I user_fk to idendity 
//unique and 
//color setting
elseif ($form_data->action == 'setcolor') {
    $query = "
    UPDATE usersettingstable 
    SET user_fk='".$form_data->user_profile."', colortheme='".$form_data->color."'
    ";
    $statement = $connect->prepare($query);
    if($statement->execute())
    {
       
    }
    $query = "SELECT colortheme FROM usersettingstable 
              WHERE user_fk='".$form_data->user_profile."'";
    $statement = $connect->prepare($query);
    if ($statement->execute()) {
        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        $data[] = $row['colortheme'];
    }
  }
}
 echo json_encode($data);

?>

also keep in mind the function checkcolor() and only that must be included in other pages as well with a kind of controller callling it with ng-init="checkcolor()" anywhere so the color in other pages is carry over as well and maybe just maybe you need to adjust it a little bit like

             $scope.checkcolor = function (){
                $http({
                method: "POST",
                url: "fetch_data_user_colortheme.php",
                data: {'user_profile':$scope.user_profile, 
               'action':'getcolor'}
            }).then(function(response) {
                console.log(response.data);
                $scope.colortheme = response.data.toString();
                console.log($scope.colortheme.toString());
               document.body.style.background = $scope.colortheme;

            })
          }

Upvotes: 1

zero298
zero298

Reputation: 26899

If you are trying to control theme through @media (prefers-color-scheme: dark) {...}, there is nothing at the JavaScript level that you can do to adjust it. This media piece is set by the user-agent or maybe even the OS in the case of macOS.

Consider the following images that are produced with the same code just varied by what I tell my OS to prefer in terms of themes:

Light Theme

Dark Theme

p {
background-color: white;
color: black;
}

@media (prefers-color-scheme: dark) {
 p {
 background-color: black;
 color: white;
 }
}
<p>Hello World!</p>


If you want to be able to control this with JavaScript, you'll need to do this with CSS classes:

const app = document.getElementById("app");
const lightBtn = document.getElementById("light");
const darkBtn = document.getElementById("dark");

lightBtn.addEventListener("click", () => {
  app.classList.remove("dark");
  app.classList.add("light");
});

darkBtn.addEventListener("click", () => {
  app.classList.remove("light");
  app.classList.add("dark");
});
#app.light,
#app.light p,
#app.light button {
  background-color: white;
  color: black;
}

#app.dark,
#app.dark p,
#app.dark button {
  background-color: black;
  color: white;
}
<div id="app">
  <p>Hello World!</p>
  <button id="dark">Dark</button>
  <button id="light">Light</button>
</div>

Upvotes: 2

Related Questions