How to get to specific element in jquery - javascript

I have HTML structureL
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">read more</button>
</div>
<div class="services-article-after-roll"></div>
</div>
I want after clicking a button something happen with my <div class="services-article-after-roll"></div>
So far, I have:
jQuery('.services-article-read-more-btn').click(() =>{
// ????????
})
I think the appropriate method is find() but I'm not sure

Just select your element. In this case, you can select you element by class. In my simple example, the button shows or hides a div.
$('.services-article-read-more-btn').click(function() {
$(".services-article-after-roll").toggle();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">My button</button>
</div>
<div class="services-article-after-roll">MY DIV</div>
</div>
EDIT: if you have a structure with more than one div with class services-article-elements-single, you can select a wrapper div using .closest() and then find the element inside that container using .find() function.
$('.services-article-read-more-btn').click(function() {
var elementWrapper = $(this).closest(".services-article-elements-single");
elementWrapper.find(".services-article-after-roll").toggle();
})
.services-article-elements-single {
padding: 10px;
margin: 10px;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">My button</button>
</div>
<div class="services-article-after-roll">MY DIV</div>
</div>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">My button</button>
</div>
<div class="services-article-after-roll">MY DIV</div>
</div>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">My button</button>
</div>
<div class="services-article-after-roll">MY DIV</div>
</div>

jQuery itself is a function which allows selecting elements. You can just use jQuery('.services-article-after-roll') and you will get the element.
jQuery('.services-article-read-more-btn').click(() => {
const $servicesArticleAfterRoll = jQuery('.services-article-after-roll');
// ... do stuff
})

Assuming you have more than one 'roll', you'll need to use a context specific selector - that just means use this within the event handler:
$(".services-article-read-more-btn").click(function() {
$(this).closest(".services-article-elements-single")
.find(".services-article-after-roll")
.fadeIn();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">read more</button>
</div>
<div class="services-article-after-roll" style='display:none;'>more info</div>
</div>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">read more</button>
</div>
<div class="services-article-after-roll" style='display:none;'>more info</div>
</div>
Where .closest finds the closest parent with that class (the containing div) and then .find goes back down within that div to find the related details.

To achieve what you require you can use DOM traversal. In the click handler you can use closest() to get the nearest common parent element to the one which raised the event and the one you want to target. Then you can use find() to get that element before amending it as required. In the example below I just toggle a class to hide/show them:
$('.services-article-read-more-btn').click(function() {
$(this).closest('.services-article-elements-single').find('.services-article-after-roll').toggleClass('show');
})
.services-article-after-roll {
display: none;
}
.services-article-after-roll.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">read more</button>
</div>
<div class="services-article-after-roll">After roll...</div>
</div>
<div class="services-article-elements-single">
<div class="services-article-description">
<button class="services-article-read-more-btn">read more</button>
</div>
<div class="services-article-after-roll">After roll...</div>
</div>

Related

How to open a div with button click and closing all other divs at the same time in jQuery

How can I show a specific div element with a button click and close all other elements at the same time in jQuery?
For example, I tired:
$('.button').each(function(i) {
$(this).click(function() {
$('.details').eq(i).slideToggle("slow")
$('.button').eq(i);
});
});
.details {
background: grey;
display: none;
}
.is-open {
display: block;
}
<!-- language: lang-html -->
<button id="button0" class="button">button 1</button>
<button id="button1" class="button">button 2</button>
<button id="button2" class="button">button 3</button>
<div class="details" id="details0">
<h1>Details Person 1</h1>
</div>
<div class="details" id="details1">
<h1>Details Person 2</h1>
</div>
<div class="details" id="details2">
<h1>Details Person 3</h1>
</div>
But this only toggles one elements without closing the others. But I want to close every opened element by clicking the one which isn't opened already.
I tried it with the suggested siblings() method but this did not apply for my case because I have my button elements separated from the button elements.
What is the best solution to achieve such an effect described above?
If you adjust your HTML to have data attributes where each button data-id corresponds to a data-id on a details element it makes it much simpler.
// Use event delegation to listen to events from the buttons
$(document).on('click', 'button', handleClick)
function handleClick() {
// Grab the id from the button
const id = $(this).data('id');
// Remove all the `show` classes from the details elements
$('.details').removeClass('show');
// And then add that class back on to the details element
// that corresponds to the id
$(`.details[data-id=${id}]`).addClass('show');
}
.details { background: grey; display: none; }
.show { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-id="1">button 1</button>
<button data-id="2">button 2</button>
<button data-id="3">button 3</button>
<div class="details" data-id="1">
<h1>Details Person 1</h1>
</div>
<div class="details" data-id="2">
<h1>Details Person 2</h1>
</div>
<div class="details" data-id="3">
<h1>Details Person 3</h1>
</div>
Additional documentation
Event delegation
Template/string literals
Do you want to implement the tab?
https://jqueryui.com/tabs/
$('.button').each(function (i) {
$(this).click(function () {
$('.details').eq(i).show("slow").siblings('.details').hide();
});
});
Here is my solution:
$('.button').each( function(index,button){
//console.log(button.outerHTML);
$(button).click(function(){
let id=this.id.replace("button","");
$(".details").hide()
$("#details"+id).show();
})
});
.details {
background: grey;
display: none;
}
.is-open {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button0" class="button">button 1</button>
<button id="button1" class="button">button 2</button>
<button id="button2" class="button">button 3</button>
<div class="details" id="details0">
<h1>Details Person 1</h1>
</div>
<div class="details" id="details1">
<h1>Details Person 2</h1>
</div>
<div class="details" id="details2">
<h1>Details Person 3</h1>
</div>

How can I wrap inner divs that are dynamic?

I have been trying badly to wrap some divs with an outer div so that I can style them. But I'm unable to do so thus far.
I have this list div which contains some inner divs that I need to wrap. That is the inner divs which have same letters need to be bundled together. Although targeting the divs with the letters is not a good idea as they are gonna be dynamic.
This is an example of what I have been trying to achieve:
<div class="list-wrapper">
<div class="el">A</div>
<div>
<a>A</a>
</div>
</div>
<div class="list-wrapper">
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
</div>
Another example:
This is what I have tried so far:
$(list).find('div.el').each(function(idx, item) {
$(item).nextAll('div').wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div>
<a>A</a>
</div>
<div class="el">B</div>
<div>
<a>B</a>
</div>
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
<div class="el">D</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div class="el">E</div>
<div>
<a>E</a>
</div>
</div>
To achieve your goal you can use a combination of nextUntil() within the loop, to get the div elements between each .el, and wrapAll(). You can include addBack() in there to add the current .el in the loop in to the collection to be wrapped. Try this:
$('#list').find('.el').each((i, el) => {
$(el).nextUntil('.el').addBack().wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
.list-wrapper { border: 1px solid #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div><a>A</a></div>
<div class="el">B</div>
<div><a>B</a></div>
<div class="el">C</div>
<div><a>C</a></div>
<div><a>C</a></div>
<div class="el">D</div>
<div><a>D</a></div>
<div><a>D</a></div>
<div><a>D</a></div>
<div class="el">E</div>
<div><a>E</a></div>
</div>
Note that $(list) was only working by proxy, as elements with an id attribute are available as properties on the document. It's much better practice to use a valid string selector.

Distribute multiple elements with same class to other elements with same class

Hello need some help to distribute multiple elements with same class to other multiple elements with same class. I think maybe .appendTo can help with this.
I want to move these:
...
<div class="button">
...
</div>
<div class="button">
...
</div>
<div class="button">
...
</div>
into these:
...
<div class="button_place">
...
</div>
<div class="button_place">
...
</div>
<div class="button_place">
...
</div>
so that I have these:
first button on first button_place and so on...
<div class="button_place">
<div class="button">
...
</div>
</div>
<div class="button_place">
<div class="button">
...
</div>
</div>
<div class="button_place">
<div class="button">
...
</div>
</div>
Select both sets, loop over one set, and append to the other set.
var buttons = $(".button"),
places = $(".button_place");
buttons.each(function(i, elem) {
places.eq(i).append(elem)
})
.button_place {
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">
b1
</div>
<div class="button">
b2
</div>
<div class="button">
b3
</div>
<div class="button_place">
</div>
<div class="button_place">
</div>
<div class="button_place">
</div>
Select all buttons and places. Then iterate over buttons and append them to corresponding places container.
jQuery version:
const $places = $('.button_place')
$('.button').each(function(i) {
$places[i].appendChild(this)
})
Pure JS version:
const buttons = document.querySelectorAll('.button')
const places = document.querySelectorAll('.button_place')
buttons.forEach(function(button, index) {
places[index].appendChild(button)
})
// NodeList.prototype.forEach is not supported in IE,
// convert NodeList to array first with slice, Array.from, etc.
You can do it using each function as:
https://jsfiddle.net/o2gxgz9r/6623/
$(".button_place").each(function(index,elem){
//$(elem).html($(".button").eq(0));
$(elem).append($(".button").eq(0));
})
use html function if you want to replace content and use append if you want to add content at the end.
Simply use with each() of $('.button_place') .and append($('.button').eq(a).clone()).html() its used to get the outerhtml of button
$('.button_place').each(function(a, b) {
$(this).append($('.button').eq(a).clone()).html()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button"> button</div>
<div class="button"> button</div>
<div class="button"> button</div>
<div class="button_place">button_place</div>
<div class="button_place">button_place</div>
<div class="button_place">button_place</div>

jQuery - Deleting 'corresponding' items

I have a list with two different kinds of items, product-x and product-y.
When the user deletes product-x I need it's equivalent product-y to also delete and vise-versa.
I've tried this a couple of different ways but nothing seems to be working. I appreciate any help!
JS
$(document).on('click', '.delete-item', function(e) {
$(this).parents('.product-x').delay(500).remove();
$(this).parents('.product-y').delay(500).remove();
});
CSS
.product-x, .product-y{
width:100px;
height:50px;
margin:10px;
}
.product-x{
border:red 1px solid;
}
.product-y{
border:navy 1px solid;
}
HTML
<div id="product-x-wrapper">
<div class="product-x">1
<button class="delete-item">x</button>
</div>
<div class="product-x">2
<button class="delete-item">x</button>
</div>
<div class="product-x">3
<button class="delete-item">x</button>
</div>
</div>
<div id="product-y-wrapper">
<div class="product-y">1
<button class="delete-item">x</button>
</div>
<div class="product-y">2
<button class="delete-item">x</button>
</div>
<div class="product-y">3
<button class="delete-item">x</button>
</div>
</div>
First, I would add a data-product-id to each element so you can find them without relying on the human-readable label:
<div id="product-wrapper">
<div class="product-x" data-product-id="1">1 <button...></div>
<div class="product-x" data-product-id="2">2 <button...></div>
<div class="product-x" data-product-id="3">3 <button...></div>
<div class="product-y" data-product-id="1">1 <button...></div>
<div class="product-y" data-product-id="2">2 <button...></div>
<div class="product-y" data-product-id="3">3 <button...></div>
</div>
Then you can remove the matching sibling like this:
$(document).on('click', '.delete-item', function(e) {
var id = $(this).parent().data('product-id');
$("#product-wrapper").find('div[data-product-id="' + id + '"]').delay(500).remove();
});
EDIT: Since you've changed the question to separate the products into two wrappers, you can use this approach, but just remove things from both places, like so:
$(document).on('click', '.delete-item', function(e) {
var id = $(this).parent().data('product-id');
$("#product-x-wrapper").find('div[data-product-id="' + id + '"]').delay(500).remove();
$("#product-y-wrapper").find('div[data-product-id="' + id + '"]').delay(500).remove();
});
Without any additional markup or classes, you can use jQuery's .index() function to delete the corresponding item:
$('.delete-item').each(function() {
$(this).parent().data('idx', $(this).parent().index())
}).click(function() {
var idx = $(this).parent().data('idx');
$('div > div').each(function() {
if ($(this).data('idx') === idx) $(this).remove()
})
})
.product-x,
.product-y {
width: 100px;
height: 50px;
margin: 10px;
}
.product-x {
border: red 1px solid;
}
.product-y {
border: navy 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="product-x-wrapper">
<div class="product-x">1
<button class="delete-item">x</button>
</div>
<div class="product-x">2
<button class="delete-item">x</button>
</div>
<div class="product-x">3
<button class="delete-item">x</button>
</div>
</div>
<div id="product-y-wrapper">
<div class="product-y">1
<button class="delete-item">x</button>
</div>
<div class="product-y">2
<button class="delete-item">x</button>
</div>
<div class="product-y">3
<button class="delete-item">x</button>
</div>
</div>
The way I would do this is grab the value of the product-y you have clicked on using jquerys .val(). Then you can loop through all your product-x's and once you have found a matching .val then you can delete that.
I can write you some code if you need but hopefully this is enough to help you understand how to solve it.
e/ - Pauls way is more elegant use that :D
you should probably just add an id to it so you can look it up by id, but assuming they are all corresponding and in order you can do this
$(document).on('click', '.delete-item', function(e) {
var producty = $(this).parent();
var index = $(".product-y").index(producty );
$('.product-x:eq('+ index +')').remove();
}
this also allows your html to differ
Quick Note: You should use some sort of DOM Handle which can be accessed using a selector, like class,id,data- attributes, name etc.
now if you still want to go this way, which I strongly discourage, then you can use the :contains selector.
$(document).on('click', '.delete-item', function(e) {
$content = $(this).parent().html();
$(this).parents('.product-x').delay(500).remove();
$(".product-y:contains("+$content+")).delay(500).remove();
});
Slightly different take:
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div data-product="one" class="one product-x">1
<button class="delete-item">x</button>
</div>
<div data-product="two" class="two product-x">2
<button class="delete-item">x</button>
</div>
<div data-product="three" class="three product-x">3
<button class="delete-item">x</button>
</div>
<div data-product="one" class="one product-y">1
<button class="delete-item">x</button>
</div>
<div data-product="two" class="two product-y">2
<button class="delete-item">x</button>
</div>
<div data-product="three" class="three product-y">3
<button class="delete-item">x</button>
</div>
<script type="text/javascript">
$('.delete-item').on('click',function(e){
var theProduct = $(this).parent().data('product');
var theElements = $('div[data-product="' + theProduct + '"]');
theElements.delay(500).fadeOut();
})
</script>
fadeOut() is sexier ;)

Javascript click specific to ID

I have a div setup like so:
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
I have the following code:
$('.show-comments').click(function(e){
e.preventDefault();
$('.comments-wrapper').slideToggle('slow');
});
As you would assume, the code works but on a class basis. I'd like for it to open up only the .comments-wrapper of its associated id (i.e. open slideToggle comments2 if content 2 button is clicked and so on and so on).
How would I do this?
$('.show-comments').click(function(e){
e.preventDefault();
$(this).closest(".content").next('.comments-wrapper').slideToggle('slow');
});
Note that this is dependent on the .content element being immediately followed by the .comments-wrapper.
If you have access to modify the html itself, I would suggest adding a wrapper element and then doing the following to avoid the reliance on the exact order of elements:
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
</div>
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
</div>
$(this).closest(".wrapper").find('.comments-wrapper').slideToggle('slow');
This way, if you add an element between the .content and the .comments-wrapper it does not break the code.
You can do this:
$(this).parent("div").next('.comments-wrapper').slideToggle('slow');
This will find the related div of class .comments-wrapper and slide toggle.
And a fiddle: http://jsfiddle.net/xCJQB/
$('.show-comments').click(function (e) {
e.preventDefault();
var num = this.id.match(/\d+$/)[0];
$("#comment" + num).slideToggle('slow');
});
Demo ---> http://jsfiddle.net/7pkyk/1/
Use this context
$(this).closest('.comments').next('.comments-wrapper').slideToggle('slow');
If it is not the immediate element then you might try this as well
$(this).closest('.comments')
.nextAll('.comments-wrapper').first().slideToggle('slow');
you can add a common class to associate a button with a div.
html:
<div class="content">
<button class="show-comments group1" id="content1"></button>
</div>
<div class="comments-wrapper group1" id="comment1">1</div>
<div class="content">
<button class="show-comments group2" id="content2"></button>
</div>
<div class="comments-wrapper group2" id="comment2">2</div>
javascript:
$('.show-comments').click(function(e){
var associate = $(this).attr('class').match(/group\d+/).pop();
var selector = '.comments-wrapper.' + associate;
e.preventDefault();
$(selector).slideToggle('slow');
});
http://jsfiddle.net/uMNfJ/

Categories

Resources