JQuery: Don't search within children - javascript

Let's say I wan't to find all the elements that have a data-view attribute but I there can be elements that have data-view which are parents to other data-view elements. I don't want the children to be in the search, I want the parents.
$('[data-view]').each(function() {});
with the following HTML:
<body>
<div data-view="app">
<div data-view="hello1">
</div>
</div>
<div data-view="job">
</div>
</body>
It should return only app and job and not hello1. I've had no luck in using the .not selector has it stops selecting any [data-view] elements.
Any suggestions?

Try:
var target_attr = "[data-view]";
$(target_attr).filter(function () {
return !$(this).find(target_attr).length;
}).each(function () {
// Whatever
});
DEMO: http://jsfiddle.net/gEVyk/1/
This will find all elements with the data-view attribute that have 0 descendants with the same attribute. In your case, that's hello1 and job.
If you're sure they're only <div>s, you should use div[data-view].
This will find all elements with the attribute that have 0 parents with the same attribute:
var target_attr = "[data-view]";
$(target_attr).filter(function () {
return !$(this).parents(target_attr).length;
}).each(function () {
// Whatever
});
DEMO: http://jsfiddle.net/ue9w9/1/
In your case, that's app and job.

How about
$('[data-view]:not([data-view] [data-view])').each(function() {});
http://jsfiddle.net/p5P8X/

Try something like $("body").children("[data-view]"). The .children() will only look at the immediate descendents of the selected element.

This should do the trick:
$('[data-view]:not([data-view] [data-view])').each(function() { ... });

Related

Jquery assign second child attribute

Is there a way to assign nested div attribute with variable? Like
<div>
<div>
123456
</div>
</div>
Become
<div>
<div sectionid="123">
123456
</div>
</div>
BTW above component will be created by JavaScript.
I've tried something like this, but it didn't work.
var a = $('<div><div>123456</div></div>');
a.eq(":nth-child(2)").attr("sectionid", "123");
Try this snippet.
//FOR DOM HTML
console.log("FOR DOM HTML");
//1st way
$('#input > div').find('div').attr("sectionid","123");
console.log($('#input').html());
//2nd way
$('#input > div > div').attr("sectionid","321");
console.log($('#input').html());
//JS HTML
console.log("FOR JS OBJECT");
var input = $('<div><div>123456</div></div>');
//1st way
input.eq(0).children().attr('sectionid', '456');
console.log(input[0].outerHTML);
var input = $('<div><div>123456</div></div>');
//2nd way
$(input[0]).children().attr('sectionid', '789');
console.log(input[0].outerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="input">
<div>
<div>
123456
</div>
</div>
</div>
nth-child(2) maches elements that are the second child element of their parent. This is not the case for your div, it is the first element of the parent div.
.eq finds an element at a specific index. It is not the place to pass a selector.
The child selector, >, will find a child element, i.e. div>div will find a div that is an immediate child of a div.
Note that the code you've provided, $('<div></div>123456<div></div>');, doesn't create a DOM tree like the one you've pasted.
Update, now that the code is edited, the value of a is a div with a child div. Since a.find will perform a search within a, you don't have to use a child selector, but can find the div immediately:
a.find('div')
Just apply attribute to children. No complicated 'find', eq(), etc.
var a = $('<div><div>123456</div></div>');
a.children().attr('sectionid', '123');
$('body').append(a);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Why don't you add it in the first place? Not clear if you add it later!
$(document).ready(function() {
var sectionid = "123";
var a = $('<div><div sectionid="' + sectionid + '">123456</div></div>');
$('body').append(a);
});
div[sectionid]{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try this - I have added comments to the code to explain what is happening.
Inspect the element to see that the attribute is added
var a = $('<div><div>123456</div></div>'); // change this to match the structure you want
a.children() // .children gets the direct descendant (which should be the nested div
.eq(0) // gets the first in the array that is returned (if there are multiple direct descendents) - it is a 0 based index selector
.attr('sectionid', '123');
$('body').append(a)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
More information about .children()
More information about .eq()
try it :
$(document).ready(function(){
$("div").eq(1).attr("sectionid","123");
})

How to select one child div by clicking on another child div of the same parent in jQuery?

For example I have simple html.
<body>
<div class="a">
<div class="child"></div> <!-- div element I click -->
<div class="childINeedToSelect"></div> <!-- div element I need to be selected -->
<div class="child"></div>
</div>
<div class="a">
<div class="child"></div>
<div class="childINeedToSelect"></div>
<div class="child"></div>
</div>
</body>
When I click on top first child class div I need to change, for example, border ONLY of the first childINeedToSelect class div. They have the same parent - a class div, but the difficult is that there are more than just one element with class a. I've already tried:
$(document).ready(function () {
var child = $('.child');
child.bind('click', function() {
detectElement($(this));
});
});
var belt;
function detectElement(arrow) {
belt = arrow.parent('.a').children('childINeedToSelect').eq(1);
belt.css("background-color", "red");
}
As you see I'm trying to send $(this) as parameter to detectElement() to determine which div was clicked. But my target div background doesn't change, and when I try to use element belt later, after it was detected by detectElement() function, Opera javascript debugger gives me error
Unhandled Error: Cannot convert 'belt.css('marginLeft')' to object
in line
var currentMargin = parseInt(belt.css('marginLeft').toString().replace('px', ''));
but this line of code worked perfectly, before calling detectElement() function; What am I doing wrong? How should I select element I need?
I'd suggest:
function detectElement(arrow) {
arrow.parent().find('.childINeedToSelect').css('background-color','red');
}
$(document).ready(function(){
$('.child').click(function(){
detectElement($(this));
});
});
JS Fiddle demo.
Or you could use the nextAll() method to find the sibling childINeedToSelect:
function detectElement(arrow) {
arrow.nextAll('.childINeedToSelect').css('background-color','red');
}
JS Fiddle demo.
And if you should have multiple .child and childINeedToSelect elements, you can pass the :first selector into the nextAll() method:
function detectElement(arrow) {
arrow.nextAll('.childINeedToSelect:first').css('background-color','red');
}
JS Fiddle demo.
I'm unsure why you were using bind(), but on the off-chance that you might be trying to account for dynamically-added elements (added after the event-handlers are bound to the various DOM nodes/jQuery objects), you could instead use on():
$('.a').on('click','.child', function(){
detectElement($(this));
});
JS Fiddle demo.
References:
find().
:first selector.
nextAll().
on().
parent().
Try this fiddle
$(document).ready(function () {
var child = $('.child');
child.bind('click', function() {
detectElement($(this));
});
});
var belt;
function detectElement(arrow) {
belt = arrow.siblings('.childINeedToSelect').eq(0);
belt.css("background-color", "red");
}
Try something like
jQuery('.a').children().first().click(function(){
jQuery('.childINeedToSelect').attr('background-color','red');
)}

How do I get the ID of a particular class using jQuery?

I have some div elements having class name hover, these div elements have parent divs having class name hoverparent but the id's of these parent elements are different.
Is it possible to get the ID of respective .hoverparent element while hovering on my .hover div elements?
I tried to get this by:
$('.hoverparent').attr('id')
But it gives the same first parent id every time.
Structure is like:
<div class="hoverparent" id="hover-1">
<div class="hover">ABC</div>
</div>
<div class="hoverparent" id="hover-2">
<div class="hover">DEF</div>
</div>
You need to use the parent or closest functions to traverse up the DOM tree to find the "parent" element you are looking for:
$(".hover").hover(function() {
var $parent = $(this).closest(".hoverparent");
alert($parent.attr("id"));
});
The difference between parent and closest is that the first will only work if the .hoverparent element is the immediate parent of the .hover element; closest will search upwards through all ancestors to find it.
try $(this).parent().attr('id') , in your hover callback.
$('.hover').mouseover(function() {
$(this).parent().attr('id');
});
don't call your class hover. this should work
$(".hover").hover(
function () {
var id = $(this).parent().attr('id');
});
Add each loop like this :
$(".hoverparent").each(function(){
var id=$(this).attr("id");
alert(id);
});
Use the parent method in the handler for the hover event:
$('.hover').hover(function(evt){
var par = $(this).parent().attr('id');
//Now do with ID what you need
},
function(evt){
//presumably you don't need anything for mouseout
});
You can try the parent() method.
Like this:
$('a').click(function(){
var parentId = $(this).parent('div.hoverparent').attr('id');
});
Try the following:
$('.hover').hover(function() {
var parentID = $(this).parent().attr('id'); alert(parentID);
});
$(".hover").hover(function(){
console.log($(this).closest(".hoverparent").attr("id"));
});
here is the fiddle http://jsfiddle.net/9dJJ9/1/show/

How to use jquery to select all elements that have two specific attributes

I have some markup where a lot of id's have an id attribute, as well as innerText. I want to select each of these elements, performing a function on the id.
How do I do that?
Something like this?
$('[id]:not(:empty)').each(function(i, el) {
// do stuff
});
Give them a common class:
HTML
<div id="first" class="all"></div>
<div id="second" class="all"></div>
<div id="third" class="all"></div>
jQuery
$('div.all').each(function(index){
processid(this.id);
});
If you are talking about selecting elements whose id (or some permutation of it) is included in its text then
$('[id]').filter(function(){
return $(this).text().indexOf( this.id ) >= 0; // the this.id should be altered to match the permutation you seek ..
}).css('color','red'); // turn those to red
After you comment to #lonesomeday (at the question comments) here is what to do ..
$('[id]').each(function(){
processid(this.id);
});
First select by a regular ID selector and then loop over that selection by filtering .text() non-empty.
$("[id]").each(function() {
if ($(this).text() != "") {
// do stuff
}
});

Check if an element is a child of a parent

I have the following code.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<div id="hello">Hello <div>Child-Of-Hello</div></div>
<br />
<div id="goodbye">Goodbye <div>Child-Of-Goodbye</div></div>
<script type="text/javascript">
<!--
function fun(evt) {
var target = $(evt.target);
if ($('div#hello').parents(target).length) {
alert('Your clicked element is having div#hello as parent');
}
}
$(document).bind('click', fun);
-->
</script>
</html>
I expect only when Child-Of-Hello being clicked, $('div#hello').parents(target).length will return >0.
However, it just happen whenever I click on anywhere.
Is there something wrong with my code?
If you are only interested in the direct parent, and not other ancestors, you can just use parent(), and give it the selector, as in target.parent('div#hello').
Example: http://jsfiddle.net/6BX9n/
function fun(evt) {
var target = $(evt.target);
if (target.parent('div#hello').length) {
alert('Your clicked element is having div#hello as parent');
}
}
Or if you want to check to see if there are any ancestors that match, then use .parents().
Example: http://jsfiddle.net/6BX9n/1/
function fun(evt) {
var target = $(evt.target);
if (target.parents('div#hello').length) {
alert('Your clicked element is having div#hello as parent');
}
}
.has() seems to be designed for this purpose. Since it returns a jQuery object, you have to test for .length as well:
if ($('div#hello').has(target).length) {
alert('Target is a child of #hello');
}
Vanilla 1-liner for IE8+:
parent !== child && parent.contains(child);
Here, how it works:
function contains(parent, child) {
return parent !== child && parent.contains(child);
}
var parentEl = document.querySelector('#parent'),
childEl = document.querySelector('#child')
if (contains(parentEl, childEl)) {
document.querySelector('#result').innerText = 'I confirm, that child is within parent el';
}
if (!contains(childEl, parentEl)) {
document.querySelector('#result').innerText += ' and parent is not within child';
}
<div id="parent">
<div>
<table>
<tr>
<td><span id="child"></span></td>
</tr>
</table>
</div>
</div>
<div id="result"></div>
If you have an element that does not have a specific selector and you still want to check if it is a descendant of another element, you can use jQuery.contains()
jQuery.contains( container, contained )
Description: Check to see if a DOM element is a descendant of another DOM element.
You can pass the parent element and the element that you want to check to that function and it returns if the latter is a descendant of the first.
Ended up using .closest() instead.
$(document).on("click", function (event) {
if($(event.target).closest(".CustomControllerMainDiv").length == 1)
alert('element is a child of the custom controller')
});
You can get your code to work by just swapping the two terms:
if ($(target).parents('div#hello').length) {
You had the child and parent round the wrong way.
Without jquery
target.matches() with :scope
If you want to see if the target element has a parent which matches some selector use the .matches() method on the target and pass the selector followed by the :scope pseudo class.
The :scope here refers to the target element so you can use the in a :where pseudo class to help you write out a clean selector.
In the following example we will match all target elements which are a decedent of an a, button, or summary element.
const app = document.getElementById("app");
app.addEventListener("click", (event) => {
if (
event.target.matches(
":where(a, button, summary) :scope"
)
) {
console.log("click", event.target.parentNode.tagName);
}
});
<div id="app">
<button>
<span>Click Me</span>
</button>
<a href="#">
<span>Click Me</span>
</a>
<details>
<summary>
<span>Click Me</span>
</summary>
</details>
<span>Click Me</span>
<div>
Note the selector :where(a, button, summary) :scope could also have been written as:
a :scope,
button :scope,
summary :scope
parent.contains()
If you are interested in seeing if the target element is a child of a specific element use .contains() on the potential parent element:
const app = document.getElementById("app");
const button = document.getElementById("button");
app.addEventListener("click", (event) => {
if (button.contains(event.target)) {
console.log("click");
}
});
<div id="app">
<button id="button">
<span>Click Me</span>
</button>
<span>Click Me</span>
<div>
In addition to the other answers, you can use this less-known method to grab elements of a certain parent like so,
$('child', 'parent');
In your case, that would be
if ($(event.target, 'div#hello')[0]) console.log(`${event.target.tagName} is an offspring of div#hello`);
Note the use of commas between the child and parent and their separate quotation marks. If they were surrounded by the same quotes
$('child, parent');
you'd have an object containing both objects, regardless of whether they exist in their document trees.
To know more background info on Aleksandr Makov's answer, checking the below page might be helpful.
https://developer.mozilla.org/en-US/docs/Web/API/Node/contains
Node.contains()
The contains() method of the Node interface returns a boolean value indicating whether a node is a descendant of a given node, that is the node itself, one of its direct children (childNodes), one of the children's direct children, and so on.
It means, the answer is not using a reclusive function.

Categories

Resources