0

So I have the following jQuery code that I've built out that checks whether a on change event has been triggered on #rtk5 and then either removes or adds the 'required' attribute.

Works perfectly in jQuery:

// Make checkbox textboxes not required unless checked
$(document).ready(function() {
    $('#rtk5').change(function() {
        if ($('.rtk5ReqField').attr('required')) {
            $('.rtk5ReqField').removeAttr('required');
        }
        else {
            $('.rtk5ReqField').attr('required','required');
        }
    });
});

I would like to convert it to JavaScript with a function call, but I can't seem to figure out how to properly do it.

Error:
TypeError: rtk5req.getAttribute is not a function

Here is my attempt:

var rtk5req = document.getElementsByClassName('rtk5ReqField');
function rtk5Required() {
    rtk5req.addEventListener('change', (e) => {
        if (rtk5req.getAttribute('required')) {
            rtk5req.removeAttribute('required');
        } else {
            rtk5req.getAttribute('required', 'required');
        }
    });
}
rtk5req.addEventListener('change', rtk5Required());
document.addEventListener('DOMContentLoaded', rtk5Required);
rtk5Required();

Updated code: Removed the repetitive change call

var rtk5req = document.getElementsByClassName('rtk5ReqField');
function rtk5Required() {
        if (rtk5req.getAttribute('required')) {
            rtk5req.removeAttribute('required');
        } else {
            rtk5req.getAttribute('required', 'required');
        }
}
rtk5req.addEventListener('change', rtk5Required());
document.addEventListener('DOMContentLoaded', rtk5Required);
rtk5Required();

Updated code #2:

Thanks all for all the hard work, there's one small issue that I'm still experiencing and had to make some tweaking - When I uncheck the checkbox, it doesn't remove the required tag placed on rtk5Declaration from which it did in the jQuery.

var rtk5_selection = document.getElementById('rtk5');

document.addEventListener('DOMContentLoaded', () => {
    rtk5_selection.addEventListener('change', () => {
        if (rtk5_selection.getAttribute('required')) {
            document.getElementById('rtk5Declaration').removeAttribute('required');
        } else {
            document.getElementById('rtk5Declaration').setAttribute('required', 'required');
        }
    });
});

Thanks so much all!

12
  • 2
    .getElementsByClassName returns an HTMLCollection of elements, not a single element. You need to iterate over it. Commented Jan 9, 2020 at 15:39
  • 1
    it won't work until you address the fact that rtk5req is a pseudo-array, not a single element. Commented Jan 9, 2020 at 15:43
  • 1
    how many elements are known to exist with this particular class? It affects how any answer might be written. Commented Jan 9, 2020 at 15:45
  • 1
    Right, in which case I see the problem - you should just change the second code to use var rtk5req = document.getElementById('rtk'); instead of using its class and the more complicated getElementsByClassName() function. Commented Jan 9, 2020 at 15:47
  • 1
    and don't use the updated code - as pointed out by @ajuni880 it's flawed. Commented Jan 9, 2020 at 15:48

2 Answers 2

1

Since you only have one element you should be using its ID instead of its class, and avoiding the complication caused by document.getElementsByClassName returning a pseudo-array of elements instead of a single element.

NB: use setAttribute to change an attribute's value, or better yet (as shown in the code below) use the direct boolean property that mirrors the element's attribute.

document.addEventListener('DOMContentLoaded', () => {

    const rtk_sel = document.getElementById('rtk5');
    const rtk_dec = document.getElementById('rtk5Declaration');

    rtk_sel.addEventListener('change', () => {
        rtk_dec.required = !rtk_sel.checked;
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the guidance @Alnitak, however I think I might need to do some tweaking because it's checking if the ID #rtk5 has a on change event triggered and then instead of using the .rtk5ReqField class, I will be using the ID rtk5Declaration to apply the required attribute there.
Assuming based on your comments that there's a single .rtkReqField element and that it's the one with the #rtk ID, the code here should exactly replicate your existing jQuery code. If you need to tweak it that's a different problem.
Thanks a bunch @Alnitak, I updated a answer with one small issue that I'm experiencing.
0

Thanks all for the contribution, below is the working version which I have tweaked:

var rtk5_selection = document.getElementById('rtk5');
var rtk5declaration = document.getElementById('rtk5Declaration');

function rtd3Declaration() {
    if (!rtk5_selection.checked) {
        rtd3declaration.removeAttribute('required');
    } else {
        rtd3declaration.setAttribute('required', 'required');
    }
}
rtk5_selection.addEventListener('change', rtd3Declaration);
document.addEventListener('DOMContentLoaded', rtd3Declaration);
rtd3Declaration();

3 Comments

ah, so it's two different elements? You didn't mention that in the question. Personally I'd still use rtd3declaration.required as a property (as you've done with rtk5_selection.checked` rather than mess about with calls to removeAttribute. In fact you could just do: rtd3declaration.required = !rtk5_selection.checked. (see my updated answer)
Thanks for the guidance @Alnitak, I'll still accept it as the final answer since it helped pave the way.
NB: you shouldn't call rtd3Declaration separately, and you should move the getElementById calls inside that function, to ensure that they actually succeed. If they're called before the DOM is loaded they won't hold the right values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.