Reputation: 982
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
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
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:
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