0

I want to select all the inputs in a form except those within a specific element.
Consider the following sample HTML:

<form id="myForm">
    <input />
    <input />

    <div class="excluded">
        <input />
        <input />
    </div>
</form>

The following doesn't work:

const myForm = document.getElementById("myForm");
const inputs = myForm.querySelectors(":not(.excluded) input");

I worked around it by setting special class names for those ones by doing this:

const exInputs = document.querySelectorAll(".excluded input");
exInputs.forEach(input => input.classList.add("excluded"));

Now, somewhere else, I could do this:

const inputs = myForm.querySelectorAll("input:not(.excluded)");

But, there must be a more straightforward method of excluding nested elements, right?!

2 Answers 2

1

Ok, I figured it out! It's basically the same :not() exclusion, but with a slight modification. So, Instead of:

const input = myForm.querySelectorAll("input:not(.excluded input)")

And that's it, turns out!

According to MDN, and I quote:

The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class.

So, basically, whatever that goes in :not() gets compared to the attached element itself. Now, if that element matches the selectors within :not() it's gets negated; in other words, excluded.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you elaborate on this?
@ChukwujiobiCanon Thank you for asking! I included some more details.
0

You can also exclude the input elements by placing them outside the form element/not as child elements to the form. And then include them in the form, using the form attribute on the input elements outside the form.

let form = document.forms.myForm;

// All child form fields to the form
console.log([...form.querySelectorAll('input')].map(elm => elm.name));

// All form fiels in the form
console.log([...form.elements].map(elm => elm.name));
<form id="myForm">
  <input name="input01" />
  <input name="input02" />
</form>
<div class="excluded">
  <input name="input03" form="myForm" />
  <input name="input04" form="myForm" />
</div>

And an aside. Sometimes the <fieldset> elements is also useful as a way to divide up form fields.

let form = document.forms.myForm;

// All form fields from the included fieldset
console.log([...form.included.elements].map(elm => elm.name));

// All form fields from the excluded fieldset
console.log([...form.excluded.elements].map(elm => elm.name));

// All form controls from the form
console.log([...form.elements].map(elm => elm.name));
<form id="myForm">
  <fieldset name="included">
    <input name="input01" />
    <input name="input02" />
  </fieldset>
  <fieldset name="excluded">
    <input name="input03" />
    <input name="input04" />
  </fieldset>
</form>

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.