Ways to modify the color of a container's border by interacting with radio buttons through JavaScript

I'm currently facing a challenge with creating a settings dropdown menu that allows users to select different themes. Each theme is supposed to modify the background color and border color, but I have successfully implemented only the background color change so far. Unfortunately, I'm struggling to figure out how to make the border color change as well.

function changeTheme() {
  if (document.getElementById("theme1").checked = true) {
    document.container.style.backgroundColor = "lightgray";
    document.container.style.borderColor = "red";
  }
}

function bgcolor(color, border) {
  document.body.style.background = color;
  document.body.style.borderColor = border;

}
<div class="dropdown">
  <input type="radio" id="theme1" name="theme" value="1" onclick="bgcolor('lightgray', 'red');" onchange="showFeedback('You changed the theme!')">Light<br><br>
</div>

The issue is that I have a square container in the middle of the page with a border, and when a theme is selected, the entire page's background color should change along with the border color of the central container. I attempted using onclick="changeTheme(), but it doesn't seem to be functioning properly.

Answer №1

In order to apply a border, you need to specify the thickness and style of it.

Avoid using inline styles or event handlers directly within the HTML code. Instead, assign a predefined class when an event occurs. Rather than checking if a radio button is selected, utilize the click event of the button. Once clicked, it's considered selected.

Moreover, if a form field is only serving as a user interface element and not intended for submitting data, omit the name attribute.

document.getElementById("theme1").addEventListener("click", function() {
  document.body.classList.add("lightTheme");  
});
.lightTheme { border:1px solid red; background-color:lightgrey; }
<div class="dropdown">
  <input type="radio" id="theme1" value="1">Light<br><br>
</div>

Answer №2

According to @Tyblitz's observation, the 'border' attribute must be properly configured:

function adjustStyle() {
  if (document.getElementById("style2").checked = true) {
    document.background.style.backgroundColor = "lightgray";
    document.background.style.borderColor = "red";
  }
}

function changeColor(color, border) {
  document.body.style.background = color;
  document.body.style.border = border;

}
<div class="dropdown">
  <input type="radio" id="theme1" 
   name="theme" value="1" 
   onclick="changeColor('lightgray', '6px solid red');"
   onchange="console.log('Theme altered!')">Light<br><br>
</div>

Answer №3

Update:
(Kudos to Scott Marcus for the insightful answer and Mike 'Pomax' Kamermans for the valuable comment)

Check out this pen.

I've implemented classes for different themes using a consistent naming convention: prefix "colorTheme" followed by the value of the input attribute.

function changeTheme() {
    /* Naming convention for theme class: prefix "colorTheme"
     followed by the input's value attribute */
    var themeClassValue = "colorTheme" + this.value;

    /* No action if clicking on the same input/label */
    if (themeClassValue != document.body.dataset.currentThemeClass) {

      document.body.classList.remove(document.body.dataset.currentThemeClass);
      document.body.classList.add(themeClassValue);
      /* Store new current theme value in custom data-current-theme-class attribute of body */
      document.body.dataset.currentThemeClass = themeClassValue;
    }
}

document.addEventListener('DOMContentLoaded', function () {
    /* Only needed at DOMContentLoaded, separate function created for this event */
    var selectedTheme = document.querySelector('input[id^="theme"]:checked');
    if (selectedTheme) {
        var themeClassValue = "colorTheme" + selectedTheme.value;
        document.body.classList.add(themeClassValue);
        document.body.dataset.currentThemeClass = themeClassValue;
    } else {
        /* If no input is checked, set data-current-theme-class to "null" */
        document.body.dataset.currentThemeClass = null;
    }
});

/* Select all inputs with id starting with "theme" */
var themeInputs = document.querySelectorAll('input[id^="theme"]');

for (let i = 0; i < themeInputs.length; i++) {
    themeInputs[i].addEventListener("click", changeTheme);
}


This method allows easy addition of new themes by following the established naming pattern.

function changeTheme() {
  /* Naming convention for theme class: prefix "colorTheme"
     followed by the input's value attribute */
  var themeClassValue = "colorTheme" + this.value;

  /* No action if clicking on the same input/label */
  if (themeClassValue != document.body.dataset.currentThemeClass) {

    document.body.classList.remove(document.body.dataset.currentThemeClass);
    document.body.classList.add(themeClassValue);
    /* Store new current theme value in custom data-current-theme-class attribute of body */
    document.body.dataset.currentThemeClass = themeClassValue;
  }
}

document.addEventListener('DOMContentLoaded', function() {
  /* Execute code only when DOM content is loaded */
  var selectedTheme = document.querySelector('input[id^="theme"]:checked');
  if (selectedTheme) {
    var themeClassValue = "colorTheme" + selectedTheme.value;
    document.body.classList.add(themeClassValue);
    document.body.dataset.currentThemeClass = themeClassValue;
  } else {
    /* If no input is checked, set data-current-theme-class to "null" */
    document.body.dataset.currentThemeClass = null;
  }
});

/* Select all inputs with id starting with "theme" */
var themeInputs = document.querySelectorAll('input[id^="theme"]');

for (let i = 0; i < themeInputs.length; i++) {
  themeInputs[i].addEventListener("click", changeTheme);
}
html {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  font-size: 16px;
}

*,
*::after,
*::before {
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  width: 100vw;
  border: 10px solid;
  border-color: transparent;
  -webkit-transition: all .4s;
  transition: all .4s;
}

ul {
  list-style: none;
  margin: 0;
  padding: 10px;
  font-size: 20px;
}

li {
  padding: 2px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

input,
label {
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  outline: none;
}

.colorTheme1 {
  color: rgb(36, 36, 33);
  font-weight: 400;
  background-color: rgb(248, 236, 220);
  border-color: rgb(60, 75, 124);
}

.colorTheme2 {
  background-color: rgb(39, 34, 28);
  border-color: rgb(102, 102, 153);
  color: rgb(248, 236, 220);
  font-weight: 700;
}

.colorTheme3 {
  background-color: rgb(255, 0, 0);
  border-color: rgb(0, 255, 255);
  color: rgb(255, 255, 0);
  font-weight: 700;
}
<body>
  <ul>
    <li><input type="radio" id="theme1" name="theme" value="1" checked><label for="theme1">Light</label></li>
    <li>
      <input type="radio" id="theme2" name="theme" value="2"><label for="theme2">Dark</label></li>
    <li>
      <input type="radio" id="theme3" name="theme" value="3"><label for="theme3">Flashy</label></li>
  </ul>
</body>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The v-for directive is displaying my list in a single row with multiple columns instead of in a single column with multiple rows

Can someone please assist in rendering my list as shown below: A B C The current rendering looks like this: 1: A 2: B 3: C Below is the code snippet: To-Do List: <input type="text" class = "todo" placeholder = "Next Item" v-on:keyup.enter="add ...

Ways to prompt the debugger to pause whenever a specific script file is called during execution in Edge/Chrome debugger

I am currently in the process of debugging a Typescript web application, which is quite new to me as I have never delved into web development before. This particular project entails multiple script files and various libraries. While running the applicatio ...

Having trouble with Vue component not showing updated data after axios POST request issue

Hi there, I'm facing an issue and could really use some guidance from a skilled Javascript Wizard. Here's the problem: I have a Laravel collection that I'm passing to a Vue component. Within the component, I am looping through the collecti ...

When the parent component in React JS rerenders, the props are not automatically passed down to the child

I have come across similar questions in the past, but I have not found any answers that directly address the issue I am facing in my scenario. In my case, there is a parent component that passes a property to a child component's state. Depending on t ...

What is the best way to convert exponential values to decimals when parsing JSON data?

var value = '{"total":2.47E-7}' var result = JSON.parse(value); Looking to convert an exponential value into decimal using JavaScript - any suggestions? ...

How can I switch out an item within FabricJS?

In order to incorporate undo and redo functionality, I have created an array named "history" that stores the most recent changes triggered by canvas.on() events. Displaying console.log: History: (3) […] ​ 0: Object { target: {…} } //initial object ...

React-select fails to trigger form submission when the Enter key is pressed

Currently, I am utilizing Formik and React-Select in my project, and I'm hoping to enable the form submission by pressing enter while focused on a select input. Interestingly, when I'm focused on any other input field and press Enter, the form s ...

Function starting too slow due to rapid Loading Spinner Image display

I am struggling with a function that is supposed to display the contents of posts when clicked on. My goal is to have a loading spinner appear for a few seconds before the post content shows up. However, I am facing an issue where the spinner only appears ...

Remove identical options from the dropdown menu

After hard-coding and adding items to the dropdown list for team size, such as 1, 2, 3, I am encountering an issue when loading it for editing or updating. Duplicate values are appearing in the list: 1 1 2 3 4... How can I remove these duplicate value ...

Are you curious about the array of elements in React's carousel?

I'm currently in the process of constructing a website using React, and I have a specific challenge related to the "news" section. Within this section, I have a list of three components that represent different news items. These components are housed ...

Perfect CSS Menu Hover Effect

I created my own navigation menu, and I'm struggling with one thing... How do I change the A tag color to white when hovering over the ul id "navitemul"? I've tried #lovedating#navitemul:hover #lovedating a {color:white} and other methods, but no ...

passing a variable from PHP to JavaScript

When I attempted to transfer variables from PHP to JavaScript, I found myself quite confused. It was straightforward for me to retrieve values using an ID, like this: var name = $("#name").val(); However, my question is if I want to convert a variable li ...

The jQuery bookmarklet in the djangobyexample book is completely unresponsive

As I work my way through Django By Example, I came across a chapter where a jQuery bookmarklet is created within a Django app. This allows users to easily save jpg images from websites into their user profile area within the Django app. Although the tutor ...

scraping mixed content from an HTML span using Selenium and XPath

Currently, I am attempting to extract information from a span element that contains various content. <span id="span-id"> <!--starts with some whitespace--> <b>bold title</b> <br/> text here that I want to grab.... < ...

The Full Screen Button on Google Maps isn't functioning properly in a third-party mapping application

Below you will see the '+' icon which is also supposed to function as the full screen button. https://i.stack.imgur.com/IMvHa.png However, when clicked on, it does not expand to full screen as intended. I have attempted using some basic jQuery ...

Could this be a problem within my recursive function?

Struggling to iterate through a stack of HTML Elements, I attempted to write a recursive function with no success. In the code snippet below, I'm facing challenges in returning a value from an if statement and ultimately from the function itself. Wh ...

Is there a way to ensure that when displaying information boxes with Bootstrap, the inputs do not get misplaced or shuffled to the wrong location

I have been working on a form that needs to display an alert: When clicking the button next to the input control, an alert should appear. Although the alert is showing correctly, the input controls are shifting to the wrong position afterwards: The desir ...

What is the best way to extract this content from the HTML using Selenium Webdriver?

My goal is to extract the text "1532.6788418669355" from this HTML code, but I've been facing challenges in doing so. Here's what I've attempted: IList options = Driver.FindElements(By.XPath(".//span//*")); Options[0].Text = "" There are n ...

Error Alert: UnhandledPromiseRejectionWarning in Async Series Causes Concern

I am currently working on a function in my project that uses the async series method to ensure specific tasks are executed in a certain order. In this case, function1 needs to be completed before function2, which must then be completed before function3. a ...

Show the correct URL address in the browser's address bar

My website utilizes Jquery/Ajax to dynamically load html pages into a specific div. By clicking on links with a certain class, the content opens up in this designated div, while the URL displayed in the address bar remains www.example.com. This setup allow ...