CSS not selector not working [duplicate] - javascript

This question already has answers here:
Why doesn't this CSS :not() declaration filter down?
(3 answers)
Closed 6 years ago.
I'm trying to select all inputs except the inputs inside some div.class. I do not know why it does not work correctly. My structure looks something like below. And why selector :not not work. And what can I do to exclude all inputs from the "exclude" div. Because i want only select inputs: i1,i2.
console.log($("div.exclude input").length);
console.log($("div:not(.exclude) input").length);
console.log($("div input").length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div id="tab1">
<div>
<div>
<input id="i1"/>
</div>
<input id="i2" />
</div>
</div>
<div id="tab2" class="exclude">
<div>
<div>
<input id="i3" />
</div>
<input id="i4" />
</div>
</div>
</div>

$('input').not('.exclude *')
or
$('input:not(.exclude *)')
These will grab all inputs which are not descendants of elements with the exclude class. You can get more specific on which inputs (maybe only the ones under a certain div or class) but this should get you the exclusion you're looking for.
You can see a working example here

In your HTML structure:
<div id="tab2" class="exclude">
<div>
<div>
<input id="i3" />
</div>
<input id="i4" />
</div>
</div>
</div>
each <input> is inside at least one <div> that does not have the class "exclude". Therefore your selector is working but it's not getting the result you want.
Instead, qualify the inputs selected the simple way:
console.log($("div input:not(.exclude *)").length);)
That selector will first select all of the <input> elements (well the ones inside <div> elements), but then exclude all of <input> elements that have an element with class "exclude" somewhere above them in the DOM.
If the original qualifier of being inside some <div> isn't really important, then all you need is "input:not(.exclude *)".

I marked inside your HTML the div that is not with the exclude class, and this is why you got 4 inputs on your console.log($("div:not(.exclude) input").length);
You can filter out the inputs that have parents with the exclude class:
console.log($("div.exclude input").length);
console.log($("div:not(.exclude) input").length);
console.log($("div input").length);
console.log($("input").filter(function() { return $(this).parents('.exclude').length > 0}).length);
$("input").filter(function() { return $(this).parents('.exclude').length > 0}).css('background', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div id="tab1">
<div>
<div>
<input id="i1"/>
</div>
<input id="i2" />
</div>
</div>
<div id="tab2" class="exclude">
<div>
<div> <!-- This div is not with the class explude -->
<input id="i3" />
</div>
<input id="i4" />
</div>
</div>
</div>

Take this:
console.log($("div.table.exclude input").length);
console.log($("div.table:not(.exclude) input").length);
console.log($("div input").length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div id="tab1" class="table">
<div>
<div>
<input id="i1"/>
</div>
<input id="i2" />
</div>
</div>
<div id="tab2" class="table exclude">
<div>
<div>
<input id="i3" />
</div>
<input id="i4" />
</div>
</div>
</div>

Problem: there are inner divs which does not have the class and they satisfy the selector too.
Solution: Add another class to the divs which you want to be part of your selector and then use this new class too .. Like
<div id="tab1" class="tabs"> And
<div id="tab2" class="tabs exclude">
And then change script to
$("div.tabs:not(.exclude) input")

Related

Hide rows missing a certain class with jQuery

I have a series of dynamic divs like these
<div id="my_unique_div">
<div>
<input type='checkbox'></input><label>Label 1</label><label><span class="unique">Text 1</span></label>
</div>
<div>
<input type='checkbox'></input><label>Label 2</label>
</div>
<div>
<input type='checkbox'></input><label>Label 3</label><label><span class="unique">Text 3</span></label>
</div>
<div>
<input type='checkbox'></input><label>Label 4</label><label><span class="unique">Text 4</span></label>
</div>
</div>
I would like to set the display of all the divs that do not contain a span with class="unique" to "none" with jQuery but not sure what selector to use to grab them.
That would leave only the 2nd div above visible and hide the 1st, 3rd and 4th.
My answer loops all of the divs under #my_unique_div and looks for .unique objects and if none, add a class that sets the display to none.
$("#my_unique_div div").each(function() {
if ($(this).find(".unique").length === 0) {
$(this).addClass("hide");
}
});
.hide {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="my_unique_div">
<div>
<input type='checkbox'></input><label>Label 1</label><label><span class="unique">Text 1</span></label>
</div>
<div>
<input type='checkbox'></input><label>Label 2</label>
</div>
<div>
<input type='checkbox'></input><label>Label 3</label><label><span class="unique">Text 3</span></label>
</div>
<div>
<input type='checkbox'></input><label>Label 4</label><label><span class="unique">Text 4</span></label>
</div>
</div>

Target parent div, but not if it includes a nest class

I want to target a parent div using document.querySelectorAll. But not if the div contains a nested div, with a particular class.
For example, in the example below, I want to grab the parent first and last floatContainer divs. But not this second, because it contains dropdown-container class.
document.querySelectorAll(".ej-form-field:not([dropdown-container])") does not seem to be working.
console.log(document.querySelectorAll(".ej-form-field:not([dropdown-container])"))
<!-- GRAB THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">First name</label>
<div class="input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
<!-- NOT THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">Last name</label>
<div class="dropdown-container input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
<!-- GRAB THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">Telephone</label>
<div class="input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
this code solve your problem.
console.log(document.querySelectorAll(".ej-form-field>div:not(.dropdown-container)"))
you must target a specific class not an attribute, ie:
document.querySelectorAll(".ej-form-field:not(.dropdown-container))
I also found this option, which seemed to work as well:
document.querySelectorAll("div.ej-form-field + :not(.dropdown-container)")

How to target the last of type visible element with jquery

I need some help I have a drupal webform in which new form elements show conditionally if the previous text input has content.
What I’m trying to do is select all inputs that are currently visible and then specifically target the last one (the most recently shown).
The issue is this targets the last child within each .form-item rather than the last form item itself directly.
$(".webform").on("change", function() {
$(".form-item:visible").each(function() {
if ($(this).is(":last-of-type")) {
//Do whatever
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="webform">
<div class="form-item" style="display:block">
</div>
<div class="form-item" style="display:block">
</div>
<div class="form-item" style="display:block">
</div>
<div class="form-item" style="display:none">
</div>
</div>
You can simplify your flow by using this jQuery:last selector
$('.form-item:visible:last')
You may apply the below code on form field change or form submit, depending on your requirements.
<div class="webform">
<div class="form-item" style="display:block">
<input type="text" value="1" />
</div>
<div class="form-item" style="display:block">
<input type="text" value="2" />
</div>
<div class="form-item" style="display:block">
<input type="text" value="3" />
</div>
<div class="form-item" style="display:none">
<input type="text" value="4" />
</div>
</div>
<script>alert($(".form-item:visible:last input").val());</script>

Wrap children elements of parent elements without class only if they contain text inputs

Consider the following HTML
I am trying to wrap the child elements (label/input) where the label text says 'This one'. Basically, I need to select the full elements without class partial if they contain input text elements and not number uinput elements. One the full elements are selected, their children elements need to be completely wrapped entirely with <div class="wrapped"></div>
<div class="group">
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
<div class="full partial">
<label>Foo</label>
<input type="text"/>
</div>
<div class="full">
<label>Foo</label>
<input type="number"/>
</div>
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
<div class="full">
<label>Foo</label>
</div>
<div class="full partial">
<label>Foo</label>
<input type="text"/>
</div>
<div class="full partial">
<label>Foo</label>
<input type="number"/>
</div>
</div>
Like this:
<div class="wrapped">
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
</div>
You could use a combination of the :not()/:has() selectors to select the desired .full elements. Iterate over the selected elements, and wrap the children elements using a combination of the methods .children()/.wrapAll():
Example Here
$('.group .full:not(.partial):has(input[type="text"])').each(function () {
$(this).children().wrapAll('<div class="wrapped"/>');
});
Alternatively, you could also use the following:
Example Here
$('.group input[type="text"]').closest('.full:not(.partial)').each(function () {
$(this).children().wrapAll('<div class="wrapped"/>');
});
I'm not sure where approach is faster.. probably the first one.

How can I select the next div using jQuery?

I am quite a noob when it comes to jQuery and I'm trying to select the next element using the next() selector but having a little trouble in getting it to work!
What I'm trying to do is to activate slideDown() once the user has finished making their selection on a ui slider. Here is my code:
$('.slider').slider({
stop: function(event, ui) {
$(this).nextAll('.secondq:first').slideDown('slow')
}
});
Trouble is, this doesn't work at all. It will only work if I put the 'secondq' question inside the parent div of the ui slider. Here is my HTML:
<div class="option">
<h2 align="left">How high is your ceiling from the floor?</h2>
<input type="text" align="right" name="bonus" class="value" disabled="disabled" />
<div class="slidewrap">
<div class="sliderFt slider"></div>
</div>
</div>
<!-- End Option -->
<div class="option">
<h2 align="left">How many windows do you have?</h2>
<input type="text" align="right" name="bonus" class="value" disabled="disabled" />
<div class="slidewrap">
<div class="sliderWinDoor slider"></div>
</div>
<div class="secondq" style="display:none;">
<h2>What type of material are your windows made of?</h2>
<div class="radiocont">
<label>Wood</label>
<input type="radio" class="styled" value="wood" name="windowtype" />
</div>
<div class="radiocont">
<label>Metal</label>
<input type="radio" class="styled" value="metal" name="windowtype" />
</div>
<div class="radiocont">
<label>PVC</label>
<input type="radio" class="styled" value="pvc" name="windowtype" />
</div>
</div>
</div>
nextAll only gets siblings. Based on your HTML structure, you could do:
$(this).parent().next()
To make it more independent from the structure, you could also do:
$(this).closest('.slidewrap').nextAll('.secondq:first')

Categories