jQuery selector to find all non nested descendants - javascript

I am looking for jQuery slector that will find all descendants of passed jQuery object that are not nested in any element that fits same selector. Consider following HTML:
<body>
<div class="container" id="1">
<div class="container" id="11"></div>
<div class="container" id="12"></div>
</div>
<div class="container" id="2"></div>
<div class="noncontainer">
<div class="container" id="3">
<div class="container" id="31"></div>
</div>
</div>
</body>
In this example $("body").find(".container magicSelector") should return divs 1, 2 and 3. $("#1").find(".container magicSelector") should return divs 11 and 12.
EDIT: I have wrote a function for that here, but I think that selector would be cleaner and faster.

Use not() for first case
$("body").find(".container").not('.container .container');
And for second use descendent in the selector
$("body").find('.container .container');

Related

JQuery affect only "this" element of same class

I have a bunch of html elements with same class and a JQuery click function when i click on one of these elements, all of the same class are affected by this function.
My question: how can I modify the following code in order to affect only clicked element and not all of the same class.
jquery
$('.editorTile').click(function(event){
$(this).data('type', selectedTile);
$(this).data('imgx', selectedTile_imgX);
$(this).data('imgy', selectedTile_imgY);
});
html
<div class="level">
<div class="a editorTile" ...>
<div class="a editorTile" ...> // affect only this
<div class="a editorTile" ...>
<div class="a editorTile" ...> // or this...
</div>
It already would work the way you have it but it won't be obvious. In this Demo click each line.
this points to the owner of the function which is in this case the specific element that happens to be clicked. A more technical term for an element that gets clicked hovered upon, etc. is said to be the "origin of the event". You can also use the event.target property which (like this but much less confusing) points to the "origin of events". The second example in the Demo shows the use of event.target.
Demo
$('.a').click(function(event){
$(this).css('background', 'red');
});
$('.b').on('click', function(e) {
$(e.target).css('font-size','36px');
});
<div class="levelA">
<div class="a">this</div>
<div class="a">is a</div>
<div class="a">keyword</div>
<div class="a">it works!</div>
</div>
<div class="levelB">
<div class="b">event.target</div>
<div class="b">is a</div>
<div class="b">property</div>
<div class="b">of the Event Object</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here is simple and easy solution:
<div class="level">
<div class="a editorTile">h</div>
<div class="a editorTile">g</div>
<div class="a editorTile">g</div>
<div class="a editorTile">g</div>
</div>
$('.editorTile').each(function(){
$(this).click(function(){
$(this).text("I am clicked");
});
});
or you want something else so you can ask.
You will have to generate dynamic class or id to get that particular div as selector.
The other way of solving this would be to use :eq(n) along with selector if you know which div you have to invoke the click.
For example in your case :-
<div class="level">
<div class="a editorTile" ...>
<div class="a editorTile" ...> // affect only this
<div class="a editorTile" ...>
<div class="a editorTile" ...> // or this...
$("div.editorTile:eq(2)") && $("div.editorTile(4)") gives you second and fourth element.
For that you have to already know the exact div order

Removing div's and keep content

I'm trying to remove the following DIV's:
<div class="whatever_name">
<div class="whatever_name">
<h2>subtitle</h2>
<p>content<p>
</div>
</div>
and need the following output:
<h2>subtitle</h2>
<p>content<p>
Using jQuery, I can not use remove() because it clear the content too. With pure javascript, happens the same.
I have no idea how to accomplish this issue.
Any idea?
EDIT:
Not always the structure is the same. It can vary, i.e.:
<div class="whatever_name">
<div class="whatever_name">
<div class="whatever_name">
<h2>subtitle</h2>
<p>content<p>
</div>
</div>
</div>
Just need an iterator that can handle such task.
Use unwrap() method twice on the children element.
$('.content .post-12')
// get children elements, or use contents()
.children()
// use unwrap twice to unwrap two parents
.unwrap().unwrap()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
<div class="post-12">
<h2>subtitle</h2>
<p>content</p>
</div>
</div>
UPDATE : With the updated content you just need to change the selector with your requirement.
$('div > div > h2,div > div > p').unwrap().unwrap()
// or use
// $('div > div:has(h2):has(p) > *')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="whatever_name">
<div class="whatever_name">
<div class="whatever_name">
<h2>subtitle</h2>
<p>content
<p>
</div>
</div>
</div>

Detach and append divs/html jquery

I thought this would be kinda straightforward but i cant wrap my head around this. I got to following html:
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
I need to grab/detach the div's .test and put/append them into the .item div's. So the first div .test needs to go in the first div .item, the second div .test to the second div .item etc. So it becomes:
<div id="foo">
<div class="item">1<div class="test">test1</div></div>
<div class="item">2<div class="test">test2</div></div>
<div class="item">3<div class="test">test3</div></div>
<div class="item">4<div class="test">test4</div></div>
</div>
Now i found some jquery code and i came to this:
var child = $('#bar').find("div").eq(0);
var parent = $('#foo').eq(0);
child.detach();
parent.append( child );
This works but as suspected, it detaches/appends the first div. Now i need to detach/append them all one by one and from reading a lot of topics, i think i need to put a loop/each in there somewhere but i have no idea how and im not getting any closer after screwing around for hours.
Anyone who can put me in the right direction with this?
You can move all of them easily by just using the append() method and selecting all the divs:
$('#bar').append( $('#foo div') )
/* This is just for showing that the elements actually moved. */
#foo { background:red; }
#bar { background:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
<div>
Alternatively, if you want to do something with each element, you can use .each():
$('#foo div').each(function(i, elem) {
var $elem = $(elem);
//Do stuff
$('#bar').append($elem);
});
/* This is just for showing that the elements actually moved. */
#foo { background:red; }
#bar { background:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
<div>
On solution is to get both collections and iterate over one of the collections. Also note that you don't need to use .detach. .append will already do that.
var $fooItems = $("#foo .item");
var $barTests = $("#bar .test");
$fooItems.each(function(index, el) {
$(this).append($barTests.eq(index));
});
Example Fiddle
I think there are two solutions for your issue : .childern() function or usiing jQuery selectors
For example using selector :
$("#bar > div")
or using children() function :
$("#bar").children("div");
also look at this post, you may have your answer here : jQuery - get all divs inside a div with class ".container"

jQuery selecting and exclude an element inside a div

I'm trying to get all the next html code and excluding the DIV with ID=fiscal-address-info using jquery. I started using filter method but no lucky.
This is the original snippet code.
<div id="fiscal-info" class="content-fields">
<div class="content-title"><h2>Datos Fiscales</h2></div>
<div class="row">...</div>
<div class="row">...</div>
<div class="row">...</div>
<div id="fiscal-address-info">
<div class="row">...</div>
<div class="row">...</div>
</div>
What I'd like to get is:
<div id="fiscal-info" class="content-fields">
<div class="content-title"><h2>Datos Fiscales</h2></div>
<div class="row">...</div>
<div class="row">...</div>
<div class="row">...</div>
<div class="row">...</div>
<div class="row">...</div>
</div>
This is what I've tried:
$('#fiscal-info').filter('#fiscal-address-info');
You can use the filter method and using a not selector:
$("#fiscal-info").children().filter(":not(#fiscal-address-info)")
This return you all the fiscal-info children ,except the excluded one.
You can use the .not() method or :not() selector
http://api.jquery.com/not-selector/
Code based on your example:
$('div#fiscal-info div').not("#fiscal-address-info");
Have a look into this fiddle
$( "div" ).filter( $( "#fiscal-address-info" ) );
Gets all div elements and filters them for id #fiscal-address-info
Hope this helps!
$('#fiscal-info div').filter(function () {
return this.id == 'fiscal-address-info'
}).remove();
jsFiddle example

jquery : dynamic events how to achieve

What is the best way to do this dynamic events linking between divs in jquery.
my HTML page:
<html>
<body>
<div id="parent1"></div>
<div id="parent2"></div>
<div id="parent3"></div>
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</body>
</html>
for each clicked parent i want to .toggle its child
Example :: if parent2 clicked, .toggle will be applied on child2 only
my parents and childs divs are dynamically created so their number is not static, i think .live should be used here, but i have no idea how to achieve that.
Thanks
This should do it, using the rel attribute to note link. You could also do the same thing by parsing the ID and so on, but I find this solution more semantic (if it means something) :
<html>
<body>
<div id="parent1" class="parents" rel="child1"></div>
<div id="parent2" class="parents" rel="child2"></div>
<div id="parent3" class="parents" rel="child3"></div>
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</body>
</html>
jQuery(function(){
jQuery(".parents").live("click", function(){
jQuery("#"+jQuery(this).attr("rel")).toggle();
});
});
This will work with your current structure (another option is to extract the number, same general idea):
$("[id^=parent]").live('click', function(){
var childId = this.id.replace('parent', 'child');
$('#' + childId).toggle();
});
Using the startsWith selector and slightly modded ID values, because the underscore character eliminates the need for a regex:
<div id="parent_1" class="parents"></div>
<div id="parent_2" class="parents"></div>
<div id="parent_3" class="parents"></div>
<div id="child_1"></div>
<div id="child_2"></div>
<div id="child_3"></div>
$("div[id^=parent]").click(function() {
$('#child_' + $(this).attr('id').split('_')[1]).toggle();
});
I also like #Kobi's approach.
Use a class for these divs and use the class selector.
$(".divclass").live ( "click" , function() {
$(this).find("yourchildelementselector").toggle();
});
If its a parent child relation then better put the child divs inside the parent element.
<div id="parent1" class="parent"><div id="child1" class="child"></div></div>
<div id="parent2" class="parent"><div id="child2" class="child"></div></div>
<div id="parent3" class="parent"><div id="child3" class="child"></div></div>
and you can call the click event as
$("div.parent").live ( "click" , function() {
$(this).find("div.child").toggle();
});

Categories

Resources