CSS check box, how to make an item unchecked only if another one is checked


Tags: javascript,jquery,html,css

Problem :

I am trying to create some sort of slide show based on CSS Checkbox. So corresponding data is visible when its button is pressed. But the issue is the data disappear if the button is pressed again. I want to make it in a way what once a button is pressed and its data is visible, it only disappear when another button is pressed. So it won't be on and off but on unless another button is pressed.

Here is the DEMO

$.fn.MP = function(options) {
  var settings = $.extend({
    // These are the defaults
    text: ""
  }, options);

  $(this).on("click tap", "input", function() {
    $(this).parent().siblings().find("input").prop("checked", false);
  });
};

// dynamically-generate id/for values
$('div.panel').each(function(index, el) {
    var $panel = $(el);
    var panelId = $panel.attr('id');
    var $panelBottom = $('div.panelBottom', $panel);

    $('div.panelTop > div > input', $panel).each(function(indexInput, elInput) {
        var $input = $(elInput);
        var inputId = panelId + '-box-' + indexInput;

        $input.attr('id', inputId);
        $('label:nth(' + indexInput + ')', $panelBottom).attr('for', inputId);
    });
});

$("#item1").MP({});
$("#item2").MP({});
input[type="checkbox"] {
  position: absolute;
  opacity: 0;
}

.panelTop > div div {
  display: none;
}

.panelTop > div input[type="checkbox"]:checked ~ div {
  display: block;
}

.panel {
  width: 400px;
  height: 100px;
  border: 1px solid black;
}

.panel > .panelTop {
  width: 100%;
  height: 49px;
  border-bottom: 1px dashed black;
}

.panel > .panelBottom {
  width: 100%;
  height: 50px;
}

.panel > .panelTop > div div {
  width: 24px;
  height: 24px;
  float: right;
  margin: 0px 9px 0 0;
  border: 1px dashed black;
}

.panel > .panelBottom > div {
  width: 32px;
  height: 32px;
  float: right;
  margin: 9px 9px 0 0;
  border: 1px solid black;
  text-align: center;
  font-size: 22px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel" id="item1">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="checkbox" checked>
      <div>1.1</div>
      <div>1.2</div>
      <div>1.3</div>
    </div>
    <div>
      <input type="checkbox">
      <div>2.1</div>
      <div>2.2</div>
      <div>2.3</div>
    </div>
    <div>
      <input type="checkbox">
      <div>3.1</div>
      <div>3.2</div>
      <div>3.3</div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>
<div class="panel" id="item2">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="checkbox" checked>
      <div>1.1</div>
      <div>1.2</div>
      <div>1.3</div>
    </div>
    <div>
      <input type="checkbox">
      <div>2.1</div>
      <div>2.2</div>
      <div>2.3</div>
    </div>
    <div>
      <input type="checkbox">
      <div>3.1</div>
      <div>3.2</div>
      <div>3.3</div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>

Now in the above example the data corresponding to button 1 is visible. if you press the same button again, its data disappears. I want it to work in a way that the button only shows data and data only disappears when a different button is pressed.

Any idea to achieve that?



Solution :

You can just use input[type=radio] instead.

$.fn.MP = function(options) {
  var settings = $.extend({
    // These are the defaults
    text: ""
  }, options);

  $(this).on("click tap", "input", function() {
    $(this).parent().siblings().find("input").prop("checked", false);
  });
};

// dynamically-generate id/for values
$('div.panel').each(function(index, el) {
  var $panel = $(el);
  var panelId = $panel.attr('id');
  var $panelBottom = $('div.panelBottom', $panel);

  $('div.panelTop > div > input', $panel).each(function(indexInput, elInput) {
    var $input = $(elInput);
    var inputId = panelId + '-box-' + indexInput;

    $input.attr('id', inputId);
    $('label:nth(' + indexInput + ')', $panelBottom).attr('for', inputId);
  });
});

$("#item1").MP({});
$("#item2").MP({});
input[type="radio"] {
  position: absolute;
  opacity: 0;
}
.panelTop > div div {
  display: none;
}
.panelTop > div input[type="radio"]:checked ~ div {
  display: block;
}
.panel {
  width: 400px;
  height: 100px;
  border: 1px solid black;
}
.panel > .panelTop {
  width: 100%;
  height: 49px;
  border-bottom: 1px dashed black;
}
.panel > .panelBottom {
  width: 100%;
  height: 50px;
}
.panel > .panelTop > div div {
  width: 24px;
  height: 24px;
  float: right;
  margin: 0px 9px 0 0;
  border: 1px dashed black;
}
.panel > .panelBottom > div {
  width: 32px;
  height: 32px;
  float: right;
  margin: 9px 9px 0 0;
  border: 1px solid black;
  text-align: center;
  font-size: 22px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel" id="item1">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" checked>
      <div>1.1</div>
      <div>1.2</div>
      <div>1.3</div>
    </div>
    <div>
      <input type="radio">
      <div>2.1</div>
      <div>2.2</div>
      <div>2.3</div>
    </div>
    <div>
      <input type="radio">
      <div>3.1</div>
      <div>3.2</div>
      <div>3.3</div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>
<div class="panel" id="item2">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" checked>
      <div>1.1</div>
      <div>1.2</div>
      <div>1.3</div>
    </div>
    <div>
      <input type="radio">
      <div>2.1</div>
      <div>2.2</div>
      <div>2.3</div>
    </div>
    <div>
      <input type="radio">
      <div>3.1</div>
      <div>3.2</div>
      <div>3.3</div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>


As a side note, you can take advantage of the CSS counter() function here. (Everything is declared at the bottom of the CSS for clarity).

$.fn.MP = function(options) {
  var settings = $.extend({
    // These are the defaults
    text: ""
  }, options);

  $(this).on("click tap", "input", function() {
    $(this).parent().siblings().find("input").prop("checked", false);
  });
};

// dynamically-generate id/for values
$('div.panel').each(function(index, el) {
  var $panel = $(el);
  var panelId = $panel.attr('id');
  var $panelBottom = $('div.panelBottom', $panel);

  $('div.panelTop > div > input', $panel).each(function(indexInput, elInput) {
    var $input = $(elInput);
    var inputId = panelId + '-box-' + indexInput;

    $input.attr('id', inputId);
    $('label:nth(' + indexInput + ')', $panelBottom).attr('for', inputId);
  });
});

$("#item1").MP({});
$("#item2").MP({});
input[type="radio"] {
  position: absolute;
  opacity: 0;
}
.panelTop > div div {
  display: none;
}
.panelTop > div input[type="radio"]:checked ~ div {
  display: block;
}
.panel {
  width: 400px;
  height: 100px;
  border: 1px solid black;
}
.panel > .panelTop {
  width: 100%;
  height: 49px;
  border-bottom: 1px dashed black;
}
.panel > .panelBottom {
  width: 100%;
  height: 50px;
}
.panel > .panelTop > div div {
  width: 24px;
  height: 24px;
  float: right;
  margin: 0px 9px 0 0;
  border: 1px dashed black;
}
.panel > .panelBottom > div {
  width: 32px;
  height: 32px;
  float: right;
  margin: 9px 9px 0 0;
  border: 1px solid black;
  text-align: center;
  font-size: 22px;
}
.panelTop {
  counter-reset: my-counter;
}
.panelTop > div {
  counter-increment: my-counter;
  counter-reset: sub-counter;
}
.panelTop > div > div {
  counter-increment: sub-counter;
}
.panelTop > div > div::before {
  content: counter(my-counter)"." counter(sub-counter)" ";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel" id="item1">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" checked>
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>
<div class="panel" id="item2">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" checked>
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>


EDIT:

To take full advantage of the radio group, and for this to work without:

  $(this).on("click tap", "input", function() {
    $(this).parent().siblings().find("input").prop("checked", false);
  });

You have to give the same value to the attribute name on each radio in the input group.

$.fn.MP = function(options) {
  var settings = $.extend({
    // These are the defaults
    text: ""
  }, options);

};

// dynamically-generate id/for values
$('div.panel').each(function(index, el) {
  var $panel = $(el);
  var panelId = $panel.attr('id');
  var $panelBottom = $('div.panelBottom', $panel);

  $('div.panelTop > div > input', $panel).each(function(indexInput, elInput) {
    var $input = $(elInput);
    var inputId = panelId + '-box-' + indexInput;

    $input.attr('id', inputId);
    $('label:nth(' + indexInput + ')', $panelBottom).attr('for', inputId);
  });
});

$("#item1").MP({});
$("#item2").MP({});
input[type="radio"] {
  position: absolute;
  opacity: 0;
}
.panelTop > div div {
  display: none;
}
.panelTop > div input[type="radio"]:checked ~ div {
  display: block;
}
.panel {
  width: 400px;
  height: 100px;
  border: 1px solid black;
}
.panel > .panelTop {
  width: 100%;
  height: 49px;
  border-bottom: 1px dashed black;
}
.panel > .panelBottom {
  width: 100%;
  height: 50px;
}
.panel > .panelTop > div div {
  width: 24px;
  height: 24px;
  float: right;
  margin: 0px 9px 0 0;
  border: 1px dashed black;
}
.panel > .panelBottom > div {
  width: 32px;
  height: 32px;
  float: right;
  margin: 9px 9px 0 0;
  border: 1px solid black;
  text-align: center;
  font-size: 22px;
}
.panelTop {
  counter-reset: my-counter;
}
.panelTop > div {
  counter-increment: my-counter;
  counter-reset: sub-counter;
}
.panelTop > div > div {
  counter-increment: sub-counter;
}
.panelTop > div > div::before {
  content: counter(my-counter)"." counter(sub-counter)" ";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel" id="item1">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" name="item1" checked>
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio" name="item1">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio" name="item1">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>
<div class="panel" id="item2">
  <div class="panelTop">
    Dependant Buttons:
    <div>
      <input type="radio" name="item2" checked>
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio" name="item2">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div>
      <input type="radio" name="item2">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
  <div class="panelBottom">
    Main Buttons:
    <label class="btn1">1</label>
    <label class="btn2">2</label>
    <label class="btn3">3</label>
  </div>
</div>


    CSS Howto..

    How can I put a inside of an ? [duplicate]

    How to force CSS to be displayed on empty element following whitespace

    CSS how to fill height of container?

    CSS - how to make content fit to the width/height of paragraph?

    How can I remove the generic HTML/CSS tooltip? [duplicate]

    Parsing awful HTML: How do I recognize boundaries with xpath?

    How to make this type of image popping out of box using XHTML css

    How to add new line in a Bootstrap button using CSS

    CSS breadcrumb - how to make radius small

    How to stop CSS/HTML navigation menu wrapping at different resolutions?

    css nested classes, how to not repeat code?

    How to make element instantly go back to initial position after CSS animation end?

    How to use this CSS font technique?

    How to prevent transition to run on page load after height is set with javascript in Safari?

    How to change radio button place & add line separator

    CSS: How to increase distance between two elements?

    How to make sure that different severity Toasters are shown differently?

    How do I wrap a overflowed span in fixed div

    How to wrap a vertical overflow horizontally in css?

    CSS how to height step arrow

    CSS: How to get lines to “line up” accross different columns?

    How to set borders between children from parent in CSS?

    How can I conditionally change css styles with js?

    How to format HTML/CSS to align with single word in sentence?

    How to vertically align lists when one li is a div

    How can I properly align two divs that fold atop each other when browser is shrinked?

    How to show a div thats hidden by css on button click

    How to make css transform-origin property work in IE7 and IE8?

    How do I keep an element scaled in CSS3 in-till mouseleave? Then on mouseleave scale the element back to it's original size

    How to Include Multiple Javascript Files in .NET (Like they do in rails)