Find not direct element - html

Edit: Please take note that the number of parent divs may vary. It may be one or more.
I am trying everything to get the parent <div> of a <div> with class rat that contains a label. So in this case, the outermost <div> must be returned.
<div> --> Should be returned
<div>
<div class="item box1" id="box1">1</div>
<div class="item" id="box2">2</div>
<div class="item" id="box3">3</div>
<div class="item rat" id="box4">4</div>
</div>
<label>Im the original parent</label>
</div>
It can easily be done when I add class attributes for each div and use closest() but for this case there's no unique selector that I can use.
Or we can take it this way: find the closest label of the <div> with class rat using the above example:
$('.rat') -> selector

A recursive approach is the most suitable for your required behavior:
function getParentWithLabel(className) {
function climbRecusively(node) {
const parent = node.parent();
return (parent.find('> label').length ? parent : climbRecusively(parent));
}
return climbRecusively($(`.${className}`));
}
$(function() {
getParentWithLabel('rat').css('background-color', 'grey');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div>
<div class="item box1" id="box1">1</div>
<div class="item" id="box2">2</div>
<div class="item" id="box3">3</div>
<div class="item rat" id="box4">4</div>
</div>
<label>Im the original parent</label>
</div>
I hope this helps.

Maybe it would be easier if you apply your style in your global jQuery, like this :
$('.rat').parent().next();

Try this too
var parentEls = $( ".rat" ).parents();
parentEls.each(function (i, obj) {
if($(obj).find( "> label" ).length){
console.log($(obj).attr('class'));
}
});
Full example : http://jsfiddle.net/harshakj89/ey00czfn/1/

Related

JQuery for multiple div id's that are the same

I have multiple divs with id='title'.
When that div is hovered over I want a hidden div with id="source" to appear.
I am using the following code but only the first div with id='title' on the page works.
<!-- Show Source / Date on mouse hover -->
<script>
$(document).ready(function(){
$("#title").mouseenter(function(){
$("#source").fadeIn( 200 );
});
$("#title").mouseleave(function(){
$("#source").fadeOut( 200 );
});
});
</script>
HTML Example:
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
Use classes instead of IDs
use .find() to search for descendants of an element
jQuery(function($) { // DOM ready and $ alias in scope
$(".title").on({
mouseenter() {
$(this).find(".source").fadeIn(200);
},
mouseleave() {
$(this).find(".source").fadeOut(200);
}
});
});
.title {
display: flex;
}
/* Utility classe */
.u-none {
display: none;
}
<div class="title col-md-3">
TITLE 1
<div class="source u-none">Visible Text</div>
</div>
<div class="title col-md-3">
TITLE 2
<div class="source u-none">Hidden Text</div>
</div>
<div class="title col-md-3">
TITLE 3
<div class="source u-none">Hidden Text</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Hello Δce Let's start by modifying the source code to use classes for you to pick. This helps us describe the functionality and allow the ID's to serve their purpose.
we'll take your
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
and we can update the jQuery code
<script>
$(function() {
$(".show-source-on-hover")
.mouseenter(function() {
$(this).find('.source').fadeIn( 200 );
})
.mouseleave(function() {
$(this).find('.source').fadeOut( 200 );
});
});
</script>
You can see here there's the use of this wrapped in the $() jquery object function. and the new use of .find to get get the correct source class.
For a working demo please see the following link: https://codepen.io/jessycormier/pen/GRmaaEb
Note: your use of ID's should change and always try and be unique like others have suggested. MDN (Mozilla Developer Network) has some great documentation on the standards of HTML, CSS, and JavaScript which can help give you.
Also, in the demo I've given your column divs some default size otherwise there is nothing to trigger the mouse over events. Good luck and happy coding 🚀
IDs are IDENTIFIERS. What that means is that there can only be one per document. Classes are not unique, so you can use them.
✅ $(".title")
❌ $("#title")

jQuery - Get highest level elements with certain class

I have a set of nested divs that look like this (this is just an example, the structure can vary):
<div class="container">
<div class="dummy">
<div class="target one"></div>
<div class="dummy">
<div class="target two">
<div class="dummy"></div>
<div class="target three"></div>
</div>
</div>
<div class="target four"></div>
</div>
</div>
I now want to select the <div>s with classes one, two and four. What I would need is a recursive selector (like $(.container div.target)) which aborts the search down a branch after it found an element and instead continues with the next branch.
$(.container div.target) selects all the targets, which is not what I want. $(.container div.target:first-of-type) almost does what I want; it selects one and two, but not four.
Is there a jQuery selector that can do what I want? If not how could I implement this behaviour in JavaScript?
You can try using the following code:
$('.container div.target').not(function () {
return $(this).parents('div.target').length > 0
})
It uses jquery .not() method to eliminate <div class='target'> elements having another <div class='target'> element somewhere up in the dom hierarchy.
$(document).ready(function () {
$('.container div.target').not(function () {
return $(this).parents('div.target').length > 0
}).each(function () {
console.log($(this).attr('id'));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="dummy">
<div id="1" class="target one"></div>
<div id="-1" class="dummy">
<div id="2" class="target two">
<div id="-2" class="dummy"></div>
<div id="3" class="target three"></div>
</div>
</div>
<div id="4" class="target four"></div>
</div>
</div>
So after trying out different things, I figured that writing my own function to do this would probably be the best solution. This is what I came up with:
$.getHighestElements = function(startPoint, selector, child = false) {
var elems = [];
startPoint.children('div').each(function () {
if($(this).hasClass(selector)) {
elems.push($(this));
} else {
$.merge(elems, $.getHighestElements($(this), selector, true));
}
});
if(child)
return elems;
else
return $(elems).map(function() { return this.toArray(); });
}
const elements = $.getHighestElements($(.container), "target");
This returns a wrapped set of elements that can be used just like any other jquery wrapped set.

Assign a role using CSS instead of adding it to the HTML tags

Is it possible to assign a role to all elements with a given class? I'd want to turn this:
<div class="a" role="button">Text!</div>
<div class="a" role="button">More text!</div>
into this
<div class="a">Text!</div>
<div class="a">More text!</div>
<style>
.a {
role: button
}
</style>
I've found solutions for filtering by role in css but nothing to assign a role to elements using css.
let buts = document.getElementsByClassName("a");
for(let i = 0; i < buts.length; i++){
buts[i].setAttribute("role", "button");
}
<div class="a">Text!</div>
<div class="a">More text!</div>
You can achieve with pure JavaScript through forEach() method.
document.querySelectorAll(".a").forEach(function(role){
role.setAttribute('role', 'button');
});
<div class="a">Text!</div>
<div class="a">Text #2</div>
<div class="a">More text!</div>

How to exclude an item from the search?

I have a search for items. The block in which the value is searched consists of several elements. I need to exclude the last item from the search. Those. so that this element is not affected, except for the rest.
I tried like this
$('.blog_content_item').not('.last').each(function() {...});
and
$(".blog_content_item:not('.last')").each(function() {...});
Does not help. Both that and that is not true on syntax. Please tell me how to exclude the "last" element from the search. Thank.
$('.blog_content_item').each(function() {
if($(this).text().toLowerCase().indexOf(value) === -1) {
...
return;
} else {
...
}
});
<div class="blog_content_item">
<div class="first">
<div class="middle">
<div class="last">
</div>
This might do the trick for you
Sample HTML
<div class="blog_content_item">
<div class="first">First</div>
<div class="middle">Middle</div>
<div class="last">Last</div>
</div>
Script
$('.blog_content_item >div:not(:last-child)').each(function () {
// your awesome stuffs here
console.log($(this).text());
})
Using :not() filter with descendant selector
https://api.jquery.com/descendant-selector/
A descendant of an element could be a child, grandchild,
great-grandchild, and so on, of that element.
console.log($('.blog_content_item :not(.last)').get())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="blog_content_item">
<div class="first"></div>
<div class="middle"></div>
<div class="last"></div>
</div>

Is there a way to dynamically wrap two elements into a div IF they exist?

I have an Angular application that renders spans based on whether they're needed or not (many ng-if's). I need to wrap these spans in a div based on their content/class names.
So, for example:
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
I don't want to do anything. But with
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
I DO want to wrap these 4 divs in a parent div <div class="parent"></div>, but only if the four appear one after the other. Is there a way to do this in CSS? Can I just use a combo of selectors to manipulate the four elements if they appear consecutively?
so you cant do this using just css and html, like the comments above, you need to use some form of javascript to manipulate the dom. heres an example using jQuery. hope it helps!
$(document).ready(function() {
$('.wrapme').each(function() {
var myElement = $(this);
var next1 = $(this).next();
var next2 = $(this).next().next();
var next3 = $(this).next().next().next();
if (next1.hasClass('wrapme') && next2.hasClass('wrapme') && next3.hasClass('wrapme')) {
var html = '<div class="parent"></div>';
next3.after(html);
var parent = next3.next('.parent')
parent.append(myElement);
parent.append(next1);
parent.append(next2);
parent.append(next3);
}
});
});
.parent {
background-color:lightgray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2<div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
hey hey
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>