5

I want to be able to loop over a few different labels and hide their content based on if a radio button is check or not. This is the solution I came up with, but I keep getting an error in the console.

var hazardOptions = $(".js-hazardous-option");
var hazard = $("input[name=Hazardous]");
for (var i = 0, len = hazard.length; i < len; i++) {
    if (hazard[i].id === "HazardousYes" && hazard[i].checked) {
        for (var ii = 0, length = hazardOptions.length; ii < length; ii++) {
            hazardOptions[ii].show();
        }
    } else if (hazard[i].id === "HazardousNo" && hazard[i].checked) {
        for (var iii = 0, leng = hazardOptions.length; iii < leng; iii++) {
            hazardOptions[iii].hide();
        }
    }
}

The error I get is:

hide() is not a function

Not sure what I'm missing, I've tried having a look online for a similar issue, but with no luck. I'm pretty sure that the problem is here: hazardOptions[iii].hide(); but not really sure why and/or how to fix it.

5
  • 2
    Can you post your HTML? Without it, it is hard to know what is wrong. Commented Aug 9, 2017 at 15:08
  • 2
    IIRC accessing an array object via index gives you the DOM element and not the JQuery object. You effectively need to do $(hazardOptions[iii]).hide(); to get it working Commented Aug 9, 2017 at 15:10
  • 1
    hide()/show() are JQuery functions. You are trying to apply them to Javascript variables. Commented Aug 9, 2017 at 15:10
  • Is there a single input with an id equal to either HazardousYes or HazardousNo? Or do you have multiples with those IDs? Commented Aug 9, 2017 at 15:54
  • Please check out my solution - I think it would greatly simplify your code and give you what you're looking for. Commented Aug 9, 2017 at 16:04

3 Answers 3

10

When you have a list of objects from a JQuery selector, if you try to access them via index you actually get the DOM element back and not the JQuery object. It's confusing for sure but it is in the documentation.

What you effectively need to do is turn it back into a JQuery object:

$(hazardOptions[iii]).hide();

Or you can use the eq() function with does provide the JQuery object ad thus still has the hide() function:

hazardOptions.eq(iii).hide();
Sign up to request clarification or add additional context in comments.

3 Comments

Why not use jQuery's built-in .each()? You're wrapping DOM elements, unwrapping, and re-wrapping. Just keep them wrapped and iterate over them
@mhodges: On second thought, the documentation suggests it requires the same anyway...
Yeah, for some reason I was thinking .each() kept a wrapped copy of the DOM element. IMHO I hate how jQuery does their iterator functions lol. Either way, the code can be significantly simplified - see my solution I posted.
1

Most probably you need to wrap it with $

$(hazardOptions[ii]).hide()

Comments

0

As you currently have it, if hazard.id === "HazardousYes", you are showing all hazardOptions, and if it is "HazardousNo"you are hiding all of them.

You can call .show() and .hide() on a jQuery collection and it will apply that to all elements in the collection. The below code will replicate the logic of your original code, however, the hazardOptions final show/hide state will be solely determined by the last hazard that is checked and has an id equal to "HazardousYes" and "HazardousNo". This may be what you want, but I would imagine it's not.

var hazardOptions = $(".js-hazardous-option");
var hazards = $("input[name=Hazardous]");
hazards.each(function (index, hazard) {
  if (hazard.checked) {
    if (hazard.id === "HazardousYes") {
      hazardOptions.show();
    } else if (hazard.id === "HazardousNo") {
      hazardOptions.hide();
    }
  }
}

Edit - Come to think of it, if you don't have elements with duplicate IDs, You can make this really simple:

hazardOptions.show($("#HazardousYes").is(":checked")); 
hazardOptions.hide($("#HazardousNo").is(":checked"));

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.