I am constructing a Likert-scale in a HTML table. I need the following features:
- Selected radio button can be unselected by clicking on it again
- Selecting and unselecting the radio button must be doable by clicking on the table cell that the radio button is located in.
I was able to make 1. work but I am struggling with 2. I tried variations with <label> but without success or with undermining 1.
What is the cleanest way to do this? It seems that this should be a common design.
This is the current state:
var allRadios = document.querySelectorAll('input[type=radio]');
var booRadio;
var x = 0;
for (x = 0; x < allRadios.length; x++) {
allRadios[x].onclick = function() {
if (booRadio == this) {
this.checked = false;
booRadio = null;
} else {
booRadio = this;
}
};
}
table {
width: 90%;
}
.tg {
border-collapse: collapse;
border-spacing: 0;
}
.tg td {
border-color: black;
border-style: solid;
border-width: 1px;
overflow: hidden;
padding: 9px 11px;
word-break: normal;
}
.tg th {
border-color: black;
border-style: solid;
border-width: 1px;
font-family: Arial, sans-serif;
font-size: 13px;
font-weight: normal;
overflow: hidden;
padding: 9px 11px;
word-break: normal;
}
.tg .tg-vt7q {
border-color: #c0c0c0;
text-align: right;
vertical-align: top;
}
.tg .tg-wo29 {
border-color: #c0c0c0;
text-align: center;
vertical-align: center;
}
.tg .tg-wo30 {
border-color: #c0c0c0;
text-align: left;
vertical-align: top;
}
.tg .tg-wo31 {
border-color: #c0c0c0;
text-align: left;
vertical-align: bottom;
}
.tg .tg-wo32 {
border-color: #c0c0c0;
text-align: right;
vertical-align: bottom;
}
.tg .tg-wo33 {
border-color: #c0c0c0;
text-align: center;
vertical-align: bottom;
}
.item {
height: 0px;
}
label {
cursor: pointer;
display: block;
text-align: center;
}
<table class="tg">
<thead>
<col width="200px">
<col width="50px">
<col width="50px">
<col width="50px">
<col width="50px">
<tr>
<th class="tg-wo29"></th>
<th class="tg-wo31" colspan="2">Gar nicht<br>hilfreich</th>
<th class="tg-wo32" colspan="2">Sehr<br>hilfreich</th>
</tr>
<tr>
<th class="tg-wo29"></th>
<th class="tg-wo33">0</th>
<th class="tg-wo33">1</th>
<th class="tg-wo33">2</th>
<th class="tg-wo33">3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-wo30">
<div class="item" id="r1">
</div>
</td>
<td class="tg-wo29">
<input type="radio" id="r1_0" name="r1" value="0" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_1" name="r1" value="1" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_2" name="r1" value="2" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_3" name="r1" value="3" />
</td>
</tr>
<tr>
<td class="tg-wo30">
<div class="item" id="r2">
</div>
</td>
<td class="tg-wo29">
<input type="radio" id="r2_0" name="r2" value="0" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_1" name="r2" value="1" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_2" name="r2" value="2" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_3" name="r2" value="3" />
</td>
</tr>
</tbody>
</table>
https://jsfiddle.net/eL10qo6g/
>Solution :
you can achieve that like this
var allRadios = document.querySelectorAll('input[type=radio]');
allRadios.forEach(radioBtn => {
// add click event to the parent which is td element
radioBtn.parentNode.addEventListener('click', ()=> {
// do the opposite when clicking (toggle between checked and unchecked)
radioBtn.checked = radioBtn.checked == false ? true : false;
})
})
table {
width: 90%;
}
.tg {
border-collapse: collapse;
border-spacing: 0;
}
.tg td {
border-color: black;
border-style: solid;
border-width: 1px;
overflow: hidden;
padding: 9px 11px;
word-break: normal;
}
.tg th {
border-color: black;
border-style: solid;
border-width: 1px;
font-family: Arial, sans-serif;
font-size: 13px;
font-weight: normal;
overflow: hidden;
padding: 9px 11px;
word-break: normal;
}
.tg .tg-vt7q {
border-color: #c0c0c0;
text-align: right;
vertical-align: top;
}
.tg .tg-wo29 {
border-color: #c0c0c0;
text-align: center;
vertical-align: center;
}
.tg .tg-wo30 {
border-color: #c0c0c0;
text-align: left;
vertical-align: top;
}
.tg .tg-wo31 {
border-color: #c0c0c0;
text-align: left;
vertical-align: bottom;
}
.tg .tg-wo32 {
border-color: #c0c0c0;
text-align: right;
vertical-align: bottom;
}
.tg .tg-wo33 {
border-color: #c0c0c0;
text-align: center;
vertical-align: bottom;
}
.item {
height: 0px;
}
label {
cursor: pointer;
display: block;
text-align: center;
}
<table class="tg">
<thead>
<col width="200px">
<col width="50px">
<col width="50px">
<col width="50px">
<col width="50px">
<tr>
<th class="tg-wo29"></th>
<th class="tg-wo31" colspan="2">Gar nicht<br>hilfreich</th>
<th class="tg-wo32" colspan="2">Sehr<br>hilfreich</th>
</tr>
<tr>
<th class="tg-wo29"></th>
<th class="tg-wo33">0</th>
<th class="tg-wo33">1</th>
<th class="tg-wo33">2</th>
<th class="tg-wo33">3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-wo30">
<div class="item" id="r1">
</div>
</td>
<td class="tg-wo29">
<input type="radio" id="r1_0" name="r1" value="0" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_1" name="r1" value="1" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_2" name="r1" value="2" />
</td>
<td class="tg-wo29">
<input type="radio" id="r1_3" name="r1" value="3" />
</td>
</tr>
<tr>
<td class="tg-wo30">
<div class="item" id="r2">
</div>
</td>
<td class="tg-wo29">
<input type="radio" id="r2_0" name="r2" value="0" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_1" name="r2" value="1" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_2" name="r2" value="2" />
</td>
<td class="tg-wo29">
<input type="radio" id="r2_3" name="r2" value="3" />
</td>
</tr>
</tbody>
</table>