Jquery closest find issue - this.closest(...).find is not a function - javascript

Why my (this).closest('.row').find('.col-lg-10').remove(); doesn't work and sending me errors in log?
<div class="row section-first">
<div class="col-lg-2 text-center text-grayer my-auto p-2">
<p class="h6">Newbie</p>
<p class="h5">
<i class="fa fa-diamond m-1" aria-hidden="true"></i>
<i class="fa fa-diamond m-1" aria-hidden="true"></i>
</p>
<img class="mb-1 border-gray" src="http://localhost/forum/public/storage/avatars/1598320e3908c6.jpg" style="width: 112px; height: 112px;"/>
<p class="small m-0">Cirapuszka</p>
<!-----------------------------------------------------------------------------Reputacja----------->
<p class="m-0"><span class="badge bg-success"><i class="fa fa-plus-square" aria-hidden="true"></i> 0</span></p>
<p class="m-0"><span class="badge bg-inverse"><i class="fa fa-minus-square" aria-hidden="true"></i> 0</span></p>
<p class="text-muted">3 postów</p>
<!------------------------------------------------------------------------Button do edycji posta--->
<button class="btn btn-info btn-sm pointer post-edit">Edytuj Post</button>
</div>
<div class="col-lg-10 text-gray p-2">
<p>
Lorem ipsum dolor sit amet...
</p>
</div>
<div class="offset-lg-2 small col-lg-9">
</div>
This is my HTML
And I have here this button
<button class="btn btn-info btn-sm pointer post-edit">
Edytuj Post
</button>
It it scripted in jquery like this:
$(document).on('click', 'button.post-edit', function(e){
e.preventDefault();
(this).closest('.row').find('.col-lg-10').remove();
});
Uncaught TypeError: this.closest(...).find is not a function
at HTMLButtonElement.<anonymous> (voluptas-eum-voluptatem-soluta-numquam-ipsum-totam-est:293)
at HTMLDocument.dispatch (jquery.js:3)
at HTMLDocument.q.handle (jquery.js:3)
It works when it is like (this).closest('.row').remove(); It deletes whole row, but it's not what I intend to do.
col-lg-10 containing content in this post have to be deleted.
So I try using (this).closest('.row').find('.col-lg-10').remove(); but as I said this doesn't work and I don't know why, because we go first to .row by traversing UP in DOM by closest and then down by find to col-lg-10
What is wrong here?

As noted in the question comments, you're missing the jQuery identifier.
Change this:
(this).closest('.row').find('.col-lg-10').remove();
To this:
$(this).closest('.row').find('.col-lg-10').remove();

Related

Angular ngbDropdown: keyboard navigation not working

I have modal made of a search bar and a list of elements, created with a ngbDropdown splitted into 2 components, parent and child. It works correctly, but I can't figure out a way to enable navigation with keyboard (use UP & DOWN keys to move between list's elements).
Following the official documentation, I tried to use ngbDropdownItem, but it's not working.
These are my 2 component's templates:
PARENT:
<div ngbDropdown class="dropdown-no-arrow" (openChange)="openChange($event)" container="body">
<!-- trigger -->
<ng-container>
<button class="btn" ngbDropdownToggle *ngIf="authorizationService.loggedInUser">
<i class="fal fa-farm me-2"></i>
<span>{{ authorizationService.loggedInUser.name }}</span>
<i class="fal fa-chevron-down ms-2"></i>
</button>
</ng-container>
<!-- menu -->
<div ngbDropdownMenu aria-labelledby="currentMenuItem" id="currentDropdown_{{ id }}">
<button ngbDropdownItem (click)="openNewModal()">
<i class="fal fa-plus me-1"></i> <span i18n>New</span>
</button>
<dm-child-list [isListDisplayed]="isDropdownOpened"></dm-child-list>
</div>
</div>
CHILD:
<div class="dropdown-header d-flex margin-x align-items-center">
<h6 class=" mb-0 flex-grow-1" i18n>MY LIST</h6>
</div>
<div class="px-4 py-2">
<div class="form-group mb-0">
<input class="form-control form-control-sm" libAutofocus [(ngModel)]="elSearch" (ngModelChange)="elSearch$.next($event)" i18n-placeholder placeholder="Search elements">
</div>
</div>
<button *ngFor="let el of list; let i = index;" ngbDropdownItem [ngClass]="{'top-border': i === 0}">
<i class="me-2 fas fa-check-circle text-success"
*ngIf="selectedEl?.id === el.id" title="Current element"></i>
<i class="me-2 fal fa-circle" *ngIf="selectedEl?.id !== el.id"></i>
<span>{{ el.name }}</span>
</button>
Can anyone help with making keyboard selection work?
Thanks!
By adding
#myDrop="ngbDropdown" (keyup)="myDrop.onKeyDown($event)"
on div where ngbDropdown directive is used, Arrow key navigation works.
In your case,
<div ngbDropdown
#myDrop="ngbDropdown"
(keyup)="myDrop.onKeyDown($event)"
class="dropdown-no-arrow
(openChange)="openChange($event)"
container="body">

Escaping a backslash in selector

I'm trying to escape a backslash into one of my selector :
if ( $("#\38 b13d5ea8c7081ff2ed6e34ab9d05ced > div.small-box.bg-red").hasClass("bg-red") ) {
//do something it does have the protected class!
console.log("i have the protected class");
}
Tried already :
#//\38 b13d5ea8c7081ff2ed6e34ab9d05ced > div.small-box.bg-red//
#//\38 b13d5ea8c7081ff2ed6e34ab9d05ced > div.small-box.bg-red//
but it doesn't fix the issue. Would appreciate your expertise.
Cheers!! , Marc
Additional informations :
I need to check if the "bg-red" class exists in one of the following div :
HTML
<div id="area4" class="col-sm-3 connectedSortable ui-sortable">
<div id="8b13d5ea8c7081ff2ed6e34ab9d05ced" class="border-box">
**<div class="small-box bg-red">**
<div class="inner inner-box">
<p> </p>
<p>Veuillez svp saisir vos coordonnées<br><br></p>
</div>
<div class="icon">
<i class="ion ion-person"></i>
</div>
Saisir mes coordonnées <i class="fa fa-arrow-circle-right"></i>
</div>
<div class="action pull-right">
<i class="fa fa-pencil"></i>
<i class="fa fa-trash"></i>
</div>
</div>
</div>
Escape the backslash itself:
$("#\\38 ...")
Please check this once or let me know if anything else is required
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#button").on('click',function(){
var a = $("div#8b13d5ea8c7081ff2ed6e34ab9d05ced div.small-box")
console.log(a)
if(a.hasClass("bg-red")){
alert("hii")
}
})
});
</script>
</head>
<body>
<button id="button">Click to check class</button>
<div id="area4" class="col-sm-3 connectedSortable ui-sortable">
<div id="8b13d5ea8c7081ff2ed6e34ab9d05ced" class="border-box">
**<div class="small-box bg-red">**
<div class="inner inner-box">
<p> </p>
<p>Veuillez svp saisir vos coordonnées<br><br></p>
</div>
<div class="icon">
<i class="ion ion-person"></i>
</div>
Saisir mes coordonnées <i class="fa fa-arrow-circle-right"></i>
</div>
<div class="action pull-right">
<i class="fa fa-pencil"></i>
<i class="fa fa-trash"></i>
</div>
</div>
</div>
</body>
</html>
2 SOLUTIONS provided by
I forgot to import jquery in my blade file, after having done it, it works.
#adesh-kumar
$('div .small-box').hasClass('bg-red')
#Jack-bashford
$('#\\38 b13d5ea8c7081ff2ed6e34ab9d05ced').hasClass('bg-red');
Thanks both of you for your time and help.
A special thanks to the one who minus my question, that's really help, thank you so much...

Loop through items in HTML table using jQuery

I have a table.
I want to go through all the goods and get their quality and price.
But i can't figure out how to get these values.
table:
<div class="table-items__container">
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">1</div>
<div class="item_price">30</div>
<div class="table-items_item__controls">
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">2</div>
<div class="item_price">20</div>
<div>
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">3</div>
<div class="item_price">10</div>
<div>
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
</div>
<div class="Summary">Summary: <span></span></div>
Script:
$('.table-items__item').children().each(function(){
console.log($(this).text());
});
I think that's all needed.
Then I need to calculate the price of all items.
http://jsfiddle.net/mg4wjfbu/
Iterate over the wrapped div and within the callback function get element within current div by specifying context argument or using find() method(within callback this refers to the current element).
$('.table-items__item').each(function() {
console.log($('.item_quality', this).text(), $('.item_price', this).text());
// or
console.log($(this).find('.item_quality').text(), $(this).find('.item_price').text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-items__container">
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">1</div>
<div class="item_price">30</div>
<div class="table-items_item__controls">
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">2</div>
<div class="item_price">20</div>
<div>
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
<div class="table-items__item">
<div class="item_name">Name</div>
<div class="item_quality">3</div>
<div class="item_price">10</div>
<div>
<i class="fas fa-edit"></i>
<i class="fas fa-trash"></i>
</div>
</div>
</div>
<div class="Summary">Summary: <span></span></div>
</div>

jQuery $.post return incomplete data

I've come across a strange behavior of a $.post command.
I have an AJAX request by $.post(param,returned data), which loads pictures onto the page of the visitor.
This is the code, with a little bit of animation:
function showPicturesByCat(cat){
$('.local-overlay').fadeIn(200);
$('#picturesByCat').stop().animate({height: '0px' },200);
setTimeout(function(){
$.post('./ajax/populate.php',{operation:'show-pictures-on-front',cat:cat})
.done(function(data){
$('#picturesByCat').html(data);
setTimeout(function(){
var inaltime = $('#picturesByCat')[0].scrollHeight+20;
$('#picturesByCat').stop().animate({height: inaltime+'px' },500);
$('#picturesByCat').css({opacity: 1});
$('.local-overlay').delay(500).fadeOut(300);
},300);
$('html, body').delay(200).stop().animate({
scrollTop: $('#picturesByCat').offset().top
},300);
});
},200);
}
On the PHP side, it's just a loading of pictures with names inside a database, based on the chosen category (cat).
Code works perfectly ... on PC,s, but when it turns to mobile, both Chrome and Firefox do the same wierd thing.
When I choose a category, the pictures loads but not completely. If you scroll to the bottom, you'll see the thing. If I tap the second time on the same category, the pictures loads completely.
Here's the address
http://adrianmalancaphotography.com/en/fotografie
I can't figure this out, it's too wierd for me. Maybe some of you can spot or already know what it's wrong.
Edited:
this is the dump data, as requested in comments.
<hr class="hr-white">
Peisaj
<hr class="hr-white">
<div class="col-12">
<div class="card-columns">
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Maci 2</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-22.jpg" class="img-fluid" width="100%" alt="fotografie Maci 2" onClick="showImage(22)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Grau</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-17.jpg" class="img-fluid" width="100%" alt="fotografie Grau" onClick="showImage(17)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Apa incetosata</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-15.jpg" class="img-fluid" width="100%" alt="fotografie Apa incetosata" onClick="showImage(15)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Apus intunecat</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-14.jpg" class="img-fluid" width="100%" alt="fotografie Apus intunecat" onClick="showImage(14)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Nori cenusii</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/preview/AMP-IMG-13.jpg" class="img-fluid" width="100%" alt="fotografie Nori cenusii" onClick="showImage(13)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>La tara</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-12.jpg" class="img-fluid" width="100%" alt="fotografie La tara" onClick="showImage(12)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Ponton</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-10.jpg" class="img-fluid" width="100%" alt="fotografie Ponton" onClick="showImage(10)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Lebede</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-9.jpg" class="img-fluid" width="100%" alt="fotografie Lebede" onClick="showImage(9)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Apus pe apa</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-8.jpg" class="img-fluid" width="100%" alt="fotografie Apus pe apa" onClick="showImage(8)"> </div>
<div class="card card-block p-0 foto-card my-2">
<div class="img-over-info"> <span>Camp cu maci</span> <span class="pull-right action-icons"> <i class="fa fa-shopping-cart"></i> <i class="fa fa-eye"></i> </span> </div>
<img src="./images/small/AMP-IMG-4.jpg" class="img-fluid" width="100%" alt="fotografie Camp cu maci" onClick="showImage(4)"> </div>
</div>
</div>
Hope it helps, although I can't see anything wrong.
The problem does not come from $.post. The problem is caused by:
var inaltime = $('#picturesByCat')[0].scrollHeight+20;
$('#picturesByCat').stop().animate({height: inaltime+'px' },500);
REASON:
Since the height is not properly calculated because, when your images start loading, its height is not calculated right, then your #picturesByCat is limited to your wrong calculated value, so it is not fully displayed, but the images are loaded correctly.
The second time you clicked on the category, those images are fully displayed and have right height, then the problem is gone.
RESOLUTION:
Set the height back to auto when your animation is finished:
$('#picturesByCat').stop().animate({height: inaltime+'px' },500, function(){
$('#picturesByCat').css('height', 'auto');
});

Hide divs on click - multiple boxes

I have a bit long info submission form. I have an option that someone click "add another", there is a notification box display with text like "Success!" like that with close button. Please check this image.
Therefore I have three "add another" buttons and three success alerts. When someone click close, that alert message needs to be disappear.
The problem
I used javascript for that success box. It does these things.
Click "Add another" button, appears success box. Click close button on
success box, box disappears.
Here is my code.
document.querySelector(".add-box").addEventListener("click", function() {
document.querySelector(".add-box-wrap").style.display = "inline-block";
});
document.querySelector(".add-box1").addEventListener("click", function() {
document.querySelector(".add-box-wrap1").style.display = "inline-block";
});
document.querySelector(".add-box2").addEventListener("click", function() {
document.querySelector(".add-box-wrap2").style.display = "inline-block";
});
$(".claim-btn-close").click(function() {
$(".add-box-wrap").hide();
});
$(".claim-btn-close1").click(function() {
$(".add-box-wrap1").hide();
});
$(".claim-btn-close2").click(function() {
$(".add-box-wrap2").hide();
});
<!-- This goes end of html page -->
function hide(target) {
document.getElementsByClassName(target).style.display = 'none';
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--Success form-->
<div class="add-box-wrap">
<div class="claim-btn-close" onclick="hide('.claim-btn-close')">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box">Add another<i class="fa fa-plus"></i></a>
</div>
See.. there is a major problem with code repeating. (I didn't repeat html codes, just post here one example) I would like to know the best practice to achieve things like this.
For displaying the notification box without repeating the code, one of the way is you could make use of data attributes. Change the data attribute for all the buttons and let the class .add-box be the same. like so:
<div class="add-box-wrap1" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="1">Add another<i class="fa fa-plus"></i></a>
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="2">Add another<i class="fa fa-plus"></i></a>
</div>
And change your Jquery to just one function.
$(".add-box").click(function() {
$(".add-box-wrap" + $(this).data('target')).show(); //.add-box-wrap1 or .add-box-wrap2
});
Explanation of the above line: It just means we are getting the value of the "clicked" button's data-target value(which is 1 or 2) AND appending that value to the "add-box-wrap"(which will be add-box-wrap1 or add-box-wrap2) to search for that element to display it using .show().
Using show() or .css jquery functions is upto you. But I suggest not to mix both vanilla JS and JQuery codes(like in your question).
Closing
You can simply use closest or parent, like so:
$(".claim-btn-close").click(function(){
$(this).parent().hide();
});
$(".add-box").click(function() {
$(".add-box-wrap" + $(this).data('target')).show();
});
$(".claim-btn-close").click(function(){
$(this).parent().hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-box-wrap1" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="1">Add another<i class="fa fa-plus"></i></a>
</div>
<!--Add another button -->
<div class="col-lg-10 col-md-10 col-sm-12 no-padding">
<a class="add-box" data-target="2">Add another<i class="fa fa-plus"></i></a>
</div>
Update on another question(3 column):
Using bootstrap, you can wrap the add-box-wrap divs within a .row and give each of it a class like col-*-4(class="col-xs-4 col-md-4 col-lg-4") assuming you have 3 success buttons(12/3 = 4). So the first part of your html would become
<div class="row">
<div class="add-box-wrap1 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap2 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
<div class="add-box-wrap3 col-md-4 col-lg-4" style="display: none;">
<div class="claim-btn-close">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
Success!
</div>
</div>
You can use DOM relationship to target the desired element. Bind event handlers using a common class then use .closest() to traverse up desired element.
$(".claim-btn-close").click(function(){
$(this).closest(".add-box-wrap").hide();
});
If element are dynamically generate use Event Delegation approach.
$(staticParentElemet).on('click',".claim-btn-close",function(){
$(this).closest(".add-box-wrap").hide();
});

Categories

Resources