0

This question is very similar to the one previously posted at: how-to-toggle-the-check-state-of-a-radio-input-element-on-click but the answer shared there only works when each input element is in its own separate div container; however, I need it to work for a specific HTML structure where all the radial inputs are instead at the same level directly inside a single parent div (I think this would probably be a more common structure for people anyway).

In the following example, I have three radio buttons acting as tabs for a tabbed section. The round button images are hidden using CSS, but the labels turn white when the radio input is: checked. The reason for this particular HTML structure is because the radio inputs must all be under the same parent at the same level as, but earlier than, the displayable content of the tabbed section in order for that hidden content to then be shown following the buttons, using a CSS selector like: #tab-1:checked ~ #tab-content-1{display:block}.

So while the given CSS wasn't absolutely necessary to be provided for this example, it has been included to indicate a reason for keeping the HTML structure intact.

Here's the code:

/* The attributes in .tab-container are likely non-essential*/
.tab-container{
  display:block; 
  margin:1rem;
}
.tab-label {
  display:inline-block;
  background: #eee; 
  border: 1px solid; 
}
[name="tab-group-1"] {
  display: none;  
}
[name="tab-group-1"]:checked + .tab-label {
  background: white;
  border-bottom: 1px solid white;
}
#tab-1 ~ #tab-content-1, #tab-2 ~ #tab-content-2, #tab-3 ~ #tab-content-3 {
  display:none;
}
#tab-1:checked ~ #tab-content-1, #tab-2:checked ~ #tab-content-2, #tab-3:checked ~ #tab-content-3 {
  display:block;
  align-self:bottom;
  border:1px solid;
  margin-top:-1px;    
}
<div class="tab-container">
    
       <input type="radio" id="tab-1" name="tab-group-1" checked><!--newline
       --><label class="tab-label" for="tab-1">Tab One</label><!--newline
       --><input type="radio" id="tab-2" name="tab-group-1"><!--newline
       --><label class="tab-label" for="tab-2">Tab Two</label><!--newline
       --><input type="radio" id="tab-3" name="tab-group-1"><!--newline
       --><label class="tab-label" for="tab-3">Tab Three</label><!--newline
       -->
       <div class="content" id="tab-content-1">
           stuff 1
       </div> 
       <div class="content" id="tab-content-2">
           stuff 2
       </div>
       <div class="content" id="tab-content-3">
           stuff 3
       </div> 
   
    
</div>
Stuff at the end is not covered up...

Ultimately, it would be nice to be able to achieve a responsive tabbed container like this using only HTML and CSS (no JS), and it would be nice to be able to toggle the radio button off with CSS using something like: #tab-1:checked:focus{checked:false;} but for the time being, I think some JS will have to be used just for this purpose of toggling a radio button off when it is toggled from a checked state.

Thanks for your help.

Community
  • 1
  • 1
Damian Green
  • 633
  • 2
  • 8
  • 13

1 Answers1

0

Here's the solution to my own question:

/*======== Toggle Off Selected Tab ==========*/
var whichOneWasClickedBefore_suffix = "0";
// First, we must get the id of the initial checked radio, if one has been identified in the html... 
var radios = document.querySelectorAll('input[type="radio"]:checked');
var radios = document.getElementsByName('tab-group-1');
for ( var i = 0; i < radios.length; i++) {
    if(radios[i].checked) {
         whichOneWasClickedBefore_suffix = (i+1).toString();
        break;
    }
}
//// Next, we get which button was selected, compare it to the previous value, and uncheck it if they match.
$("[id^=thistab-]").click(function(event){
 var whichOneWasClickedAfter =  event.target.id;
  var whichOneWasClickedAfter_suffix = whichOneWasClickedAfter.match(/\d$/).shift();

  if (!whichOneWasClickedBefore_suffix.localeCompare(whichOneWasClickedAfter_suffix)){
   whichOneWasClickedBefore_suffix = "0";
    $(this).prop('checked', false);  
  }else{
    whichOneWasClickedBefore_suffix = whichOneWasClickedAfter_suffix;
  };

});
/*======== END Toggle Off Selected Tab ==========*/
/* The attributes in .tab-container are likely non-essential*/
.tab-container{
  display:block; 
  margin:1rem;
}
.tab-label {
  display:inline-block;
  background: #eee; 
  border: 1px solid; 
}
[name="tab-group-1"] {
  display: none;  
}
[name="tab-group-1"]:checked + .tab-label {
  background: white;
  border-bottom: 1px solid white;
}
#thistab-1 ~ #tab-content-1, #thistab-2 ~ #tab-content-2, #thistab-3 ~ #tab-content-3 {
  display:none;
}
#thistab-1:checked ~ #tab-content-1, #thistab-2:checked ~ #tab-content-2, #thistab-3:checked ~ #tab-content-3 {
  display:block;
  align-self:bottom;
  border:1px solid;
  margin-top:-1px;    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab-container">
    
       <input type="radio" id="thistab-1" name="tab-group-1" ><!--newline
       --><label class="tab-label" for="thistab-1">Tab One</label><!--newline
       --><input type="radio" id="thistab-2" name="tab-group-1" checked><!--newline
       --><label class="tab-label" for="thistab-2">Tab Two</label><!--newline
       --><input type="radio" id="thistab-3" name="tab-group-1"><!--newline
       --><label class="tab-label" for="thistab-3">Tab Three</label><!--newline
       -->
       <div class="content" id="tab-content-1">
           stuff 1
       </div> 
       <div class="content" id="tab-content-2">
           stuff 2
       </div>
       <div class="content" id="tab-content-3">
           stuff 3
       </div> 
   
    
</div>
Stuff at the end is not covered up...

Note: this uses JQuery; it is also a fully responsive tab container, much better, I think, than the other one posted earlier by Kumar.

Damian Green
  • 633
  • 2
  • 8
  • 13
  • I find it interesting that after 24 hours, this post has been viewed 40 times and no one else was able to post a solution... There may be a better solution (I'm not super strong with JS and JQuery), but after spending an entire day working on this I figured I should post my solution. Hard to believe that it is 2017 and this can't yet be done without JS. It would be nice to see a new HTML element just to handle tabs like this; perhaps in HTML6. Anyway, here's to bettering the world... – Damian Green Mar 08 '17 at 06:41