Slide Toggle Won't Activate On Class - javascript

I looked up many questions on this topic and there are similar answers that should work, but it's not working for me. I admit DOM traversal is not my strong point, so if you have a solution and can give some context it would really help me understand why the other solutions weren't working.
I have a div with a button and on a button click (this button only appears on mobile) it should slide down only the current div content. I can get this to work, but the issue is it opens up ALL the divs content. I cannot however get it to only open the specific card even using solutions such as $(this), $(next), $(prev) or $(find).
The code I am posting below does not open it at all, and I am using this version of the code because it is most similar to answers on Stack Overflow.
$(document).ready(function(){
$('.mobile-icon').on('click', function(){
event.preventDefault();
$(this).next().find('.card-bottom').slideToggle();
console.log('hi there'); //this does print
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- FIRST CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<span class="glyphicon glyphicon-plus"></span>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
<!-- SECOND CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<span class="glyphicon glyphicon-plus"></span>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->

The main issue is how you're using jQuery's .next() and .find(). Since $(this) is the <a> tag, .next(), which selects the next sibling, is the <p> tag. Then calling .find() on the <p> tag would check through all its descendants, for which there are none.
Therefore you need to select the parent of both the 'card-top' and 'card-bottom' divs before you traverse down with .find().
For example:
$(document).ready(function(){
$('.mobile-icon').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.card-bottom').slideToggle();
});
});
The first call to .parent() will be the parent of the <a> tag, which is the 'card-top' div, and the .parent() of that will be the 'card' div. Then calling .find() will work.
http://www.bootply.com/UMwXaOILHv

Missing the closing " on class="card>
Add event to function() so it's function(event)
If you don't need to link anywhere use a div instead of an a tag and you won't need preventDefault.
$('.mobile-icon').on('click', function(event) {
event.preventDefault();
$(this).closest('.card').find('.card-bottom').slideToggle();
// .closest finds the nearest .card ancestor (it goes up)
// .find then finds .card-bottom within the closest .card
});
.mobile-icon {
background-color: black;
width: 100px; height: 40px;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- FIRST CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<div class="mobile-icon">click me</div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
<!-- SECOND CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
click me
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
fiddle
https://jsfiddle.net/Hastig/m2zaLfnz/

Related

how can I change child node css?

I am trying to enable view / hide feature in my faq questions, but however at the moment to trying to access to my child answers_body with children I got an error . children is not a function, how can I properly access to answers_body in order to change display:none to display:block
<section class="faqs">
<div class="accordion row">
<div class="__block col-lg-7 mx-auto py-3">
<div class="row justify-content-between align-items-start">
<div class="col-11">
<h3 class="__question">
demo
</h3>
</div>
<div class="col-1">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="12"><path fill="none" stroke="#5267DF" stroke-width="3" d="M1 1l8 8 8-8" /></svg>
</div>
</div>
<div class="answers_body"> I want to access to this node in order to display it
<div class="col">
<p class="answer">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tincidunt justo eget ultricies fringilla. Phasellus blandit ipsum quis quam ornare mattis.
</p>
</div>
</div>
</div>
</section>
$('.__question').click(function(){
var $parent = $(this);
console.log($patern[0].InnerText)
});
If you are trying to do a toggle effect for your faq, then you can try the following.
$('.__question').click(function() {
var parent = $(this).parents('.accordion.row');
if (parent.find('.answers_body').hasClass('answers-active')) {
parent.find('.answers_body').removeClass('answers-active');
} else {
parent.find('.answers_body').addClass('answers-active');
}
});
Here you need to find the parent that is common to both the element you are clicking and the element you need show. Then using .find() method you can target the element and show. Refer the fiddle
UPDATE
Since you said this is not working, I think the parent class that is used for all faq is wrong. If you can update the code, I can help with that. Else you can use the following code.
$('.__question').click(function() {
var parent = $(this).closest('.row').siblings('.answers_body');
if (parent.hasClass('answers-active')) {
parent.removeClass('answers-active');
} else {
parent.addClass('answers-active');
}
});

I have 3 divs each with it's own topic, and now I would like for each div to open its modal

So far I manage to open one modal by clicking on any of the divs. How can I have one modal for one div element, that is I would like when I click on services to open services modal, and when I click on about to open about modal...and so on..I also have to close every modal when one is opend...I dont know how to connect each div with it's own modal. This is the code I have...
<div class="section">
<div class="container">
<div class="row">
<div class="col-md-4 sector">
<h3>Services</h3>
<i class="fa fa-gear"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
<div class="col-md-4 sector">
<h3>About me</h3>
<i class="fa fa-address-card-o"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
<div class="col-md-4 sector">
<h3>Contact</h3>
<i class="fa fa-phone"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
</div>
</div>
</div>
<div class="modal-container" id="myMod">
<div class="modal-content">
<span class="close">&times</span>
<h1>Heading</h1>
<p>Some text goes in here...</p>
</div>
</div>
<div class="showcase">
<div class="container">
<h1>Got Ideas?</h1>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sed sem rhoncus urna iaculis faucibus. Pellentesque ultrices nibh ac imperdiet tincidunt. Donec hendrerit velit eros</p>
Read More
</div>
</div>
<script type="text/javascript">
// Get the button that opens the modal
var myOver = document.getElementsByClassName('over');
// Get modal to pass it to function
var modal = document.getElementById('myMod');
// get closing button
var span = document.getElementsByClassName('close')[0];
// Function to open the modal
for(var i = 0; i<myOver.length; i++){
myOver[i].addEventListener('click', function(){
modal.style.display = 'block';
});
}
// When the user clicks on <span> (x), close the modal
span.onclick = function(){
modal.style.display='none';
}
</script>
You could use a similar naming scheme and find the right text simply by by appending a suffix to the object that was clicked on's id, for instance have each span element have an id corresponding to the modal they go with. For instance contact then have the click event listener be
function(e) { //e is the event object event
document.getElementById(e.target.id + "-modal").style.display = 'block'
}
now id the contact modal as 'contact-modal' and it should find it easily
As for closing each element, just iterate through all elements with the class modal-contain and set their display to none before opening the
new one

Find parent of unwrapped element and use it in .wrap() using jquery

I have dynamically added div elements with structure as follows.
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
I want to remove a wrappers from h1 elements and add them to parent div elements. The result should be like:
<a href="link/to/full_artical">
<div class="blogPost">
<h1>Some Heading</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
</a>
I wish there is a way in jquery maybe a combination of unwrap() and wrap() functions.
I do not have access to the source of this dynamically added content.
divs are being added dynamically.
Thanks in advance.
EDIT
tried
$('.blogPost').wrap('')
Not Working.
You can use .clone() to copying a element and store it in variable. Use .unwrap() to remove a parent of h1 and use .wrap() to wrapping copied element around .blogPost.
var clone = $("a").clone().children().remove().end();
$("h1").unwrap().parent().wrap(clone);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
Another way:
var href = $('.blogPost').children('a').attr('href');
$('.blogPost').wrap('');
$('h1').unwrap();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
var link = $('a'),
heading = link.find('h1'),
blogPost = $('.blogPost');
blogPost.prepend(heading);
blogPost.wrap(link);
link.remove();
CODEPEN

Opening modal on page load

I am using a animatedModal.js to display full screen modal on my page.
It works properly and is triggered by clicking on a button.
But, instead of that, i would need it to open automatically once the user enters the site, aka, it needs to be opened before the main page content.
This is the markup:
<!-- MODAL STARTS -->
<a id="demo01" href="#animatedModal">DEMO01</a>
<div id="animatedModal">
<div class="close-animatedModal">
CLOSE MODAL
</div>
<div class="modal-content">
</div>
</div>
<!-- PAGE CONTENT -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
And it is triggered by
$("#demo01").animatedModal();
Fiddle can be found at https://jsfiddle.net/5zLe3npu/
What would be the best solution to display it first, before the content?
I am a JS newbie so sorry for potentially stupid question.
Use trigger() API Documentation
Try this
$("document").ready(function() {
$("#demo01").animatedModal();
$("#demo01").trigger('click');
});
Demo Here
You could use the .on method to specify what to do on-click of the close button, such as showing the content. And to hide the content initially you could just use style='display:none;' on a containing the content.
HTML -
<!-- MODAL STARTS -->
<div id="animatedModal">
<div class="close-animatedModal">
CLOSE MODAL
</div>
<div class="modal-content">
</div>
</div>
<!-- PAGE CONTENT -->
<div id='container' style='display:none;'>
<a id="demo01" href="#animatedModal">DEMO01</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
JQuery -
$("#demo01").animatedModal(); //initialize animatedModal
$("#demo01").click(); //triggers opening of Modal.
$(".close-animatedModal").on( "click", function() {
$("#container").show();
});
Please see JSFiddle - http://jsfiddle.net/w1gw64aj/
If this answers your question, please mark this as the accepted answer.

Cycle2 - Can't initialize the slider

Hopefully someone can help me with this. I am not an expert on use of Cycle2 jQuery plugin and I would like to implement it. Supposedly Cycle2 is supposed to be able to slide composites and that is what I am trying to do.
I have html that looks like the sample below. The code is actually generated by djangocms and I don't have the ability to add attributes to the html structure unless I am adding them using JavaScript...
So I suppose I am left with one option and that is to initialize the slider using this:
$('.cycle-slideshow').cycle();
But that doesn't seem to do anything.
I also tried this:
// Cycle Slideshow
$('.cycle-slideshow').attr('data-cycle-fx', 'scrollHorz');
$('.cycle-slideshow').attr('data-cycle-timeout', '2000');
$('.cycle-slideshow').attr('data-cycle-slides', '> div');
My HTML structure...
<div class="cycle-slideshow">
<div class="slider">
<h2>Teaser Title 1</h2>
<img src="/media/cms_page_media/2014/8/20/Banner1.png" alt="Teaser Title 1">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="slider">
<h2>Teaser Title 2</h2>
<img src="/media/cms_page_media/2014/8/20/Banner2.png" alt="Teaser Title 2">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="slider">
<h2>Teaser Title 3</h2>
<img src="/media/cms_page_media/2014/8/20/Banner3.png" alt="Teaser Title 3">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="slider">
<h2>Teaser Title 4</h2>
<img src="/media/cms_page_media/2014/8/20/Banner4.png" alt="Teaser Title 4">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
The reason why that might not work is because Cycle 2 Inits all slideshows right after it loads the plugin, so your jQuery won't affect your slideshows, because Cycle 2 has already been initialized.
What happens if you add the attributes and THEN init the slideshow:
$('.cycle-slideshow')
.data('cycle-fx', 'scrollHorz')
.data('cycle-timeout', '2000')
.data('cycle-slides', '> div')
.cycle();
You can also, try to pass your options as an object to your slideshow:
$('.cycle-slideshow')
.cycle({
'fx' : 'scrollHorz',
'timeout' : 2000,
'slides' : '> div'
});
Finally, you also try re-writing the cycle 2 defaults in order for all your slideshows to work accordingly. This should be avoided unless necessary, but it might work!
$.fn.cycle.defaults = $.extend($.fn.cycle.defaults, {
'fx' : 'scrollHorz',
'timeout' : 2000,
'slides' : '> div'
});
$('.cycle-slideshow').cycle();
UPDATE:
You might want to re-write the defaults before $(document).ready so that cycle uses your default options when initiating the plugin. It automatically calls itself on $(document).ready.
Source Code:
https://github.com/malsup/cycle2/blob/master/src/jquery.cycle2.core.js#L678-L681

Categories

Resources