Please check this JSFiddle, Here there are two div named step-wrapper and inside these step-wrapper div there are three div named step-box. Its written in such a way that while clicking on a step-box div its background color changes to yellow.
I have added a reset button. What I needed is on clicking the reset button, the color of last clicked step-box div should changes to white. But in this code, when I click the reset button all the step-box background color changes to white.
I believe this is what you're looking for:
https://jsfiddle.net/richardgirges/8m9qstg3/11/
We're saving a reference to the lastClicked div, and targeting it specifically when reset is hit. Like so:
var $lastClicked = null;
$('.step_wrapper').on('click','.step_box',function () {
$(this).parent().find('.step_box').css('background-color', '');
$(this).css('background-color', '#fff000');
$lastClicked = $(this);
});
$('.reset').on('click',function(){
if ( $lastClicked ) {
$lastClicked.css( 'background-color', '#fff' );
$lastClicked = null;
}
});
EDIT: Improved the code. Using explicit var instantiation to keep it within scope.
It looks kind of weird when you have only one reset button at the very end but only want to reset only one wrapper. How about if we add a reset button inside the wrapper div and resets only that wrapper when we click each reset? See if you like it.
HTML:
<div class="step_wrapper">
<div class="step_box" onclick="show('Page1');"> <span>Content of page 1</span>
</p>
</div>
<div class="step_box" onclick="show('Page2');"> <span>Content of page 2</span>
</p>
</div>
<div class="step_box" onclick="show('Page3');"> <span>Content of page 3</span>
</p>
</div>
<div class="reset"> Reset </div>
</div>
<br>
<br>Second Wrapper
<br>
<br>
<div class="step_wrapper">
<div class="step_box" onclick="show('Page1');"> <span>Content of page 1</span>
</p>
</div>
<div class="step_box" onclick="show('Page2');"> <span>Content of page 2</span>
</p>
</div>
<div class="step_box" onclick="show('Page3');"> <span>Content of page 3</span>
</p>
</div>
<div class="reset"> Reset </div>
</div>
Javascript:
$('.step_wrapper').on('click','.step_box',function () {
$(this).parent().find('.step_box').css('background-color', '');
$(this).css('background-color', '#eeffaa');
});
$('.reset').on('click',function(){
$( this ).parent().find(".step_box").css( 'background-color', '' );
});
Add class last to last clicked element and reset this one.
$('.step_wrapper').on('click','.step_box',function () {
$(this).parent().find('.step_box').css('background-color', '');
$(this).css('background-color', '#fff000');
$('.last').removeClass('last');
$(this).addClass('last');
});
$('.reset').on('click',function(){
$( ".step_box.last" ).css( 'background-color', '' );
});
http://jsfiddle.net/8m9qstg3/7/
See this fiddle
What I have done is that, I've added an ID attribute to your step_box class and used the id to set a hidden field when the step_box is clicked. And later in the onClick of reset, i ve used the id that is set in the hidden field.
Please the code below..
JS
$('.step_wrapper').on('click','.step_box',function () {
$(this).parent().find('.step_box').css('background-color', '');
$(this).css('background-color', '#fff000');
document.getElementById('test').value=this.id;
});
$('.reset').on('click',function(){
var a= document.getElementById('test').value;
$( "#"+a ).css( 'background-color', '' );
});
HTML
<div class="step_wrapper">
<div class="step_box" onclick="show('Page1');" id="1"> <span>Content of page 1</span>
</p>
</div>
<div class="step_box" onclick="show('Page2');" id="2"> <span>Content of page 2</span>
</p>
</div>
<div class="step_box" onclick="show('Page3');" id="3"> <span>Content of page 3</span>
</p>
</div>
</div>
<br>
<br>Second Wrapper
<br>
<br>
<div class="step_wrapper">
<div class="step_box" onclick="show('Page1');" id="4"> <span>Content of page 1</span>
</p>
</div>
<div class="step_box" onclick="show('Page2');" id="5"> <span>Content of page 2</span>
</p>
</div>
<div class="step_box" onclick="show('Page3');" id="6"> <span>Content of page 3</span>
</p>
</div>
</div>
<input type="hidden" id="test" />
<div class="reset">Reset</div>
http://jsfiddle.net/8m9qstg3/6/
I created a variable named last and assigned the clicked object to it. This way, when you hit reset, it will know what the last element is that was clicked. If you're looking for multiples you could create an array and use .push() to create a string of last elements clicked, but this should answer your question.
var last;
$('.step_wrapper').on('click','.step_box',function () {
$(this).parent().find('.step_box').css('background-color', '');
$(this).css('background-color', '#fff000');
last = this;
});
$('.reset').on('click',function(){
$(last).css("background-color", "white");
});`
Related
I have a javascript hide/show div with 4 different divs going. It is working partially but not performing the way I would like. When I click one of the divs it opens up the hidden div, which is perfect, but when I click the other link to open up the other div I want the other one I clicked first to close and then the new one to open. Here is my javascript.
$('[id^="hideshow"]').on('click', function(event) {
var dataValue = $(this).attr('data-value');
dataValue = $('#'+dataValue);
$(dataValue).toggle('hide');
});
<a class="pure-button pure-button-primary" type='button' id='hideshow1' value='hide/show' data-value="content1"><div class="witb">
<hr class="dark2">
<p></p>Whats in the Bag <i class="fa fa-angle-down" style="font-size:24px"></i></p>
</div>
</div></a>
<div id='content2' style="display:none">
<div class="wedge-thumbs">
<img class="thumbs" src="build/wedge-thumb.png?$staticlink$" alt="Milled Grind Header">
<span style="customize"> Customize It</span>
<hr class="dark">
<span class="title">Milled Grind 54° LB</span>
</div>
<div class="wedge-thumbs">
<img class="thumbs" src="build/wedge-thumb.png?$staticlink$" alt="Milled Grind Header">
<span style="customize"> Customize It</span>
<hr class="dark">
<span class="title">Milled Grind 54° LB</span>
</div>
<div class="wedge-thumbs">
<img class="thumbs" src="build/wedge-thumb.png?$staticlink$" alt="Milled Grind Header">
<span style="customize"> Customize It</span>
<hr class="dark">
<span class="title">Milled Grind 54° LB</span>
</div>
</div>
// Hopefully you have some selector reference to target them all
var $all = $(".drops"); // Clearly I used .drops for example
$('[data-value]').on('click', function(event) {
var $target = $('#'+ this.dataset.value);
$all.not( $target ).hide(); // Hide all but target one
$target.toggle(); // Toggle target one
});
Here's an improved example:
var $all = $(".togglable");
$('[data-toggle]').on('click', function(event) {
var $target = $(this.dataset.toggle);
$all.not( $target ).hide(); // Hide all but target one
$target.toggle(); // Toggle target one
});
[data-toggle]{cursor:pointer; display:inline-block; color:#0bf; padding:0 8px;}
.hidden{display: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a data-toggle="#el1">TOGGLE1</a>
<a data-toggle="#el2">TOGGLE2</a>
<a data-toggle="#el3">TOGGLE3</a>
<div id="el1" class="togglable hidden">ELEMENT1</div>
<div id="el2" class="togglable hidden">ELEMENT2</div>
<div id="el3" class="togglable hidden">ELEMENT3</div>
Please try this
$('[id^="hideshow"]').on('click', function(event) {
var dataValue = $(this).attr('data-value');
dataValue = $('#'+dataValue);
$(dataValue).toggleClass('hide');
});
It will be better if you could give your divs a common class instead of ids so you could hide other divs using this common class like :
$('.common_class').addClass('hide');
If you cant you could loop through all the divs and hide them before showing the current clicked one :
$('[id^="hideshow"]').on('click', function(event) {
$('[id^="hideshow"]').each(function(){
$('#'+$(this).data('value')).addClass('hide');
});
dataValue_id = $('#'+$(this).data('value'));
$(dataValue_id).toggleClass('hide');
});
Hope this helps.
Snippet using common classes :
$('.common_class').on('click', function(event) {
$('.common_class_2').not($('.common_class_2', this)).addClass('hide');
$('.common_class_2', this).toggleClass('hide');
});
.hide{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='common_class'>DIV 1
<p class='common_class_2'>Content 1</p>
</div>
<div class='common_class'>DIV 2
<p class='common_class_2 hide'>Content 2</p>
</div>
<div class='common_class'>DIV 3
<p class='common_class_2 hide'>Content 3</p>
</div>
<div class='common_class'>DIV 4
<p class='common_class_2 hide'>Content 4</p>
</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>
Basically I have multiple elements A,B,C,... And they are all "connected" to A1,B1,C1,...
For simplicity and better understanding , lets say A,B,C are personal data about A1,B1,C1 persons (A1,B1,C1 are pictures of those persons).
html looks like :
<div class="personal_data">
<p class="A"> Ronnie </p>
<p class="B"> James </p>
<p class="C"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1"> img2 </div>
</div>
</div>
<div>
<div>
<div class="C1"> img3 </div>
</div>
</div>
</div>
Yes , those divs that contain img are nested like that and the order must not be changed.
p elements are hiddenand are shown in personal_data window according to which person has been clicked.
How can I make it that when one picture is clicked its corresponding p element is shown and the rest of them are hidden , and when I click to another picture it shows another p element and hides previous , and so on?
I tried with jQuery two methods :
$(".A1").click(function () {
$(".A").show();
$(".B").hide();
$(".C").hide(); })
But I immediately abandoned it for obvious reasons. It's ugly and I have more than 3 persons so doing it for every person like this would not be a good practice.
$(".persons div").click(function () {
var index=$(".persons div").index(this);
$(".personal_data p").hide().eq(index).show(); })
Because I don't know all jQuery functions ( and all native javascript functions) I was amazed by the power of these but because of those nested images the index of A that corresponds to the A1 would be ok , but other indexes would not have their pair with persons because the number od divs are not equal , rather then "shifted" by +3. So I tweaked .personal_data with 2 empty p elements after A,B and C so the indexes would align. And it worked but I feel like I am violating something .
Is there a more elegant way for achieving this? I feel my problem is lack of knowledge of all functions that exist inside javascript (and jQuery).
Get the list of matching clickable elements, and the personal data, ahead of time (so we don't have to keep re-querying them):
var clickables = $('.persons > div > div > div[class]');
var data = $('.personal_data p');
Then, when clicked, get the index of the clicked thing in that list, rather than hunt through the DOM:
clickables.click(
function() {
data.hide(); // hide the others
var idx = clickables.index(this);
$(data[idx]).show();
}
);
var clickables = $('.persons > div > div > div[class]');
var data = $('.personal_data p');
clickables.click(
function() {
data.hide();
var idx = clickables.index(this);
$(data[idx]).show();
}
)
.personal_data p {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A">Ronnie</p>
<p class="B">James</p>
<p class="C">Dio</p>
</div>
<div class="persons">
<div>
<div>
<div class="A1">img1</div>
</div>
</div>
<div>
<div>
<div class="B1">img2</div>
</div>
</div>
<div>
<div>
<div class="C1">img3</div>
</div>
</div>
</div>
Assuming that you will have this class structure in your page consistently, I did something by comparing the class names. If the class name of the clicked div contains the class name of the p element, then the p will be shown, otherwise they will be hidden :
$(".persons div").click(function () {
var myclassname = $(this).attr('class');
$(".personal_data p").hide().filter(function() {
return myclassname.indexOf($(this).attr('class')) >= 0); //if it contains
}).show();
});
Well, I don't like working with index's in lists. I prefer that you retrieve it when you mount it on the server-side with attributes and id's.
So try the following:
$(document).ready(function () {
$('.personal_data p').on('click', function (event) {
var theTarget = $(this).attr('data-detail');
$('.person-details').removeClass('show'); //remove this line in case you don't want only one at a time
$('#' + theTarget).addClass('show');
});
})
.person-details {
opacity: 0;
}
.person-details.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A" data-detail="ronnie"> Ronnie </p>
<p class="B" data-detail="james"> James </p>
<p class="C" data-detail="dio"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1 person-details" id="ronnie"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1 person-details" id="james"> img2 </div>
</div>
</div>
<div>
<div>
<div class="C1 person-details" id="dio"> img3 </div>
</div>
</div>
</div>
All the styling or class you can customize. If you prefer showing or hiding , just change the removeClass to hide, and the addClass to show
If you want the oposite interaction :
$(document).ready(function () {
$('.person-details').on('click', function (event) {
var theTarget = $(this).attr('data-detail');
$('.personal_data p').removeClass('show'); //remove this line in case you don't want only one at a time
$('#' + theTarget).addClass('show');
});
})
.personal_data p {
opacity: 0;
}
.personal_data p.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A" id="ronnie"> Ronnie </p>
<p class="B" id="james"> James </p>
<p class="C" id="dio"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1 person-details" data-detail="ronnie"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1 person-details" data-detail="james" > img2 </div>
</div>
</div>
<div>
<div>
<div class="C1 person-details" data-detail="dio"> img3 </div>
</div>
</div>
</div>
I have three (or more in the future) dropdown menus that are show when clicked on a 'trigger'
The code is functional but I want the slideUp animation to finish before another slideDown animation begins.
Note that the 'dropdown' elements are positioned absolutely, top:100% in relation to the 'container' so they appear under the 'triggers'
The code on Codepen
HTML
<div class="container">
<div class="drop-container">
<span class="trigger">Drop 1</span>
<div class="dropdown">
<p>First Dropdown</p>
</div>
</div>
<div class="drop-container">
<span class="trigger">Drop 2</span>
<div class="dropdown">
<p>Second dropdown</p>
</div>
</div>
<div class="drop-container">
<span class="trigger">Drop 3</span>
<div class="dropdown">
<p>Third dropdown</p>
</div>
</div>
</div>
jQuery
var $container = $('.drop-container'),
$trigger = $('.trigger');
$trigger.on('click',function(){
var $this = $(this).siblings('.dropdown');
$container.find('.dropdown').slideUp();
if($this.is(':visible')) {
$this.hide('fast');
}
else {
$this.slideDown();
}
});
You could just add a delay
$this.delay(500).slideDown();
but as pointed out it in the comments would be better to use the callback.
Codepen Example
There is a way to do this without using timers. You can basically add a class to the element that has slide down and use the "oncomplete" property of jQuery slide. Replace your javascript with the below and it should work live example here
$container = $('.drop-container')
$trigger = $('.trigger')
$trigger.on('click',function(){
var $drop = $(this).siblings('.dropdown')
$down = $container.find('.down')
if($down.length > 0){
$down.slideUp(function() {
$(this).removeClass('down')
$drop.addClass('down')
$drop.slideDown()
})
}
else{
$drop.addClass('down')
$drop.slideDown()
}
})
I've got six divs that act as buttons. When clicked, one of the spans in a different div (and class) is displayed, and others are hidden.
Buttons:
<div class="menu">
<div class="menubutton">
Menu1
</div>
.
.
.
<div class="menubutton">
Menu6
</div>
</div>
Info shown based on clicked button:
<div class="information">
<span class="information1"> Info1 </span>
...
<span class="information6"> Info6 </span>
</div>
How do I know which one called the function, so I can know which span to make visible?
Provided your markup is this way:
<div class="menu">
<div class="menubutton">
Menu1
</div>
<div class="menubutton">
Menu2
</div>
<div class="menubutton">
Menu3
</div>
<div class="menubutton">
Menu4
</div>
<div class="menubutton">
Menu5
</div>
<div class="menubutton">
Menu6
</div>
</div>
<div class="information">
<span class="information1"> information1 </span>
<span class="information2"> information2 </span>
<span class="information3"> information3 </span>
<span class="information4"> information4 </span>
<span class="information5"> information5 </span>
<span class="information6"> information6 </span>
</div>
You can do this:
$('.menubutton').click(function(){
var index = $('.menubutton').index(this); //get the index of the menubutton clicked
$('.information > span').eq(index).show().siblings().hide(); // show the corresponding information item based onthe clicked one's index and hide others.
});
Demo
with this you can safely remove the class with index like information1, information2 etc instead you can add a common class say content
<div class="information">
<span class="content"> information1 </span>
<span class="content"> information2 </span>
<span class="content"> information3 </span>
<span class="content"> information4 </span>
<span class="content"> information5 </span>
<span class="content"> information6 </span>
</div>
and change it to:
$('.menubutton').click(function(){
var index = $('.menubutton').index(this); //get the index of the menubutton clicked
$('.information > .content').eq(index).show().siblings().hide(); // show the corresponding information item based onthe clicked one's index and hide others.
});
Since you can't have ID's, we can get the index of the clicked menu item, add 1, then find the corresponding information span to show:
$(".menubutton").click(function() {
var menuIndex = $(this).index() + 1;
$(".information" + menuIndex).show();
});
The this keyword inside a function refers to the element that called the function.
Add the #id for each menubutton, so:
<div class="menubutton" id="btn_1"></div>
then:
$(".menubutton").on("click", function() {
// Get the id of button clicked.
var id = $(this).attr("id").split("_")[1];
// Target SPAN with the same id.
$("SPAN.information" + id).show();
});