Using jquery to toggle div when parent div is visible - javascript

I have several parent div tags with same class which contain two children divs one of which is hidden. Only one parent is shown at a time. I have a button which moves through the parent one at a time by show the next and hiding the previous. A second button has to toggle the two children divs of a parent when its visible, it however only works for the first parent and not the others.. pls sample html below.. help is much appreciated.. Thanks
<div class="parent" >
<div id="child1"> text </div>
<div id="child2" style="display:none"> text </div>
</div>
<div class="parent" style="display:none" >
<div id="child1"> text </div>
<div id="child2" style="display:none"> text </div>
</div>
<div class="parent" style="display:none" >
<div id="child1"> text </div>
<div id="child2" style="display:none"> text </div>
</div>
scripts to move through parent :
$(function () {
$(".parent:first").fadeIn(); // show first step
$("#next-step").val('Continue');
$("#back-step").hide().click(function () {
var $step = $(".parent:visible");
if ($step.prev().hasClass("parent")) { // is there any previous step?
$step.hide().prev().fadeIn(); // show it and hide current step
}
});
$("#next-step").click(function () {
var $step = $(".parent:visible");
if ($step.next().hasClass("parent")) {
$step.hide().next().fadeIn();
$("#back-step").show(); // recall to show backStep button
}
else { // this is last step, submit form
//$("#next-step").hide();
$("form").submit();
}
});
});
script for button to toggle children for each current visible parent div
$('.txtFlip').on('click', function(event) {
$('.parent:visible > #child1').slideToggle();
$('.parent:visible > #child2').slideToggle();
});
My problem now is the script to toggle child1 and child2 for each current visible parent. It only works for the first parent but not the rest. Help plz...
Thanks......

You can use jQuery's :visible selector to pick which element is currently visible and toggle based on that.
bindLoopThrough = function($button, initial_selector){
// Define a function that will apply for both sets of buttons,
// because they have similar functionality
$button.on("click", function(){
var $current = $(initial_selector),
$next = $current.next();
if($next.length===0){
$next = $current.siblings().eq(0); // Reached end, get first.
}
$current.hide();
$next.show();
});
}
bindLoopThrough($("#button1"), ".parent:visible");
bindLoopThrough($("#button2"), ".parent:visible .child:visible");

Related

Targeting Multiple Elements with One Function

I have a function that assigns dynamic classes to my div's. This function is a that runs on the page. After the page loads, all 10 of my primary 's have classes ".info1" or ".info2" etc...
I am trying to write a Jquery function that changes the class of the div you click on, and only that one. Here is what I have attempted:
$(".info" + (i ++)).click(function(){
$(".redditPost").toggleClass("show")
});
I have also tried:
$(".info" + (1 + 1)).click(function(){
$(".redditPost").toggleClass("show")
});
And
$(".info" + (i + 1)).click(function(){
$(".redditPost").toggleClass("show")
});
EDITED MY HTML: DIV RedditPost is actually a sibling to Info's parent
<div class="listrow news">
<div class="newscontainer read">
<div class=".info1"></div>
<div class="redditThumbnail"></div>
<div class="articleheader read">
</div>
<div class="redditPost mediumtext"></div>
</div>
My issue is two fold.
The variable selection for ".info" 1 - 10 isn't working because i doesn't have a value.
If I did target the correct element it would change all ".redditPost" classes instead of just targeting the nearest div.
Try like this.
$("[class^='info']").click(funtion(){
$(this).parent().find('.redditPost').toggleClass("show");
});
Alternative:
$('.listrow').each(function(){
var trigger = $(this).find("[class^='info']");
var target = $(this).find('.redditPost');
trigger.click(function(){
target.toggleClass("show");
});
});
Try this
$("div[class*='info']").click(function(){
$(this).parent().find(".redditPost").toggleClass("show")
});
Explanation:
$("div[class*='info'])
Handles click for every div with a class containing the string 'info'
$(this).parent().find(".redditPost")
Gets the redditPost class of the current clicked div
Since the class attribute can have several classes separated by spaces, you want to use the .filter() method with a RegEx to narrow down the element selection as follows:
$('div[class*="info"]').filter(function() {
return /\binfo\d+\b/g.test( $(this).attr('class') );
}).on('click', function() {
$(this).siblings('.redditPost').toggleClass('show');
});
.show {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="listrow news">
<div class="newscontainer read">
<div class="info1">1</div>
<div class="redditThumbnailinfo">2</div>
<div class="articleheader read">3</div>
<div class="redditPost mediumtext">4</div>
</div>
</div>

Adding List records into container only once in Jquery

I have two containers in top and bottom,
Top container initially it will have no records i'm adding list of text from bottom container to top container on button click as of now its working fine,
but one small change in my scenario currently now multiple records are adding to my top container i want only once no multiple/same list record should appear in top container
say for example if i have one record placed above in top container next time even if i click add button same list record should not be added into top container either button should be disabled after adding list record or no duplicate record should be allowed in top container
somebody help me out in achieving it Thanks!
https://jsfiddle.net/qx69o1bd/
html
<div>
<ol id="sortable">
</ol>
</div>
<br/>
<div>
<ul id="draggable">
<li>
<div class="qitem">
<label class='lbl'>
Lance
</label>
<button class="hello" >Add To Top container</button>
</div>
</li>
<li >
<div class="qitem" >
<label>
Adam
</label>
<button class="hello" >Add To Top container</button>
</div>
</li>
<li >
<div class="qitem" >
<label>
Rickey
</label>
<button class="hello" >Add To Top container</button>
</div>
</li>
</ul>
</div>
JQuery
$(document).ready(function() {
$("#sortable").sortable();
$("button").click(function () {
var label = $(this).prev().text();
$("#sortable").append('<li>'+label+'</li>');
});
});
only add a class to disable and validate it. With css also you can stylling the button. https://jsfiddle.net/mig1098/qx69o1bd/4/
$(document).ready(function() {
$("#sortable").sortable();
$("button").click(function () {
var label = $(this).prev().text();
if(!$(this).hasClass('disabledbutton')){
$("#sortable").append('<li>'+label+'</li>');
}
$(this).addClass('disabledbutton');
});
});
$(document).ready(function() {
$("#sortable").sortable();
$("button").click(function () {
var label = $(this).prev().text();
if ($("#sortable > li:contains("+label+")").length != 0)
return;
$("#sortable").append('<li>'+label+'</li>');
});
});
This checks if there is already an element which contains the name, and if so doesn't let the user add it again!
If you use the one method to attach your listener to the click event, the button will only run your listener once (per button the selector applies to):
$("button").one('click', function () {
var label = $(this).prev().text();
$("#sortable").append('<li>'+label+'</li>');
});
If you wish to actually disable your button, you can do this by setting the disabled attribute on the object:
$("button").one('click', function () {
var label = $(this).prev().text();
$("#sortable").append('<li>'+label+'</li>');
$(this).attr('disabled', true');
});

Show/hide div on checkbox click with unknown amount of divs

I have an auto-generated list of sections that looks like that:
<div class="list">
<section class="visible list-0"></section>
<section class="hidden list-1"></section>
<section class="hidden list-2"></section>
<section class="hidden list-3"></section>
<!-- unknown amount of sections -->
</div>
And a checkbox:
<input type="checkbox" id="accept" value="1" required>
If checkbox is checked I want to hide the first section .list-0 and show next section list-1. Then if checkbox is checked again, hide list-0 and list-1 and show list-2. Please note that the amount of sections in unknown and can be up to about 25.
The following code is what I wrote by now.
$('#accept').on('click',function() {
var count_sections = $('.list > section').length;
$('.list-0').removeClass('visible').addClass('hidden');
$('.list-1').removeClass('hidden').addClass('visible');
// this should uncheck the checkbox
$('#accept').attr('checked', false);
});
I want to automate it so it will work no matter how many sections I have. Any help is very appreciated. Thanks.
try this one:
$('#accept').on('click',function() {
$('.visible').next('.hidden').removeClass('hidden').addClass('visible');
$('.visible:first').removeClass('visible').addClass('hidden');
// this should uncheck the checkbox
$('#accept').prop('checked', false);
});
this is my first approach. you select the visible element, hide it, toggle class visible, select the next element, show it and toggle class visible.
i completely removed the hidden class from this solution, since we switch between two states - visible and hidden - we only need the visible class to know if it is visible or hidden...
$('#accept').on('click',function() {
if (!$("section:last").hasClass("visible"))
{
$('.visible').hide().toggleClass("visible").next()
.show().toggleClass("visible");
// this should uncheck the checkbox
$('#accept').attr('checked', false);
}
});
UPDATED FIDDLE: http://jsfiddle.net/tbu116w8/2/
added the if statement to check, if you are currently on the last section
Try this -
var $previousSection=$(".list-0").show();
$('#accept').on('change',function() {
if($(this).is(":checked")){
$previousSection.hide();
$previousSection = $previousSection.next("section").show();
}
});
DEMO
You need to store the current visible in a variable. Then show the next one and hide the current one. This is more efficient than finding the visible one again.
You can also store the section you are showing next so you know when you have reached the end:
$('#accept').on('click',function() {
var vis = $('.visible');
var hid = vis.next('.hidden').removeClass('hidden').addClass('visible');
$('#accept').prop('checked', false);
// if we showed something (not at the end yet), hide the current visible one
if(hid.length > 0) {
vis.removeClass('visible').addClass('hidden');
}
});
.visible {
display:block;
}
.hidden {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class="list">
<section class="visible list-0">0</section>
<section class="hidden list-1">1</section>
<section class="hidden list-2">2</section>
<section class="hidden list-3">3</section>
<!-- unknown amount of sections -->
</div>
<input type="checkbox" id="accept" value="1" required/>
use count on checkbox value
here is the working fiddle with the condition of upto 25
$('#accept').on('click',function() {
var count_sections = $('.list > section').length;
var count = $(this).val();
if(count > 25)
{
return false;
}
$('.list-'+count).removeClass('visible').addClass('hidden');
count++;
$('.list-'+count).removeClass('hidden').addClass('visible');
$(this).val(count);
// this should uncheck the checkbox
$('#accept').attr('checked', false);
});
here is the html
<div class="list">
<section class="visible list-0">1st</section>
<section class="hidden list-1">2nd</section>
<section class="hidden list-2">3rd</section>
<section class="hidden list-3">4th</section>
<!-- unknown amount of sections -->
</div>
working example
jsfiddle.net/dr8Ln350/

this parent jQuery

jQuery
$(".drop-down h3").click(function(e) {
e.preventDefault();
$(this).parent(".drop-down").find($("ul")).stop().slideToggle();
$(this).parent(".drop-down").find($(".divider-aside")).stop().toggle("slow");
$(this).parent(".drop-down").find($(".arrow")).stop().toggleClass("rotate1 rotate2");
});
HTML
<div id="categories">
<div class="drop-down">
<h3>Categories</h3>
</div>
<div class="divider-aside"></div>
<ul>
<li>123</li>
<li>12323</li>
<li>1231</li>
<li>523</li>
<li>31</li>
</ul>
</div>
I'd like to hide everything in .drop-down class excluding <h3> by clicking on <h3>. In this case only .arrow toggleClass works.
Use closest instead of parent
$(this).closest("#categories")
parent will only go back 1 level , i.e, the immediate parent. But you gotta get the container that encloses all the 3 elements
So $(this).parent(".drop-down")
supposed to be either
$(this).parent().parent() // this will break if there is an extra
// parent container gets added
or
$(this).closest("#categories") // This will work even if the no of
// parent container keep chaning
if you need toggle them all but the .drop-down .siblings is just what you need
$("div.drop-down > h3").click(function(){
var $t = $(this);
$t.parent().siblings().toggle();
});

How do I use a function argument for this jquery code, or is there a better solution?

I have about 50 p tags and next to these are again 50 divs. on click of each p tag, its div should be shown and the rest hidden. How do i acheive this. I can use something like below:
$(function() {
$('.p1').click(function(){
$('.div1').show();
$('.div2','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
$('.p2').click(function(){
$('.div2').show();
$('.div1','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
//////////////
//////
})
but as you see that this is not an effiecient solution. I am also not sure how the jquery each can be leveraged here or how can this implementation be done using arrays. Can somebody point me in the right direction. I think we should use a function and pass that no. as a parameter, but I dont know how to use custom functions in jquery.
UPDATE:
This is what I have done
$(function() {
$('.p1').click(function() {
$('.div').hide();
$('.d1').show();
})
})
I have added the class div to all of my 50 divs and I am showing d1 on click of p1. Now how do I replace 1 for each instance till 50.
I would have a common class to all div and p so that the binding the handler and the hide can be simple. And for the div, I would associate a data-tag to each p to link each p tag to div
<p class="p1 pclass" data-showdiv="div1">
...
</p>
<p class="p2 pclass" data-showdiv="div2">
..
<div class="mydiv div1" ..>
..
</div>
<div class="mydiv div2" ..>
..
</div>
And the script would be,
$(function() {
$('.pclass').click(function(){
$('.mydiv').hide();
$('.' + $(this).data('showdiv')).show();
});
});
As Jason told,
Use this
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
If the div is next to each paragraph.
But, if there's an element between p and div, it wont work.
For you problem, you can do,
$('p').click(function() {
$('div').hide();
var divClass = $(this).attr("class").replace('p','div');
$('.' + divClass).show();
});
provided you have only p1, p2 .... in paragrah classes ;)
Update
See this fiddle
Notice , we have <br> tags between <p> and <div> as you wanted.
Assuming your HTML structure is
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
....
Use the following in your $(function(){}); method:
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
var dvs = ['.div1','.div2','.div3','.div4','.div5','.div6',.........,'.div50'];
$('p').click(function() {
var index = parseInt(this.className.replace('p','')) - 1;
$(dvs[index]).show();
$(dvs.join(', ')).not(dvs[index]).hide();
});
The jQuery click event will automatically be registered on all elements that match the selector, so you shouldn't have to use the each() method. I would suggest having two CSS classes to distinguish between elements that have this toggling behaviour and elements that are primary (i.e. should be shown when their parent is clicked).
The markup:
<body>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p>This is a normal paragraph</p>
</body>
The code:
$(function () {
$('.togglable').click(function () {
// hide all our children
$(this).children().hide();
// now only show our primary chlid
// NOTE: we pass 'this' as the second argument
// so that the selector will only apply to the
// children of the element that was clicked
// (i.e. we are providing a custom context for the selector).
$('.primary', this).show();
// You could even use the position of the child as well:
// $(this).children().first().show();
// This will show the first child element.
});
});
In this example all elements with the class togglable will show their primary child element when clicked and hide all other child elements.

Categories