Selecting nested elements - javascript

I have a page hierarchy like this:
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
....
So I have a bunch of these panels with nested panels inside, and I'm trying to create on on click handler for the delete buttons of the top level panels only (so the ones immediately inside panels that do not have an association id). The only different between the parent and child panels is that the child ones have the extra attribute "association-id".
So I can select the top level panels only like so:
$('.panel[attribute-id]:not([association-id]')
But if I try to get the delete buttons from from these like:
$('.panel[attribute-id]:not([association-id] .delete')
Obviously I'm still going to get the child buttons.
I can't modify the html in anyway, how could I go about doing this?

$(':not(.panel[attribute-id][association-id]) > .delete')
seems to do the trick.
jsfiddle
I've changed .panel-group to .panel to get it to work with the HTML provided.

Wrap them all in a div and assign that div a unique class. Then you can use jquery selector ".panel-group > .panel" to get only direct children of top level.
<div class="panel-group">
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
<div class="panel" attribute-id="11">
<button class="delete">
<div class="panel" attribute-id="12" association-id="120">
<button class="delete">
</div>
</div>
</div>

You can use the children method:
$('.panel-group[attribute-id]').children('button').first()

Related

Angular access DOM sibling element to alter css class

How do I gain access to the respective sibling element of my button from the ngFor iteration on my collection?
Dom Element, I'm attempting to access this DOM element, so I can alter the sibling element div.popup class. As shown in the Codepen example linked at the bottom of the post.
I'm very new with angular, please advise.
<button
#popBtn
href="#"
id="info"
class="info popup-trigger"
title="info"
(click)="PopUp($event)"
>
Popup
</button>
Prior to the posting here, I read on the following articles but I couldn't understand completely or relate to it.
Pass a reference to DOM object with ng-click
how to get DOM element with ng-click
How to get the element html clicked in a ngFor to add a css class?
Overview of code
Component.html
<section class="ArticlesGrid">
<div *ngFor="let article of articles" class="windowsBox">
<article class="ui-titlebar">
<h4 class="ui-titletext">{{article.title}}</h4>
</article>
<div class="windowsScreen">
<button
#popBtn
href="#"
id="info"
class="info popup-trigger"
title="info"
(click)="PopUp($event)"
>
Popup
</button>
<div class="popup" role="alert">
<div class="popup-container">
Close
<p>{{article.content}}}</p>
</div>
</div>
</div>
<p class="windowsTech">
Technologies:
<span class="THtml"></span>
<span class="TCss"></span>
<span class="TJs"></span>
</p>
</div>
</section>
Component.ts
PopUp(event: Event) {
//console.log(this.viewBtn.nativeElement.nextElementSibling.classList.toggle("is-visible"));
console.log(event);
// this.viewBtn.nativeElement.
}
SandBox Mockup
https://stackblitz.com/edit/angular-collection-popup?file=src/app/app.component.html
Function to mirror
https://codepen.io/Gugiui/pen/vweXYR
Thanks for reading my question. I hope you can advise/guide me
add template reference variable on popup div -
<div class="popup" role="alert" #popupDiv>
pass it in button click function -
(click)="PopUp($event, popupDiv)"
change class in PopUp method using plain javascript -
PopUp(event: Event, element) {
element.classList.remove('popup');
element.classList.add('test');
console.log(element.classList);
}

How to get only child elements outside a certain class jquery

This is the scenario. The black element has an ID and theoretically I want to select like this:
$("#someid .class2")...
I don't want to get the element inside the red element though. And yes, the classes are written correctly, the red element and black have the same class...
Also, there may be elements between any of these elements (like in nested - the green element inside the red one might be nested inside multiple other elements, so the red one is not necessarily the parent)
So basically ignore all class1 elements other than itself.
How can I get this?
Edit: I added 2 examples. The query, whatever it is, should work for both.
Example 1
<div id="someid" class="class1">
<div class="class1">
<div>
<span class="class2"></span> <---- NO
</div>
</div>
<div>
<span class="class2"></span> <-----YES
</div>
</div>
Example 2
<div id="someid" class="class1">
<div>
<div>
<div class="class1">
<div>
<span class="class2"></span> <---NO
</div>
</div>
<span class="class2"></span> <-------YES
</div>
</div>
<div class="class1">
<span class="class2"></span> <--------NO
</div>
<span class="class2"></span> <-----------YES
</div>
console.log(document.querySelectorAll("#test1 > .class2"))
<div id="test1" class="class1">
<div class="class1">
<div class="class2">test 3</div>
</div>
<div class="class2">test 1</div>
</div>
In this example im using vanilla javascript but with jQuery the css selector it would be the same.

jquery add class to closest parent

I have a form, and some the fields are set inside 3 groups of collapsible divs, I wan't after the validation that if any field has errors the parent div receive a class to unfold it.
<div class="panel-group" id="fields_panel">
<div class="panel panel-primary">
<div id="basic_info_fields" class="panel-collapse collapse in"> <!-- add class "in" -->>
<div class="panel-body">
<div class="row clearfix">
<div class="col-md-12 m-b-0">
<div class="form-group">
<div class="form-line error"> <!-- if this div has "error" -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I have two more panels with the same structure, eacho one with a couple of fields, I'm trying to find if any form-line has error and append to the panel-collapse parent the class in to unfold it.
Right now I have the following jquery code:
$(function () {
var elem = $('.panel').find('.form-line');
if (elem.hasClass('error')) {
elem.closest('.panel-collapse').addClass('in');
};
});
But it apply the in class to all panel-collapse.
What should I do to apply it only to the top level parent that have a child element with that class, and not to all parents?
Your hasClass won't work as elem is an array of jQuery objects - not just one.
Why do you need it - why not just include the class in your selector:
$('.panel').find('.form-line.error').closest('.panel-collapse').addClass('in');
This also stops you looping through elements in the array that doesn't have the class thus improving efficiency
Use following code:
$('.panel').find('.form-line.error').each(function(){
$(this).closest('.panel-collapse').addClass('in');
});
$(this) refers to the specified element which has the error class.

jQuery DataTables append div to specific place

I have code:
<div class="addButton col-lg-6">
<button type="button" class="btn btn-primary" data-toggle="modal">BTN</button>
</div>
<div class="table-responsive">
<div id="PositionDataTable2_wrapper" class="dataTables_wrapper form-inline dt-bootstrap no-footer">
<div id="PositionDataTable2_processing" class="dataTables_processing" style="display: none;">Processing...</div>
// place where <div class="addButton"> should appear
<div id="PositionDataTable2_filter" class="dataTables_filter"></div>
<div class="dataTables_paginate paging_simple_numbers" id="PositionDataTable2_paginate"></div>
</div>
</div>
I want to take first div, which has addButton class and put into div PositionDataTable2 and place it between the processing and filter parts. But append and prepend only does it inside div start or end.
Also it would be great, if someone would suggest how to place it correctly and make a copy or so that my button wouldn't disappear on datatable fndestroy and recreate.
You could try using the $.after() insert like:
$(".dataTables_processing").after($(".addButton").html());
Jquerys insertAfter() should work.
Try something like this:
$('div.addButton').insertAfter('div#PositionDataTable2_wrapper');
EDIT: If you don't want that the first addButton disappears you could use .clone()
$('div.addButton').clone().insertAfter('div#PositionDataTable2_wrapper');

Enumerating data-targets in ng-repeat

I have an accordion in my HTML that is dynamically populated as such -
<div class="accordion">
<div class="accordion-panel">
<div class="accordion-heading>
<a data-target="#collapse" data-toggle="collapse">{{x.header}}</a>
</div>
<div id="collapse" class="accordion-body">
....
</div>
</div>
</div>
The problem is that the data-target remains static. So all the open/close buttons only open one piece of the accordion! The solution would be to enumerate the data-target/ids based on $index, but I don't know how to do that.
Is there a way to enumerate attributes in the way that I described? Or is there another solution I can use?
Just replace data-target value with #collepse-{{$index}} and ID of body with 'collapse-{{$index}}'
Hope this might be helpful to you!!

Categories