简体   繁体   中英

Make table cell clickable with jQuery

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 class="row_cls" id="quiz_row0">
    <td class="clickable" 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;" class="radio-form-control radio_input1" id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> 
            <span style="font-size: 20px;">Herausforderung</span>
        </label></td>
    <td class="clickable" 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;" class="radio-form-control radio_input1" 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!

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 class="row_cls" id="quiz_row0"> <td class="clickable" 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;" class="radio-form-control radio_input1" id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> <span style="font-size: 20px;">Herausforderung</span> </label></td> <td class="clickable" 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;" class="radio-form-control radio_input1" 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 class="row_cls" id="quiz_row0"> <td class="clickable" 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;" class="radio-form-control radio_input1" id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> <span style="font-size: 20px;">Herausforderung</span> </label></td> <td class="clickable" 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;" class="radio-form-control radio_input1" id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg" checked="checked"> <span style="font-size: 20px;">Macht/ Aufstieg</span> </label></td> </tr> </table>

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 class="row_cls" 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 class="clickable"> <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" class="radio-form-control radio_input1" id="radio_input166" name="quiz_row0" value="Herausforderung" checked="checked"> <span>Herausforderung</span> </label></td> <td class="clickable"> <label> <input type="radio" class="radio-form-control radio_input1" id="radio_input118" name="quiz_row0" value="Macht/ Aufstieg"> <span>Macht/ Aufstieg</span> </label></td> </tr> </tbody> </table>

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 );
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM