Home > database >  Make table cell clickable with jQuery
Make table cell clickable with jQuery

Time:07-20

I have a small Quiz on a webpage with a table of questions. In each row are two possible answers, each has its own radio button for selection. Now my Problem, i want to make the whole cell clickable and not just the Radio button.

This is the code i came up with, but it only works once per radio button. After the first click, i have to click multiple times to switch the selection.

jQuery(".clickable").click(function(event) {
    var x = jQuery("input", this).attr("checked");
    jQuery("input", this).attr("checked", !x);
    return false;
});

Here is a sample row

<tr  id="quiz_row0">
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
        <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> 
            <span style="font-size: 20px;">Herausforderung</span>
        </label></td>
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
        <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg" checked="checked"> 
            <span style="font-size: 20px;">Macht/ Aufstieg</span>
        </label></td>
</tr>

I would be really grateful for suggestions!

CodePudding user response:

You need to use .each for all two class like:

$( ".clickable" ).each(function( index ) {
  $(this).click(function(event) {
    var x = jQuery("input", this).attr("checked");
    jQuery("input", this).attr("checked", !x);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr  id="quiz_row0">
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
      <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> 
            <span style="font-size: 20px;">Herausforderung</span>
        </label></td>
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
      <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg" checked="checked"> 
            <span style="font-size: 20px;">Macht/ Aufstieg</span>
        </label></td>
  </tr>
</table>


Pure js solution:

document.querySelectorAll('.clickable').forEach(el => {
  el.addEventListener('click', () => {
    el.querySelector('input').checked = true;
  });
});
<table>
  <tr  id="quiz_row0">
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
      <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> 
            <span style="font-size: 20px;">Herausforderung</span>
        </label></td>
    <td  style="border:1px solid #ddd;vertical-align: middle;padding-top:10px;padding-bottom:10px;padding-left:10px;">
      <label style="margin-bottom:0px;">
            <input type="radio" style="height:20px; width:20px;"  id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg" checked="checked"> 
            <span style="font-size: 20px;">Macht/ Aufstieg</span>
        </label></td>
  </tr>
</table>

CodePudding user response:

You don't need to use jQuery – or JavaScript of any kind – to "make the whole cell clickable," all you have to do is use CSS to have the <label> element fill the whole of the cell. One approach is below, with explanatory comments in the CSS:

/* copied the CSS from the relevant elements' "style"
   attribute into the CSS below: */
td.clickable {
  border: 1px solid #ddd;
  vertical-align: middle;
  /* removed the padding from the <td> and applied
     it to the <label> child element in order that
     the <label> could extend to the edges of its
     parent <td> (this element) */
}

label {
  /* by default causes the <label> to take the full
     width of its parent: */
  display: block;
  /* removes any margin that might move the <label>
     from the edges of its parents borders: */
  margin: 0;
  /* padding applied to the <label> instead of the
     parent <td>, in order to preserve spacing
     and aesthetics, but keeping the <label>
     positioned against all edges of the parent: */
  padding-block: 10px;
  padding-inline: 10px;
}

td.clickable input {
  height: 20px;
  width: 20px;
}

td.clickable span {
  font-size: 20px;
}
<table>
  <tbody>
    <tr  id="quiz_row0">
      <!-- I moved the inline CSS from the "style" attributes into the CSS pane, on the right;
           this makes it easier to modify the design and makes the HTML easier to read and
           understand: -->
      <td >
        <label>
          <!-- I've modified your <input> elements; in your original code they both had the
               "checked" attribute, but as they share the same "name" only one could ever
               be active, or "checked." With that in mind I removed the attribute from the
               second of <input> elements, so the first <input> is checked by default: -->
          <input type="radio"  id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked">
          <span>Herausforderung</span>
        </label></td>
      <td >
        <label>
          <input type="radio"  id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg">
          <span>Macht/ Aufstieg</span>
        </label></td>
    </tr>
  </tbody>
</table>

CodePudding user response:

You need to use event.currentTarget to make sure you always target the clickable parent row no matter the user clicks on inside the row. then use .find() to get the input field inside the clicked row.

jQuery(".clickable").on( 'click', function(event) {
    let clickable = jQuery(event.currentTarget);
    let radioInput = clickable.find('.radio_input1');
    radioInput.prop("checked", true );
});
  • Related