How to slide down dynamic content using jQuery? - javascript

I have a comment system and I would like to implement the "Show Replies (2)" slide down effect.
This is an example of my setup.
<div class="comment">
<div class="main-comment">
Message.
Show Replies (1)
</div>
<div class="sub-comment">
Funny comment up there, mate.
</div>
</div>
But because both the main comment and its sub comments are dynamically generated using ajax, setting event handlers was a little tricky. This is how I did it:
$(".comment").delegate('.show-replies', 'click', function(event) {
$(this).parent().next(".sub-comment").slideDown();
});
I've tried to make the setup as simple and close to the real thing as possible.
What am I doing wrong and how do I solve it?

<div class="comment">
<div class="main-comment">
Message.
Show Replies (1)
</div>
<div class="sub-comment" style="display: none">
Funny comment up there, mate.
</div>
</div>
<script>
$(document).ready(function() {
$('.show-replies').on('click', function() {
$('.sub-comment').slideToggle();
});
});
</script>

In order to bind to NEW dynamic content you need to tell jquery where it is going to be.. Also make sure to use the latest jQuery, delegate is old.
<div class="comments">
<div class="main-comment">
Message.Show Replies (1)
</div>
<div class="sub-comment" style="display: none">
Funny comment up there, mate.
</div>
</div>
<script>
$(document).ready(function() {
$('.show-replies').on('click','.comments', function() {
$('.sub-comment').slideToggle();
});
});
</script>
Notice the .on(eventType, selector, function) signature.
This will work for dynamic content, anything loaded INTO the div class 'comments' - jQuery will always travesre that container from fresh, instead of caching it.
Also- dont just do it on the entire page,because it will cause slow response, since, every click, it will try and bind to the selector.

Replacing
$(this).parent().next(".sub-comment").slideDown();
with
$(this).parent().parent().next(".sub-comment").slideDown();
Fixed the problem.

Related

jQuery accordion - style="display:none; - stops javascript

I'm using an accordion style html code
<div class="accordion-link">Link</div>
<div class="accordion-panel" style="display:none;">content</div>
with this jQuery script
$(function(){
$('.blog .accordion-link').click(function(){
if(!$(this).hasClass('accordion-on'))
$('.blog .accordion-link').removeClass('accordion-on');
$(this).toggleClass('accordion-on');
$(this).next(".accordion-panel").slideToggle().siblings(".accordion-panel:visible").slideToggle();
})
});
In the first accordion tab I'm using a fotorama slideshow.
The problem I'm facing is, that the 'style="display:none;' breaks/stops the execution of the slideshow. How can use the slideshow after toggling the accordion?
Regards
Peter
Try removing the inline style from there, and add a parent <div> which wraps all that, and then control the slideToggle from there, not on the accordion itself.
<div class="acc">
<div class="accordion-link">Link</div>
<div class="accordion-panel" style="display:none;">content</div>
</div>
Also I'm not sure what your if is for but you can just use toggleClass()
Hail mary guess
Try:
<div class="accordion-panel"style="visibility:hidden;">content</div>
I think the plugin is trying to manipulate that css.
Do you have a demo I could look at? I might be able to give a better answer.
$(function(){
$('.accordion-link').click(function(){
if(!$(this).hasClass('accordion-on'))
$('.accordion-link').removeClass('accordion-on');
$(this).toggleClass('accordion-on');
$(this).next(".accordion-panel").slideToggle().siblings(".accordion-panel:visible").slideToggle();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="accordion-link">Link</div>
<div class="accordion-panel" style="display:none;">content</div>
<div class="accordion-link">Link2</div>
<div class="accordion-panel" style="display:none;">content2</div>
<div class="accordion-link">Link3</div>
<div class="accordion-panel" style="display:none;">content3</div>
I didn't see any wrong with your code
I removed the inline style "display:none" and added this line of code in jQuery script
$('.accordion-panel').css('display','none');
This helps fotorama initialize and start - but with the wrong image size.
Adding this line of code to the click(function)
$(window).trigger('resize');
resolves the problem. Now it works.

Draggable many elements with same class

I need to be able to drag all the .notes on the page, but when i use draggable() from the jQuery UI, it only works for the first .note. I have jQuery UI downloaded and is working. When I click the page it makes a new .note so I think that this is a cloning problem. Here is the code
HTML:
<body>
<div id="wrapper">
<div id="wrp">
<h1>Click to make a new note!!!</h1>
<hr>
<div class="note">
<p class="remove"><b>X</b>
</p>
<div class="time"></div>
<hr>
<textarea class="item"></textarea>
<div class="saved"><span class="msg"></span>
</div>
</div>
</body>
JS:
$(".note").closest('.note').draggable();
(I will not include all my JS)
Fiddle here: http://jsfiddle.net/cjhind/zfxj3cps/46/
Any advise?
Add this extra line in your onclick function because jquery cannot recognise new items. It is like it has already did target the items with .note and you need to retarget them. Take care because this will load again the script and it will act twice. so as many items you insert you can see by firebug that it is calling script more times. If you need more info let me know.
$('#wrp, #wrapper').click(function showNote() {
$('.note').fadeIn();
$(".note").closest('.note').draggable(); // ADD THIS TO GIVE YOUR NOTE THE ABILTY TO BE DRAGABLE
});
Did this help?

Selecting only one div of entire css class in jQuery

my goal is to show an overlay on a div when that div is hovered on. The normal div is called .circleBase.type1 and the overlay is circleBase.overlay. I have multiple of these divs on my page. When I hover over one .cirlceBase.type1, overlays show on every .circleBase.type1. How do I prevent this?
Here is some code:
HTML
<div class="circleBase type1">
<p class="hidetext">Lorem ipsum</p>
<hr size="10">
<strong class="gray hidetext">gdroel</strong>
</div>
<div class="circleBase overlay">
<p class="date">11/12/14</p>
</div>
and jQuery
$(document).ready(function(){
$('.overlay').hide();
$('.date').hide();
$(".circleBase.type1").mouseenter(function(){
$(".overlay").fadeIn("fast");
$('.date').show();
$('.hidetext').hide();
});
$(".overlay").mouseleave(function(){
$(this).fadeOut("fast");
$('.date').hide();
$('.hidetext').show();
});
});
Use $(this) to get current element reference and do like this:
$(".circleBase.type1").mouseenter(function(){
$(this).next(".overlay").fadeIn("fast");
$(this).next(".overlay").find('.date').show();
$(this).find('.hidetext').hide();
});
and:
$(".overlay").mouseleave(function(){
$(this).fadeOut("fast");
$(this).find('.date').hide();
$(this).prev(".circleBase").find('.hidetext').show();
});
usually when I want to target something specific you just give it an ID.
ID's play better in JavaScript than classes.
If you had a specific container, using the container as your starting point is a good route as well
$('#container').find('.something.type1').doSomething();
This is much more efficient for jquery, because it only searches .something.type1 inside of #container.
Well I'm not sure exactly what you're looking to do, but it looks like you want to replace content in some kind of circle with a hover text, but with a fade. To do that you'll have to add some CSS and it would be best to change your HTML structure too.
The HTML should look like this:
<div class="circleContainer">
<div class="circleBase">
<p>Lorem ipsum</p>
<hr>
<strong class="gray">gdroel</strong>
</div>
<div class="overlay" style="display: none;">
<p class="date">11/12/14</p>
</div>
</div>
so your js can look like this:
$(function(){
$(".circleContainer").mouseenter(function(){
$(this).find(".overlay")
$(this).find('.circleBase').hide();
});
$(".circleContainer").mouseleave(function(){
$(this).find('.circleBase').show();
$(this).find(".overlay").hide();
});
});
Here's a working solution that includes some CSS to make it nice. Try taking it out and running it, you'll see the problems right away.

jquery double function each

I have the following block of HTML code more than once
<div id="page_1" class="page">
<div class="imageDetail_bg">
<img src="../_img/detail_car.jpg" alt="" id="car_detail" class="car_detail"/>
</div><!-- imageDetail-->
<div id="listThumbs">
<div id="thumbsContainer_1" class="thumbsContainer">
<div id="areaThumb" class="areaThumb">
<div id="posThumb_1" class="posThumb">
<img src="../_img/detail_car.jpg" class="detail_img" alt="">
</div>
</div><!--areaThumb-->
<div id="areaThumb" class="areaThumb">
<div id="posThumb_2" class="posThumb">
<img src="../_img/detail_car.jpg" class="detail_img" alt="" />
</div>
</div><!--areaThumb-->
...
...
...
</div><!--listThumbs-->
</div><!--page-->
and the following jQuery code:
$('.page').each(function(i) {
$('.areaThumb').each(function(j) {
$('.detail_img').eq(j).click(function(){
$('.car_detail').eq(i).attr('src', $(this).attr('src'));
});
});
});
What I want to do is: For each page there's a block of thumbs, and when I click in any thumb, the image in #car_detail is replaced by the image of the thumb I clicked. At this moment I can do this, BUT the #car_detail image is replaced in all pages. I'm not getting individually actions for each page. Every click make the action occurs in all pages.
Can anyone tell me what I'm doing wrong?
Thanks
You need not iterate through each element of the jquery selector result to bind a click event.
And you are missing a closing div for thumbsContainer div, add that before each .
Also if you have an element with id car_detail then you should use #car_detail instead of .car_detail
Working example # http://jsfiddle.net/2ZQ6b/
Try this:
$(".page .areaThumb .detail_img").click(function(){
$(this).closest("div.page").find('.car_detail').attr("src", this.src);
});
If the .detail_img elements are being used for the car_detail image then you can simplify the above code to:
$(".detail_img").click(function(){
$(this).closest("div.page").find('.car_detail').attr("src", this.src);
});
You need to give context to your children nodes:
$('.page').each(function(i) {
$('.areaThumb', this).each(function(j) {
$('.detail_img', this).eq(j).click(function(){
$('.car_detail', this).eq(i).attr('src', $(this).attr('src'));
});
});
});
Every this is pointing to the current element given by the jquery function that called it.
[edit] Cybernate found a better way to do what you wanted to. My answer mostly explains why your code did not work as you wanted
I think you have the wrong approach about this,
You should just use cloning and you will be fine...
HTML
<div class="holder">Replace Me</div>
<div>
<div class="car"><img src="img1" /></div>
<div class="car"><img src="img2" /></div>
</div>
JS
$('.car').click(function(){//when you click the .car div or <img/>
var get_car = $(this).clone();//copy .car and clone it and it's children
$('.holder').html('').append(get_car);//put the clone to the holder div...
});
I think this is what you should be doing, simple and elegant... do not understand why you complicate as much :)

jQuery: get a reference to a specific element without using id

I'm tinkering a bit with jquery to show a hidden div when a link is clicked. This should be fairly simple, but there's a flaw to it in this case. I have the following markup:
<div class="first-row">
<div class="week">
<p>Uge 2</p>
<p>(08-01-11)</p>
</div>
<div class="destination">
<p>Les Menuires</p>
<p>(Frankrig)</p>
</div>
<div class="days">4</div>
<div class="transport">Bil</div>
<div class="lift-card">3 dage</div>
<div class="accommodation">
<p><a class="show-info" href="#">Hotel Christelles (halvpension)</a></p>
<p>4-pers. værelse m. bad/toilet</p>
</div>
<div class="order">
<p>2149,-</p>
<p class="old-price">2249,-</p>
</div>
<div class="hotel-info">
<!-- The div I want to display on click -->
</div>
</div>
When I click the "show-info" link I want the "hotel-info" div to display.
My backend devs don't want me to use ids (don't ask me why..) and the above markup is used over and over again to display data. Therefore I need to be able to access the "hotel-info" div in the "first-row" div where the link is clicked.
I've tried to do something like:
$(document).ready(function() {
$('.show-info').click(function() {
var parentElement = $(this).parent().parent();
var lastElementOfParent = parentElement.find(".show-hotel");
lastElementOfParent.show();
});
});
But without a result :-/ Is this possible at all?
Any help is greatly appreciated!
Thanks a lot in advance!
Try this:
$('.show-info').click(function() {
$(this).closest('.accommodation').siblings('.hotel-info').show();
});
Even better imo, as it would be independent from where the link is in a row, if every "row div" has the same class (I assume only the first one has class first-row), you can do:
$(this).closest('.row-class').find('.hotel-info').show();
Reference: .closest, .siblings
Explanation why your code does not work:
$(this).parent().parent();
gives you the div with class .accommodation and this one has no descendant with class .hotel-info.
It is not a good idea to use this kind of traversal for more than one level anyway. If the structure is changed a bit, your code will break. Always try to use methods that won't break on structure changes.
You're right in not using an ID element to find the DIV you want :)
Use closest and nextAll
Live demo here : http://jsfiddle.net/jomanlk/xTWzn/
$('.show-info').click(function(){
$(this).closest('.accommodation').nextAll('.hotel-info').toggle();
});

Categories