2

I am following the excellent example I found here: CSS - How to Style a Selected Radio Buttons Label? trying to style a group of radio-buttons which I create dynamically using javascript. While I manage to create the buttons, I can't find a solution on how to change the background of the label of the radio button that is currently selected. In my example the color only changes during hovering but flips back to normal besides being selected.

My code on JSFiddle: https://jsfiddle.net/dsarh65p/2/

For reference:

HTML

<html>
  <head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
    <div class="btn-group" data-toggle="buttons">
      <span id=car></span>
    </div>
  </body>
</html>

JS

var array = ["Saab", "Volvo", "BMW"];
var item = document.createElement('div');
item.className = 'radio-toolbar';

for (var i = 0; i < array.length; i++) {

  var input = document.createElement('input');
  var input_label = document.createElement('label');

  input.type = 'radio';
  input.name = 'radio-btn';
  input.id = 'radio' + i;
  input.value = "true";
  input_label.innerHTML = array[i];

  input_label.setAttribute("class", "btn btn-primary");
  input_label.appendChild(input);


  item.appendChild(input_label);
  document.getElementById("car").appendChild(item);
}

CSS

.radio-toolbar input[type="radio"] {
  display: none;
}

.radio-toolbar label {
  display: inline-block;
  background-color: #ddd;
  padding: 4px 11px;
  font-family: Arial;
  font-size: 16px;
  cursor: pointer;
}

.radio-toolbar input[type="radio"]:checked {
  background-color: #bbb;
}
AaronDT
  • 3,940
  • 8
  • 31
  • 71

2 Answers2

2

var array = ["Saab", "Volvo", "BMW"];
var item = document.createElement('div');
item.className = 'radio-toolbar';

for (var i = 0; i < array.length; i++) {

  var input = document.createElement('input');
  var input_label = document.createElement('label');

  input.type = 'radio';
  input.name = 'radio-btn';
  input.id = 'radio' + i;
  input.value = "true";
  input_label.innerHTML = array[i];

  input_label.addEventListener('click', function(element) {
    document.querySelectorAll('.radio-toolbar label').forEach((labelEl) => {
      labelEl.selected = false;
      labelEl.style.backgroundColor = '#ddd';
    });
    element.selected = true;
    element.style.backgroundColor = 'red';
  }.bind(this, input_label));

  input_label.setAttribute("class", "btn btn-primary");
  input_label.appendChild(input);



  item.appendChild(input_label);
  document.getElementById("car").appendChild(item);
}
.radio-toolbar input[type="radio"] {
  display: none;
}

.radio-toolbar label {
  display: inline-block;
  background-color: #ddd;
  padding: 4px 11px;
  font-family: Arial;
  font-size: 16px;
  cursor: pointer;
}

.radio-toolbar input[type="radio"]:checked {
  background-color: #bbb;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />


<body>
  <div class="btn-group" data-toggle="buttons">
    <span id=car></span>
  </div>
</body>

Link: https://jsfiddle.net/dsarh65p/24/

EDIT:

Updated fiddle with single listener and class names: https://jsfiddle.net/dsarh65p/26/

ksav
  • 20,015
  • 6
  • 46
  • 66
Saurabh Nemade
  • 1,522
  • 2
  • 11
  • 20
0

I have updated your fiddle here: https://jsfiddle.net/urbandrone/y49df8wv/1/

Also, I added comments everywhere I changed your code. Basically, what you want to do is not wrap <input> elements inside a <label>, but rather next to it and connect both of them via the id attribute of the <input> and the for attribute of the <label>. This way, you can change the background color of the label with CSS only, which is almost always nicer than having to use JavaScript.


HTML

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
  <div class="btn-group" data-toggle="buttons">
    <span id=car></span>
  </div>
</body>
</html>

CSS

.radio-toolbar input[type="radio"] {
    display: none;
}

.radio-toolbar label {
    display: inline-block;
    background-color: #ddd;
    padding: 4px 11px;
    font-family: Arial;
    font-size: 16px;
    cursor: pointer;
}

.radio-toolbar .radio {     /* style the wrapper */
    position: relative;     /* allows to "hide" the radio with absolute positioning (won't occupy space) */
    display: inline-block;  /* show wrappers in horizontal line */
}

.radio-toolbar input[type="radio"] { /* hide the <input> */
    position: absolute;
    z-index: -1;
}

.radio-toolbar input[type="radio"]:checked + label { /* target the <label> */
    background-color: #000;                          /* changed to more obvious color */
}

JS

var array = ["Saab", "Volvo", "BMW"];
var item = document.createElement('div');
item.className = 'radio-toolbar';

for (var i = 0; i < array.length; i++) {

  var wrapper = document.createElement('div'); // <-- create a wrapper element
  var input = document.createElement('input');
  var input_label = document.createElement('label');

  input.type = 'radio';
  input.name = 'radio-btn';
  input.id = 'radio' + i;
  input.checked = i === 0;
  input.value = array[i]; // <-- <input>s should have different values

  input_label.htmlFor = 'radio' + i; // <-- connect label to <radio> via for-attribute
  input_label.innerHTML = array[i];
  input_label.className = "btn btn-primary";
  input_label.appendChild(input);

  wrapper.className = 'radio';      // <-- add a class to the wrapper
  wrapper.appendChild(input);       // <-- add the <input>
  wrapper.appendChild(input_label); // <-- add the <label>


  item.appendChild(wrapper);        // <-- add wrapper to toolbar
  document.getElementById("car").appendChild(item);
}
David
  • 3,552
  • 1
  • 13
  • 24