find children while moving upwards in dom - javascript

This can be sound little confusing but here it is.
What i want is to find the children(OF CLASS PARENT ) when user clicks on class target.
Important: I am not aware of children class & child inside html structure.Target class can be after 'blah' like in first case OR can be directly after children like in second case.
Information available: class "PARENt" and $(this) [class target]
Find: Children(ID) of class PARENT (you cannot use class .children)
<div class="parent">
<div class="children" id="1">
<div class="blah">
<div class="target">TARGET</div>
</div>
</div>
<div class="children" id="2">
<div class="target">TARGET</div>
</div>
<div class="children" id="3">
<div class="blah">
<div class="target">TARGET</div>
</div>
</div>
Example:
Clicking Target 1 would produce: ID = 1
Clicking Target 2 would produce: ID = 2
Clicking Target 3 would produce: ID = 3

If you want to find only ONE ID use:
$('.target').click(function() {
var found = false;
var parent;
var previous;
while(!found) {
if (previous) {
parent = previous.parent();
} else {
parent = $(this).parent();
}
if (parent.hasClass('parent')) {
found = previous;
}
previous = parent;
}
console.log(found.attr('id'));
});
Demo.

To literally answer your question:
$(".parent *") will give you ALL of the children of .parent no matter how many layers deep
To practically answer your question:
Limit possible elements, classes, IDs, etc.
$(".parent div, .parent span, .parent .child ...etc")
You can also grab only the immediate children of an element or set of elements by using the > CSS selector:
$(".parent > *") for example, will give you ALL of the immediate children of .parent
In the context of your problem
$(".target").on("click", function () {
$(this).closest(".parent").children();
// OR
$(this).closest(".parent").find("*");
});
To get the specific ID Given your current DOM structure...
$(".target").on("click", function () {
var id = $(this).closest("[id]").attr("id");
console.log(id);
});

Use .parentsUntil() to get the set of all parents up to (but not including) .parent. Then get the last element of this to get the child of the parent.
$(".target").click(function() {
var child = $(this).parentsUntil(".parent").last();
console.log(child.attr('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="parent">
<div class="children" id="1">
<div class="blah">
<div class="target">TARGET</div>
</div>
</div>
<div class="children" id="2">
<div class="target">TARGET</div>
</div>
<div class="children" id="3">
<div class="blah">
<div class="target">TARGET</div>
</div>
</div>
</div>
Another

Related

get dataset from parent

I have the element inside this structure:
<div data-unit="5" data-id="0" id="unit-0" class="session-unit-container unit-columns">
<h1 class="unit-title">5</h1>
<div class="session-unit">
<div id="element" class="session-card" draggable="false" style="">Item 5</div> // here is the element
</div>
</div>
How can I get the data-unit="5" of the parent element when I select the element?
I don't understand what you mean by saying when I select the element. You mean when you click? When you mouse select the text?
Anyway, the way to access the value is the following:
// Here I select the element I am interested for.
let element = document.getElementById('element');
// Here I just console.log the value of the data-unit
console.log(`Here Is The data-unit Value: ${element.parentNode.parentNode.dataset.unit}`);
<div data-unit="5" data-id="0" id="unit-0" class="session-unit-container unit-columns">
<h1 class="unit-title">5</h1>
<div class="session-unit">
<div id="element" class="session-card" draggable="false" style="">Item 5</div> // here is the element
</div>
</div>
Assuming you have more than one container containing cards you can attach a listener to each container and, if the element you clicked on was a card, log the value of the data attribute.
(Note: if you do have multiple containers of cards don't give each card the same id.)
// Cache the container elements
const containers = document.querySelectorAll('.session-unit-container');
// Add listeners to them
containers.forEach(container => {
container.addEventListener('click', handleClick, false);
});
function handleClick(e) {
// Get the class list from the element that was clicked
const { classList } = e.target;
// If it's a card...
if (classList.contains('session-card')) {
// Locate the container element
const parent = e.target.closest('.session-unit-container');
// And get its unit value from the dataset
const { unit } = parent.dataset;
console.log(unit);
}
}
.session-card:hover { cursor: pointer; color: red; }
<div data-unit="2" data-id="0" id="unit-0" class="session-unit-container unit-columns">
<h3 class="unit-title">2</h3>
<div class="session-unit">
<div class="session-card" draggable="false" style="">Item 2</div>
</div>
</div>
<div data-unit="5" data-id="0" id="unit-0" class="session-unit-container unit-columns">
<h3 class="unit-title">5</h3>
<div class="session-unit">
<div class="session-card" draggable="false" style="">Item 5</div>
</div>
</div>
Additional documentation
Destructuring assignment
closest
classList
addEventListener

Find div and then go backward to a specific div (jQuery)

I want to find the matching "identifier" and then add a class to the div with classname "two", for example "found".
html example
<div id="list">
<div class="box">
/* Part ONE */
<div class="one">
<div class="one_one">
<span class="identifier">1234</span>
</div>
</div>
/* Part TWO */
<div class="two"></div>
</div>
...
</div>
I tried:
var identifier = $("#list").find(".box > .one > .one_one > span:contains('1234')");
if (....) {
identifier.closest(".one").addClass("found");
}
I only managed to go back to the div with the classname "one", but I need the div with classname "two" (unfortunately it is outside the parent tree of the identifier).
Traverse the DOM up to a common parent and then find the target element within that parent. For example:
identifier.closest(".box").find(".two").addClass("found");

Get Element that Parent not a class

I would like to return an element in javascript that does not have a class in its parent element.
For example, I would like to get the child class element in the following code snippet that does not have 'parent' as a class for the parent element:
<div>
<div class= "parent">
<div class="child">
Not to be selected
</div>
</div>
<div>
<div class="child">
To be selected
</div>
</div>
</div>
I tried to return it through xpath in protractor
You can use the :not selector .
console.log(document.querySelectorAll(':not(.parent) > .child'));
<div>
<div class= "parent">
<div class="child">
Not to be selected
</div>
</div>
<div>
<div class="child">
To be selected
</div>
</div>
</div>
There are a few ways to do this. Either you check if the class is there.
var elementList = [];
document.querySelectorAll("div.child").forEach(function(e) {
var parent = e.parentElement;
if(parent.classList == null || !parent.classList.contains("parent")) {
elementList.push(e);
}
})
console.log(elementList);
If the parent class is specific you can use the css :not attribute
var elementList = document.querySelectorAll("div:not(.parent) > div.child");
console.log(elementList);

How to check if inner <div> has text

what I'm trying to do is to check if my inner <div> has a text for example Ended and then remove if it has a text. I have multiple <div> with the same class name. I tried using .filter(). I would like to remove the div container_one that contains the found element.
Here is my HTML:
var $filstatus = $('.status').filter(function() {
return $(this).text() == 'Ended';
});
$filstatus.remove();
<div class="main_container">
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">On going</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
</div>
Thank you for the help!
I would use the jQuery's selector by content
combined with .closest(). This might be the shortest way:
$('.status:contains("Ended")', $('.main_container')).closest('.container_one').remove();
First ('.status:contains("Ended")') will select all elements that have a class status, contain the text "Ended" and are children of main_container (not needed but is recommended to speed up selection of elements on complex pages).
Then the method .closest('container_one') will climb up the parents tree for each of the elements from the previous step and select the first parent element with class 'container_one'.
At last it will remove all elements found.
Note: all those methods work both with single element and collections of elements, so no need of any for/foreach.
Working JSFiddle Demo
Pure JavaScript solution with forEach:
var div = document.querySelectorAll('.container_one');
div.forEach(function(el){
var target = el.querySelector('.status');
if(target.textContent == 'Ended'){
el.remove();
};
})
<div class="main_container">
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">On going</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
</div>
Try this
$filstatus.parent().parent().remove();
filter will return an array , then use each to loop over that and delete the element. In this case it will remove that specific div but the parent div will still be in dom
var $filstatus = $('.status').filter(function() {
return $(this).text().trim() === 'Ended';
});
$filstatus.each(function(index, elem) {
$(elem).remove();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main_container">
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">On going</div>
</div>
</div>
<div class="container_one">
<div class="inner_container">
<div class="status">Ended</div>
</div>
</div>
</div>
If you want to remove .container_one whose inner child has the text Ended, try
const ended = $('.status').filter((index, element) => $(element).text() === 'Ended')
ended.parents('.container_one').remove()
Since you want to remove the closest ansistor with class .container_one, you will need to use closest
$filstatus.closest(".container_one").remove();
Check this: https://jsfiddle.net/n3d5fwqj/1/
https://api.jquery.com/closest/
Try using this if you don't need $filstatus in other places
$('.status').each(function(){
if ($(this).text() == "Ended"){
$(this).parent().parent().remove();
}
})
I see your problem is you are able to remove the child div status but what you want is to remove the entire parent div with class container_one
you can use $.each for that and use closest(class_name) to remove the parent including its child
$.each($('.status'), function(idx, div) {
if ($(this).text() == 'Ended') {
$(this).closest('.container_one').remove();
}
});
Demo
or you can continue your filter and just add .closest('.container_one') to your jquery selector
var $filstatus = $('.status').filter(function() {
return $(this).text() == 'Ended';
});
$filstatus.closest('.container_one').remove();
Demo

how to append li tag into ul in angularjs?

I have a html like this
<div>
<div class="submain">
<div><ul><ul><div>
<div g-directive>click</div>
</div>
<div class="submain">
<div><ul><ul><div>
<div g-directive>click</div>
</div>
<div class="submain">
<div><ul><ul><div>
<div ng-directive>click</div>
</div>
<div>
when i click on particular div(click div), i want to append one li tag into the ul tag of before particular clicked div.
i have directive like this, i have tried this but it is not working
app.directive('ngDirective',function()
{
return function(scope,element,attrs)
{
element.bind('click',function()
{
element.prev().children('ul').append('<li></li>');
});
}
});
how to append li tag into ul that is children of div ?
Just a rough example of what you could do:
HTML
<div>
<div class="submain">
<div><ul>
<li ng-show="showLI">{{content}}</li>
<ul><div>
<div ng-click="toggleLI()">click</div>
</div>
<div>
JS
$scope.showLI = false;
$scope.toggleLI = function() {
$scope.showLI = !$scope.showLI;
}
Your code doesn't work, because of wrong element selector. .children searches only the first level of children elements, so basically <div class="submain"> doesn't have children element <ul>. You can use .find('ul') instead, it searches the whole tree downwards

Categories

Resources