Retrieve a specific parent of child button using jQuery - javascript

I have this html structure (very general), the id of the div is added dynamically, by a function that creates sequential objects made this way:
<div id="mydiv1">
<div> Stuff</div>
<div>
<button id="remove"></button>
</div>
</div>
The button "remove" should remove the div where he is, so I have to retrieve the id of the div to do it. I do not know how. How can you make using jQuery? thank you
<form>
<div id="mydiv1">
<div> Stuff</div>
<div>
<button id="remove"></button>
</div>
</div>
<div id="mydiv2">
<div> Stuff</div>
<div>
<button id="remove"></button>
</div>
</div>
</form>
I tried:
("#remove").click(function(event) {
var id = event.target.id;
}
But the result is: "remove" instead of "mydiv1" or "mydiv2"

You should use class instead of id for the buttons (id should be unique):
$('.remove').click(function() {
$(this).closest('div[id^="mydiv"]').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<div id="mydiv1">
<div>Stuff 1</div>
<div>
<button class="remove">REMOVE</button>
</div>
</div>
<div id="mydiv2">
<div>Stuff 2</div>
<div>
<button class="remove">REMOVE</button>
</div>
</div>
</form>
EDIT: Updated to new code posted by OP

For mydiv2 change button like this:
$(".remove").click(function() {
var id = $(this).data('id');
$("#mydiv"+id).remove();
}
<button class="remove" data-id="2"></button>

Use $(this).parent('div') to get the first parent node of type <div>
$("#remove").click(function(event) {
var parent = $(this).parent('div');
parent.remove();
}
EDIT
So add a class to your divs, let say .divRow for example
<form>
<div id="mydiv1" class="divRow">
<div> Stuff</div>
<div>
<button id="remove"></button>
</div>
</div>
<div id="mydiv2" class="divRow">
<div> Stuff</div>
<div>
<button id="remove"></button>
</div>
</div>
</form>
and your javascript would be in this case
$("#remove").click(function(event) {
var parent = $(this).parent('.divRow'),
id = parent.attr("id");
alert(id);
parent.remove();
}

Try
$('.remove').click(function() {
var id = $(this).parent().parent().attr('id');
//This will give you the id
});
For the next part of your question try this:
$(document).on('click','.remove',function() {
var id = $(this).parent().parent().attr('id');
//This will give you the id
});

Related

JavaScript .closest returning null

I have the following simple layout which I am unable to change. I am trying to use JavaScript to get the extra element which is closest to the button that was pressed
With help from another question I was able to get the preventDefault part working but now I am struggling with closest
<div class="buttons">
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">64736</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">5446</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">78667</div>
</div>
</div>
document.querySelector('.myButton').addEventListener('click', myFunction);
function myFunction() {
event.preventDefault();
close = this.closest(".extra");
console.log(close)
}
But this is giving me null when I press the button, where am I going wrong?
A combination of closest and querySelector can be used:
document.querySelectorAll('.myButton').forEach(function(button) {
button.addEventListener('click', myFunction);
});
function myFunction(evt) {
evt.preventDefault();
var closest = evt.currentTarget.closest(".button").querySelector('.extra');
console.log(closest)
}
<div class="buttons">
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">64736</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">5446</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">78667</div>
</div>
</div>
More info:
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
.closest traverses up the dom and does not look at sibling or child elements. In the answer by #MaartenDev he is using .closest to step up one level and target the buttons parent div. He then chains queryselector to step back down into the children and select using the .extra class.
Another solution would be to use .nextElementSibling so you do not have to step up and back down. This would only work if your html elements were direct siblings and the item you were trying to target followed the element you were calling nextElementSibling on.
Here is an example of this.
document.querySelectorAll('.myButton').forEach(function(button){
button.addEventListener('click',myFunction);
})
function myFunction() {
event.preventDefault();
var closest = this.nextElementSibling;
console.log(closest);
}
<div class="buttons">
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">64736</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">5446</div>
</div>
<div class="button">
<button class="myButton">Click Me</button>
<div class="extra">78667</div>
</div>
</div>

Getting value of internal div when outside div is clicked

I have the following: A bunch of button div's which each have unique info
<div class="button">
<div id="first">
Johny
</div>
<div id="second">
Dog
</div>
<div id="third">
Pasta
</div>
</div>
<div class="button">
<div id="first">
Bob
</div>
<div id="second">
Cat
</div>
<div id="third">
Noodles
</div>
</div>
.
.
.
I'm trying to make it so that when one of these buttons is clicked, i can check the values of the inner divs.
For instance
$('.button').on('click', function () {
// Check to see if the text of the 'first' div is
// johnny or bob or something else
});
First of all you cannot use same id for multiple elements in a page.So,Instead use class for that.Ex:
<div class="button">
<div class="first">
Johny
</div>
<div class="second">
Dog
</div>
<div class="third">
Pasta
</div>
</div>
<div class="button">
<div class="first">
Bob
</div>
<div class="second">
Cat
</div>
<div class="third">
Noodles
</div>
</div>
Now in the javascript:
$('.button').on('click', function () {
var first=this.getElementsByClassName("first")[0];//gets first element of this button
var second=this.getElementsByClassName("second")[0];
var third=this.getElementsByClassName("third")[0];
//Now you do what ever you want
});
Try $(this).children(":first").text() to get fist div's text
<script>
$('.button').on('click', function () {
if ($(this).find("#first").html().trim() == "Johny") {
console.log("The first div is Johny");
} else if ($(this).find("#first").html().trim() == "Bob") {
console.log("The first div is Bob");
}
});
</script>
How about giving each div its own click handler? (you will need unique ids for this to work properly)
<script type="text/javascript">
var bchildren = $('.button').children();
$(bchildren).click(function() {
console.log($(this).html());
});
}
</script>

put multi div and another multi div

I want to put a div in another div using js. I found a solution can do this but just put 1 div in div. Below html is my situation.
For example:
<body>
<div>
<span class="outer_part">
</span>
<div class="inner_part">1
</div>
</div>
<div>
<span class="outer_part">
</span>
<div class="inner_part">2
</div>
</div>
<div>
<span class="outer_part">
</span>
<div class="inner_part">3
</div>
</div>
</body>
Result:
<body>
<div>
<span class="outer_part">
<div class="inner_part">1</div>
</span>
</div>
<div>
<span class="outer_part">
<div class="inner_part">2</div>
</span>
</div>
<div>
<span class="outer_part">
<div class="inner_part">3</div>
</span>
</div>
</body>
I found solution but not work
<script>
$('.inner_part').appendTo('span.outer_part');
</script>
Your problem is that you appending all the .inner_part elements to all the .outer_part elements, but you only need to do a portion of that.
You can use each() to loop over all the .inner_parts, and attach each to its previous sibling, which is the .outer_part.
// loop over all inner parts
$('.inner_part').each(function() {
var innerPart = $(this);
var outerPart = innerPart.prev(); // inner part's previous sibling is the outer part
innerPart.appendTo(outerPart);
});
Or, shorter:
$('.inner_part').each(function() {
$(this).appendTo($(this).prev());
});
Get element by the ID, then add html inside of it to add a div in this case or anything you want.
document.getElementById('div1').innerHTML += '<div class="inner_part">1</div>';
<div id="div1"></div>

Performance wise and fastest way to get all element with Id inside a container element

I am trying to refactor and make a performance wise code.
The idea of the code is to update the id or value of all element with id or value that needs to be updated that happens when an element has been removed / deleted
So what I am trying to do is get all element with Id or value inside a container element (which is possible to be nested in 2 to 4).
At the moment, I am using jQuery to this task. I added a class on every element that has Id and use jQuery .find() to get all of this element using the class I've assign to them .. which is I really hate about my code and wanted to change as well if there's another best way to do it.
So is there a fastest way and performance wise at the same time to do this task?
$("button").on("click", function(){
$($(this).val()).remove();
updateParagraph();
});
function updateParagraph() {
$(".paragraphs").each(function(index, data){
var dataId = data.id.split("-");
var idIndex = dataId[dataId.length-1];
var index = index + 1;
if (index != idIndex) {
dataId.splice(-1, 1);
dataId.push(index);
dataId = dataId.join("-");
$(this).attr("id", dataId);
setChildElementsId($(this), index)
}
});
}
function setChildElementsId(parent, inx) {
$(parent).find(".id-holder").each(function(index, data){
if (data.id) {
var dataId = data.id.split("-");
dataId.splice(-1, 1);
dataId.push(inx);
dataId = dataId.join("-");
$(this).attr("id", dataId);
if(isParagraph(data.tagName)) {
$(this).text(inx);
}
}
else if (data.value) {
var dataValue = data.value.split("-");
dataValue.splice(-1, 1);
dataValue.push(inx);
dataValue = dataValue.join("-");
$(this).val(dataValue);
}
});
}
function isParagraph(tagName){
return tagName == "P";
};
<div id="container-1" class="paragraphs">
<div id="header-container-id-1" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-1" class="id-holder">
<p id="id-1" class="id-holder">1</p>
</div>
<button value="#container-1" class="id-holder">delete</button>
</div>
<div id="container-2" class="paragraphs">
<div id="header-container-id-2" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-2" class="id-holder">
<p id="id-2" class="id-holder">2</p>
</div>
<button value="#container-2" class="id-holder">delete</button>
</div>
<div id="container-3" class="paragraphs">
<div id="header-container-id-3" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-3" class="id-holder">
<p id="id-3" class="id-holder">3</p>
</div>
<button value="#container-3" class="id-holder">delete</button>
</div>
<div id="container-4" class="paragraphs">
<div id="header-container-id-4" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-4" class="id-holder">
<p id="id-4" class="id-holder">4</p>
</div>
<button value="#container-4" class="id-holder">delete</button>
</div>
<div id="container-5" class="paragraphs">
<div id="header-container-id-5" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-5" class="id-holder">
<p id="id-5" class="id-holder">5</p>
</div>
<button value="#container-5" class="id-holder">delete</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If I understand your question correctly, you're looking to more elegantly identify which elements have an id of the form "__-id-#" or simply "id-#".
If this is the case, take a look at some more advanced jQuery selectors. One in particular which might meet your needs is the Attribute Contains Selector.
For instance, I think $(parent).find("[id*='id-']") might do what you're looking to do.
While I understand what you're attempting to do, I don't quite understand why you're doing this in the first place.
Unless there are restrictions that force you to structure your HTML like you did, well, don't. Aim for the simplest structure:
<div id="container-123" class="paragraphs">
<h4>Header</h4>
<p>1</p>
<button type="button">delete</button>
</div>
Remove the <div>s around the <h4> and the <p> unless you need them for some styling reason. The <button> doesn't need to know its ID, because it's a child element of the container, so you're delete handler could make use of that fact:
$(document.body).on("click", "button", function() {
$(this).closest('.paragraphs').remove();
});
If there are outside forces that require a specific ID (e.g. for linking to an anchor), keep that on the top container element. If your CSS targets elements by ID, refactor the CSS.
I would like to answer your question using javascript. In fact you don't need any of those id-s
I hope I'm not too late.
let buttons = Array.from(document.querySelectorAll(".id-holder"));
buttons.forEach(b => {
//for each button add an event listener
b.addEventListener("click", () => {
b.parentElement.parentElement.removeChild(b.parentElement);
resetNums();
});
});
function resetNums(){
// reseting the text inside the p
let btns = Array.from(document.querySelectorAll(".id-holder"));
btns.forEach((bt,i)=>{
let theP = bt.parentElement.querySelector("p");
theP.innerHTML = i+1;
})
}
<div>
<div>
<h4>Header1</h4>
</div>
<div>
<p>1</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header2</h4>
</div>
<div>
<p>2</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header3</h4>
</div>
<div>
<p>3</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header4</h4>
</div>
<div>
<p>4</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header5</h4>
</div>
<div>
<p>5</p>
</div>
<button class="id-holder">delete</button>
</div>

Create a div inside div with same class name

I have the following structure of my HTML code:
<div id="bb-bookblock" class="bb-bookblock">
<div class="bb-item">
<div class="bb-custom-side">
Hello
</div>
<div class="bb-custom-side">
<button id="add">Click Here to add The page</button>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is first page</p>
</div>
<div class="bb-custom-side">
<p>Hello</p>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is second Page</p>
</div>
<div class="bb-custom-side">
<p>This is last page</p>
</div>
</div>
</div>
When I click on button with id=add I want to create the a new div after the last bb-item div with same two div inside it having class name bb-custom-side.
I know how to create the div using createElement and it a class, but I don't know how to create the sub div inside that newly created div. Can I associate with the last child or similar concept?
So after click event I want my HTML to be something like this:
<div id="bb-bookblock" class="bb-bookblock">
<div class="bb-item">
<div class="bb-custom-side">
Hello
</div>
<div class="bb-custom-side">
<button id="add">Click Here to add The page</button>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is first page</p>
</div>
<div class="bb-custom-side">
<p>Hello</p>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is second Page</p>
</div>
<div class="bb-custom-side">
<p>This is last page</p>
</div>
</div>
<--Newly created div-->
<div class="bb-item">
<div class="bb-custom-side">
new div
</div>
<div class="bb-custom-side">
new div 2
</div>
</div>
</div>
Use clone() to create copy of div elements and append it to main div:
$("#add").click(function(){
var clonedDiv = $(".bb-item:last").clone();
clonedDiv = clonedDiv.find("div.bb-custom-side p").text("This is third Page");
$("#bb-bookblock").append(clonedDiv);
});
DEMO FIDDLE
NOTE: I just updated text for last div (This is third Page). You have to put it in loop to increase number.
Try this.
$('#add').on('click',function(){
$('.bb-item').eq(1).append($('.bb-item:last-child').html());
});
OR
$('#add').click(function(){
$('.bb-item').eq(1).append($('.bb-item:last-child').html());
});
Working Demo
You can try this.
$(document).ready(function () {
$("#add").click(function () {
$("#bb-bookblock").append('<div class="bb-item"><div class="bb-custom-side"> new div</div><div class="bb-custom-side">new div 2</div></div>');
});
});
DEMO
This may not appeal to everyone, but, personally, I tend to like "blank slates" for my cloning.
If it were me, I would do this:
var $baseItem = $("<div></div>").addClass("bb-item");
var $baseCustomSide = $("<div></div>").addClass("bb-custom-side");
$("#add").click(function(){
var $newItem = $baseItem.clone();
$newItem.append($baseCustomSide.clone().html("your_first_content_here"));
$newItem.append($baseCustomSide.clone().html("your_second_content_here"));
$("#bb-bookblock").append($newItem);
});
Unless there is a really good reason to reuse an existing element, I find you end up having to be a lot more complex to "scrub" the existing content from the clone . . . using a blank template always seems more clean to me.

Categories