I try to get the value of Checkbox through the following function:
function sickness_selection() {
var element = event.target.id;
// console.log( event.target.checked);
element = document.getElementById(element);
if (element.checked === true) {
element.parentElement.classList.add("asanism-selected-radio");
} else {
element.parentElement.classList.remove("asanism-selected-radio");
}
}
the function works but receives the following error in the console:
Uncaught TypeError: Cannot read properties of null (reading 'checked')
at sickness_selection (js_cEGLc76e0OdunEJf9-WqG_aDsYoNtkkBvpRxiXeaSmg.js:1701:17)
at HTMLDivElement.onclick (create:1:1)
because the value does not render in the HTML file while changing the input:
<div class="js-form-item js-form-type-checkbox checkbox form-check js-form-item-sickness7 form-item-sickness7">
<label class="form-check-label">
<input data-drupal-selector="edit-sickness7" type="checkbox" id="edit-sickness7--iViLtzwqW-A" name="sickness7" value="1" class="form-checkbox form-check-input" required="">
<label for="edit-sickness7--iViLtzwqW-A" class="option">somthing</label>
</label>
</div>
is there any solutions for error?
I try to get the value of Checkbox through the following function:
function sickness_selection() {
var element = event.target.id;
// console.log( event.target.checked);
element = document.getElementById(element);
if (element.checked === true) {
element.parentElement.classList.add("asanism-selected-radio");
} else {
element.parentElement.classList.remove("asanism-selected-radio");
}
}
the function works but receives the following error in the console:
Uncaught TypeError: Cannot read properties of null (reading 'checked')
at sickness_selection (js_cEGLc76e0OdunEJf9-WqG_aDsYoNtkkBvpRxiXeaSmg.js:1701:17)
at HTMLDivElement.onclick (create:1:1)
because the value does not render in the HTML file while changing the input:
<div class="js-form-item js-form-type-checkbox checkbox form-check js-form-item-sickness7 form-item-sickness7">
<label class="form-check-label">
<input data-drupal-selector="edit-sickness7" type="checkbox" id="edit-sickness7--iViLtzwqW-A" name="sickness7" value="1" class="form-checkbox form-check-input" required="">
<label for="edit-sickness7--iViLtzwqW-A" class="option">somthing</label>
</label>
</div>
is there any solutions for error?
Share Improve this question asked Mar 28, 2022 at 8:51 Hassan MonfaredHassan Monfared 691 gold badge3 silver badges9 bronze badges 3- How is sickness_selection being triggered? – Nitheesh Commented Mar 28, 2022 at 8:59
-
@Nitheesh - That information is hidden away in the stack trace (would have been much better if it had been shown directly): It's a
click
handler on thediv
(well, on adiv
, I'm assuming it's that one). – T.J. Crowder Commented Mar 28, 2022 at 9:05 - By far, the best way to find out what's going wrong here (as in almost all other cases) is to use the debugger built into your IDE and/or browser. Put a breakpoint on the first line of the event handler and click the element. Then, step through the function, looking at the values of variables, etc. Using a debugger is not an advanced skill. More here and here. – T.J. Crowder Commented Mar 28, 2022 at 9:09
1 Answer
Reset to default 1The error is telling you that element
is null
, because getElementById
returned null
. The only reason getElementById
returns null
is that no element with that id
exists (see this question's answers).
But just that isn't the root of the problem. You're using a click handler on a div
element (from the error message), then using event.target.id
to find the input
element using getElementById
. There are two problems there:
If
event.target.id
were the correct ID, you'd already have the element:event.target
.It's entirely possible to click somewhere in the
div
that isn't theinput
element.event.target
is the element that was clicked (in your case, that might be thediv
, thelabel
, or theinput
itself). I suspect that's what's happening, you're clicking an element (alabel
, for instance) that doesn't have anid
, so you're passingundefined
intogetElemntById
, so it's looking forid="undefined"
and not finding it.
Instead, given the structure of your HTML, you should look for the input
within the div
using querySelector
:
const div = event.currentTarget;
const checkbox = div.querySelector("input[type=checkbox]");
Also note that if (element.checked === true)
is more idiomatically written as simply if (element.checked)
.
So doing all of the above:
function sickness_selection() {
const div = event.currentTarget;
const checkbox = div.querySelector("input[type=checkbox]");
// assert(checkbox !== null);
const label = checkbox.parentElement;
if (checkbox.checked) {
label.classList.add("asanism-selected-radio");
} else {
label.classList.remove("asanism-selected-radio");
}
}
If you don't need to support Internet Explorer, you could use the second argument to classList.toggle
instead:
function sickness_selection() {
const div = event.currentTarget;
const checkbox = div.querySelector("input[type=checkbox]");
// assert(checkbox !== null);
const label = checkbox.parentElement;
label.classList.toggle("asanism-selected-radio", checkbox.checked);
}
The above assumes that the handler function is hooked on the div
that's immediately around the checkbox (again, this is an asumption I'm making from the error message). But in a ment you've asked how to handle multiple checkboxes, which suggests to me it may be on a div
deeper in the document that contains multiple copies of the structure you've shown.
If so, the code above won't work (it'll always find the first input[type=checkbox]
in that outer div
). Instead, starting from the target
, find that inner div
to start with (see the ***
line):
function sickness_selection() {
const div = event.target.closest("div"); // ***
const checkbox = div.querySelector("input[type=checkbox]");
// assert(checkbox !== null);
const label = checkbox.parentElement;
label.classList.toggle("asanism-selected-radio", checkbox.checked);
}
Internet Explorer doesn't have that closest
method. You can probably find a polyfill for it. Or just replace it with a loop:
// If you really need IE support
function sickness_selection() {
let div = event.target;
while (div && !div.matches("div")) {
div = div.parentElement;
}
// assert(div !== null);
const checkbox = div.querySelector("input[type=checkbox]");
// assert(checkbox !== null);
const label = checkbox.parentElement;
if (checkbox.checked) {
label.classList.add("asanism-selected-radio");
} else {
label.classList.remove("asanism-selected-radio");
}
}
Finally: It looks like your HTML has a label
within a label
. That's invalid HTML:
label
...
Content model:
Phrasing content, but with no descendant labelable elements unless it is the element's labeled control, and no descendant
label
elements.
(my emphasis)