can I query select the Parent from child in Javascript? - javascript

how to use querySelector to select the parent element from the child?
in my example the HTML structure is like this:
<label>
<input/> <!-- I know only this -->
</label>
and in html what I know is only the child so input.
how can get the parent from child input, so getting the label.
from what I know is easy to get the child from the parent by doing like this parent > child
is there any child < parent? (similar logic).
if isn't possible with querySelector() is there any other way with the javascript API?

use .parentElement or use .closest()
parentElement: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement
if you want only the parent element.
closest: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
if you want specific tag (this can make you some bugs if not used properly)
const input = document.querySelector("input");
// you get the same result with these 2
console.log(input.parentElement)
console.log(input.closest("label"))
// you can use all the method of element
// like style, classList, etc...
input.parentElement.style.outline = "0.2rem solid red";
<label>
<input type="text" /> <!-- I know only this -->
</label>

First you can get input element, after get parent with function closest():
var inputElement = document.querySelector('input');
var label = inputElement.closest('label');
console.log(label)
<label>
<input type="text" /> <!-- I know only this -->
</label>

get the element by the input tag and then look for its parent. However, be sure to check for the undefined and multiple query results from the below code snippet.
document.querySelector("input").parentElement

Related

for each element javascript remove parent div and replace with own div

I'm trying to remove the parent div's for each input class with javascript and replace them with my own classes. However the id's of the input fields are always random. Here's my code:
<script type="text/javascript">
var filter = document.getElementsByName('filter[]');
function show() {
for (var i = 0; i < filter.length; i++) {
alert(filter[i].value)
}
}
//The .sidebar-filter-item, should not be hardcoded
//because that name can differ always.
$("<h2> test </h2>").insertBefore(".sidebar-filter-item ");
Here is how my input fields look like:
<div class="random1293">
<input id="filter_16" type="checkbox" name="filter[]" value="16">
</div>
<div class="random2423">
<input id="filter_17" type="checkbox" name="filter[]" value="17">
</div>
Even though you have not tagged this post as Jquery but still used jquery in your code in the OP, I conclude that Jquery solution is acceptable.
Select all the input elements which start with the id filter_ and then change the class of the parent div to what ever you want.
$('input[id^="filter_"]').each(function(){
$(this).parent().attr('class','yourOwnClassHere');
});
Once selected you can select a DOM elements parent element using:
element.parentElement
Regarding selecting the elements if the id attributes are going to be random/unpredictable you could instead use:
document.getElementsByTagName("input");
Which will give you an array of all your input elements which you can then loop through to perform your operation to each.
Alternatively you could give each of the elements you want selected a class (if you don't want all inputs on the page) an use:
document.getElementsByClassName("className");
which will also return an array which you can handle in the same fashion.

jquery catch previous class issue

My html is
<input type="text" class='myclass' value="start">
<div>
<input type="text" class='myclass' value="sea">
</div>
<button class="mybutton">Catch</button>
<br/>
<input type="text" value="end" class='myclass'>
and javascript is
$('.mybutton').click(function(){
var text = $(this).prev('.myclass').val();
console.log(text);
});
I want to get the value of immediate previous input value by class name. but the result is undefined.I want to get the value sea. Where is the problem? the working fiddle link is Here >> Thank you.
Immediate previous element of catch button is a div, so you need to do a find() inside that
like this:
$('.mybutton').click(function(){
var text = $(this).prev('div').find('.myclass').val();
console.log(text);
});
I want to get the value of immediate previous input
Well, that's the problem, input is not immediate. you can use prevAll method instead:
$('.mybutton').click(function(){
var text = $(this).prevAll('.myclass').val();
alert(text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class='myclass' value="start">
<div>
<input type="text" class='myclass' value="sea">
</div>
<button class="mybutton">Catch</button>
<br/>
<input type="text" value="end" class='myclass'>
Interesting. I have never used the ".prev()" function before. Anyways:
If you read here https://api.jquery.com/prev/ you will find:
"Given a jQuery object that represents a set of DOM elements, the .prev() method searches for the predecessor of each of these elements in the DOM tree and constructs a new jQuery object from the matching elements."
Also:
If no previous sibling exists, or if the previous sibling element does not match a supplied selector, an empty jQuery object is returned.
So in other words, as has been mentioned before, the ".prev()" simply looks for the previous element.
To do what you want to do in the way you want to do it you might want to consider the ".prevAll()" function that is explained here: https://api.jquery.com/prevAll/
But then again since the element you want is actually a child of the previous element and not a direct sibling you might want to consider Beginners' suggestion:
$('.mybutton').click(function(){
var text = $(this).prev('div').find('.myclass').val();
console.log(text);
});
But in fact you should be able to make it slightly simpler by removing the 'div' selector:
$('.mybutton').click(function(){
var text = $(this).prev().find('.myclass').val();
console.log(text);
});
As long as you are certain that your '.myclass' element will be a child of the previous element this should work irregardless of what the parent element is (div, span, whatever)

jQuery selector to find inputs inside a div

I have HTML like this:
<div class="s-item s-question">
<label>label text</label>
<div>
<input name="s1" type="checkbox" class="switch-indeterminate k-input"
data-indeterminate="true"
data-on-text="Yes"
data-off-text="No" />
</div>
</div>
Dynamically with jQuery, how can I select that input? I want to determine when a change occurs.
The highest level div will always have class s-item but instead of a checkbox, sometimes I might have a button or a select box, etc.
So I thought maybe $('.s-item').find('select, input, button').change(function() { ... }); would work? But it didn't.
What should I do?
The "change" event is only valid on input, select, and textarea elements. It doesn't work because you are attempting to assign it to a button element.
$('.s-item').find('select, input, textarea').change(function() { ... });
should work.
It would be cleaner simply to assign a class to the items you care about, so you could just do
$(".s-change-watch").change(function() { ... });
which better separates the semantics of markup (like what element type it is) from functionality.
You can simply do the following to get the checkbox then check the value
$('.s-item div input')
or just give the input an id or class and select that.

jQuery - find all inputs, except the ones descending from div

Well I'm trying to write a validation jQuery plugin, but for that I need to find all inputs inside of a container, which is marked with an attribute. However, that container may have other sub-containers, also marked with attributes, and they may have their own inputs.
I need to select all inputs, descendants of the parent container (accessed by $(this)) which are not descendants of the sub-containers. Is that possible?
Some code to illustrate:
<div data-container>
<input>
<div class="form-group">
<input>
</div>
<input>
<div data-container>
<input>
<input>
<input>
</div>
</div>
I want to select those first three inputs, and ignore the ones inside the children data-container. The one inside the form-group must be selected too.
Use .not() to exclude a selection from an existing jQuery selection:
var yourSelection = $(this).find('input').not($(this).find('[data-container] input'));
JSFiddle (I replaced the $(this) by $('[data-container]:first') in the fiddle for simplicity)
This should work, here http://jsfiddle.net/2Wv7P/
$('div[data-container] input:lt(3)')
You can select based on the parent div like this. Only the first level children are going to be selected based on you given tag, assuming you ID the parent div as #parent
$('#parent > input')
So following this path, if you have to select the parent with $(this), which is to say using 'this', then you can select this same set of 'input's using
$('#' + this.id + ' > input')
For example
see this fiddle

how to get 1 hidden field among several within div

i have 3 hidden fields in 1 div. when I have reference to this div, how to get 1 of the hidden fields in this div.
This will also work (jQuery):
$('#my_div').find('input[type=hidden]:first')
Assuming you have a DIV, like so:
<div id="mydiv">
<input type="hidden">
<input type="hidden">
<input type="hidden">
</div>
You can use jQuery to do something like this to select all of them:
$('input:hidden','#mydiv');
With that selector, now you have all 3 hidden fields in a jQuery collection. You can pick and choose from there which one you want to use by using several methods:
$('input:hidden:first','#mydiv'); // get first one using first
$('input:hidden:last','#mydiv'); // get last one using last
$('input:hidden','#mydiv').eq(0); // get first one using eq
$('input:hidden','#mydiv').eq(1); // get second one using eq
$('input:hidden','#mydiv').eq(2); // get third one using eq
$('input:hidden:eq(0)','#mydiv'); // get first one using eq in selector
The options are:
first - get the first matched element in the collection.
last - get the last matched element in the collection.
eq(N) - get the Nth matched element, 0 based.
:eq(N) - get the Nth matched element, 0 based, inside the selector string.
I am personally a fan of option 3 as I don't like having too much crap in my selector.
One caveat of the above is that by using the :hidden selector we might match other input elements that are hidden (ie, not visible). If you expect that to happen, or even if you don't, you could do this:
$('input[type=hidden]', '#mydiv').eq(0);
Without any code it's hard to help but i'd say give the hidden field an ID and use:
var hdn = document.getElementById("id");
Or if you're using Jquery use:
var hdn = $("#id");
if it's like this:
<div id="somediv">
<input type="hidden"/>
<input type="hidden"/>
<input type="hidden"/>
</div>
and you're using jquery, you can just write this:
$("#somediv > input[type='hidden']:eq(1)")
and it should return a reference to the 1st hidden field. if you want the 2nd, use "eq(2)" and so forth.
var firstHidden = $("input[type='hidden']:first", ref);
:first pseudo-class and attribute selector
or
var firstHidden = $("input:hidden:first", ref);
:hidden pseudo-class (be careful, because :hidden finds also elements with style="display: none")
or
var firstHidden = $("input[type='hidden']", ref).eq(0);
.eq()
where 'ref' variable is a reference to the DIV element
I would assign a class to the hidden you want to find - a little easier on the programmer looking back on it in 4 years. I'm using "id" as an example of the hidden. Once you find it with jQuery - you can use .val() to get its value.
HTML:
<div id="mydiv">
<input type='hidden' name='mydiv_id' class='idField' value='test1' />
<input type='hidden' name='mydiv_hidden2' class='option2' value='test2' />
<input type='hidden' name='mydiv_hidden3' class='option3' value='test3' />
</div>
jQuery:
//execute on document ready:
$(function() {
var div = $('#mydiv'); //some jquery/dom element "div"
// use the jQuery selector with "div" as our context.
var $hidden = $('input.idField', div);
alert($hidden.val()); // should alert 'test1'
});
For a reference, if you're not using jQuery like the original poster and assuming the structure above:
<div id="mydiv">
<input type="hidden">
<input type="hidden">
<input type="hidden">
</div>
var div = document.getElementById('mydiv');
var inputs = div.getElementsByTagName('input');
for(var i = 0; i < inputs.length; i++){
// Match your input with inputs[i].name, etc.
}

Categories