I am very new to javascript and I'm learning everyday from your community.
However, I can't find a clean solution for my current problem.
I have a grid of tiles on the first slide of a slideshow, and I want each one to link to the respective slide. For example the tile with classname "linkSlide3" goes to slide "3". Now I want to avoid repeating the following function which is working at the moment:
$('.linkSlide3').click(function() {
$('.slider').mySuperSlider('goTo', 3);
return false;
});
I need to increment from 1 to 20, how can I write it nicely please?
Thank you very much for your help! :-)
For such situations I use data attributes to refer corresponding elements:
$('.linkSlide').click(function() {
$('.slider').mySuperSlider('goTo', $(this).data('slide'));
return false;
});
And in HTML you add data-slide attribute to each repeating element:
<a class="linkSlide" data-slide="3">...</a>
Here is abstract example of how such a binding can work: http://jsfiddle.net/rNvKe/
Instead of naming your action buttons
.linkSlide1
.linkSlide2
.linkSlide3
.etc...
you can just do
.linkslide
and make sure that there's no other element inside the parent of your buttons,
that way your .linkslide elements will be organized by index from 0 to 19 (for 20 buttons).
Than go grab the .index() of the clicked button and send it to .superSlider( THAT INDEX!! ).
To animate your slider than you can just multiply that retrieved index by one-slide-width:
LIVE DEMO
jQuery:
$('.linkSlide, .back').click(function() {
var ind = $(this).index()+1; // +1 cause we are already at 0
if($(this).hasClass('back')) ind = 0; // go to slide index 0
superSlider( ind );
});
function superSlider( ind ){
var oneSlideWidth = $('.slide').width();
$('#allSlides').stop().animate({left: -(ind*oneSlideWidth) },700);
}
HTML:
<div id="slider">
<div id="allSlides">
<div class="slide"> <!-- index = 0 -->
Slide 0
<button class="linkSlide">Tile index 1</button> <!-- index = 0, add 1-->
<button class="linkSlide">Tile index 2</button> <!-- index = 1, add 1 -->
<button class="linkSlide">Tile index 3</button> <!-- index = 2, add 1 -->
</div>
<div class="slide"> <!-- index = 1 -->
Slide 1
<button class="back">Back to 0</button>
</div>
<div class="slide"> <!-- index = 2 -->
Slide 2
<button class="back">Back to 0</button>
</div>
<div class="slide"> <!-- index = 3 -->
Slide 3
<button class="back">Back to 0</button>
</div>
</div>
</div>
CSS:
#slider{
position:relative;
width:100px;
height:95px;
background:#eee;
text-align:center;
overflow:hidden;
}
#allSlides{
position:absolute;
left:0;
width:9999px;
height:95px;
}
.slide{
position:relative;
width:100px;
height:95px;
float:left;
}
Explore the jQuery methods I used:
http://api.jquery.com/click/
http://api.jquery.com/index/
http://api.jquery.com/hasclass/
http://api.jquery.com/width/
http://api.jquery.com/stop/
http://api.jquery.com/animate/
This was my first question on this website, and I didn't expect so many detailed answers… so quickly!
So thanks to all of you, for your time, skills and kindness!
I followed dfsq answer and it worked fine :-)
HTML:
<div class="linkSlide" data-slide="1"></div>
<div class="linkSlide" data-slide="2"></div>
<div class="linkSlide" data-slide="3"></div>
etc… until 20
JS:
$('.linkSlide').click(function() {
$('.slider').mySuperSlide('goTo', $(this).data('slide'));
return false;
});
Related
I'm trying to figure out the simplest way to show and hide a series of divs with Previous and Next buttons by adding and removing some classes.
So far, I can get the Next button to trigger, but it's adding the active class to all of the divs and not just the next one in line.
I've been reading through other examples and so far they seem really bloated or not what I am looking for specifically.
Here's what I have so far:
Codepen Link: https://codepen.io/ultraloveninja/pen/pxrrmy/
HTML:
<div class="group">
<div class="item active">
<h2>Thing One</h2>
</div>
<div class="item">
<h2>Thing Two</h2>
</div>
<div class="item">
<h2>Thing Three</h2>
</div>
</div>
<div class="btns">
Previous
<a class="btn next" href="#">Next</a>
</div>
JS:
$('.next').on("click", function(){
if($('.item').hasClass('active')) {
$('.item').next().addClass('active');
}
})
CSS:
body {
padding: 10px;
}
.active {
display:block !important;
}
.item {
display:none;
}
It seems like this should be fairly simple, but I can't seem to think of how to target the next div by itself without it showing all of the other ones.
Basically you should get your last active element and activate next after it:
$('.next').on("click", function(){
const $active = $('.item.active');
const $next = $active.next();
if ($next.length) {
$active.removeClass('active');
$next.addClass('active');
}
})
The problem in your current code is that you are getting all items and performing hasClass on all of them so it returns true all the time because there is at least one element with this class and then you are getting next element after each item element and add active class to them so all of your elements are activated in result.
I think you want something like this
$('a.next').on("click", function(){
var a = $('.item.active').last();
a.next().addClass('active');
a.removeClass('active')
});
I am trying to create the following.
I have a button and on click of that button i need to add some active class to a div, but i have 4 divs with same class. What am trying to create is like a Choose Bet system like when you click first time on button you choose the first bet, when second time the second, i have 4 bets.
My html structure is the below
<div class="game_paytable_bluebet_column game_paytable_column"></div>
<div class="three_bet_wrappaer">
<div class="game_paytable_greenbet_column game_paytable_column"></div>
<div class="game_paytable_orangebet_column game_paytable_column"></div>
<div class="game_paytable_redbet_column game_paytable_column"></div>
</div>
What i did so far with jquery see below
jQuery('.choose_bet_button').click(function(){
if(!jQuery('.game_paytable_column:first').hasClass('active_blue_bet')){
jQuery('.game_paytable_column:first').addClass('active_blue_bet');
}else{
jQuery('.game_paytable_column:first').removeClass('active_blue_bet');
jQuery('.game_paytable_column').next().addClass('active_blue_bet');
}
});
With this code it is getting 2 elements.
Any idea how to get a solution to this?
Thanks in advance.
Here is an interpretation, please see the comments for a breakdown.
jQuery('.choose_bet_button').click(function(){
// get all the elements that match your selector
var $columns = $('.game_paytable_column')
// get the currently active element
var $active = $columns.filter('.active_blue_bet')
// get the index of the active element relative to your columns
var index = $active.length ? $columns.index($active) : -1
// increment the index if there is a next element or reset to 0
var newIndex = ($columns.length > index + 1)
? index + 1
: 0
// remove the active class from all elements
$columns.removeClass('active_blue_bet')
// set the new active column
$columns.eq(newIndex).addClass('active_blue_bet')
});
.game_paytable_column {
width: 100%;
height: 40px;
margin: 4px;
background: #eee;
}
.active_blue_bet {
background: #bada55;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game_paytable_bluebet_column game_paytable_column active_blue_bet"></div>
<div class="three_bet_wrappaer">
<div class="game_paytable_greenbet_column game_paytable_column"></div>
<div class="game_paytable_orangebet_column game_paytable_column"></div>
<div class="game_paytable_redbet_column game_paytable_column"></div>
</div>
<button class="choose_bet_button">choose</button>
Using :eq() you can achieve your requirement.
And initialize a counter and based on the counter add class in div.
And every four click make the counter 0.
Please check this snippet.
var _click = 0;
$('.choose_bet_button').click(function(){
if((_click % $(".game_paytable_column").length)==0){_click=0;}
$('.game_paytable_column').removeClass('active_blue_bet');
$('.game_paytable_column:eq('+_click+')').addClass('active_blue_bet');
_click++;
if($.trim($(".in_sight_area").html())==""){
$(".in_sight_area").html('<div class="top_bet_column_two top_bet_column game_paytable_column">New One</div>');
}
});
.active_blue_bet{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="in_sight_area"></div>
<div class="game_paytable_bluebet_column game_paytable_column">1</div>
<div class="three_bet_wrappaer">
<div class="game_paytable_greenbet_column game_paytable_column">2</div>
<div class="game_paytable_orangebet_column game_paytable_column">3</div>
<div class="game_paytable_redbet_column game_paytable_column">4</div>
</div>
<br/>
<button class="choose_bet_button">Choose Bet</button>
<div class="game_paytable_redbet_column game_paytable_column">5</div>
If you have a button... i.e.:
<button onclick="next()" >NEXT</button>
Seems quite simple:
// get all elements with class game_paytable_column
var columns = document.getElementsByClassName("game_paytable_column");
// counter to control the actual index
var counter = 0;
function next() {
// this selects the actual element and shows content
alert(columns[counter].innerHTML);
//and passes to next element
if (counter == columns.length - 1)
counter = 0;
// first if necessary
else
counter ++;
}
WORKING DEMO
That's all :)
I'm trying to show hidden rows one at a time on button click, but they all show at once since they have class "row" - the 1st row is shown by default and the rest are hidden
I can't use Id selectors since it's server side and dynamic, so how can I only show the immediate next row/sibling on each click until there are none left? I could append a counter to each row class but that wouldn't help when trying to select the next row in jQuery with that counter
This is what I have which shows all rows on one click
<script>
$(".myButton").click(function() {
$('.container .row').next('.row:hidden').slideDown();
});
</script>
<div class="container">
<!-- 1st row not hidden by default -->
<div class="row">
<div class="row">
<div class="row">
</div>
Thanks for help in advance!
$('.container .row:visible').last().next('.row:hidden').slideDown();
If all you're doing is showing them in a sequential order, then you don't need to track which are active. You can simply use the visibility to always choose the last.
All you do is add the :visible to the row selection, to find all visible rows; then use the last() method to only reference the last of that stack. This allows next() to be called for only one element (the last one), and not all the rows in the container.
To simplify this even more (and call fewer methods), you could choose to only select the first hidden row: $('.container .row:hidden:first').slideDown(); or $('.container .row:hidden').first().slideDown();
Fiddle
If you add the class "selected" to the first row than you could do this:
<script>
$(".myButton").click(function() {
$('.container .row.selected')
.removeClass('selected')
.hide()
.next()
.addClass('selected')
.slideDown();
);
</script>
<div class="container">
<div class="row selected">
<div class="row">
<div class="row">
</div>
You could try iterating through the collection to display the correct one. See this JSFiddle: http://jsfiddle.net/gjqb6m83/
var i = 0;
var collection = $(".row");
$(".myButton").click(function() {
$(collection).css('display', 'none');
$(collection[i]).slideDown();
i++
i = i % collection.length;
});
you can use :nth-child()
$(document).ready(function() {
var counter = 1;
$(".myButton").click(function() {
counter++;
$('.container .row').hide();
$('.container .row:nth-child(' + counter + ')').slideDown();
});
});
.row {
display:none;
}
.row:nth-child(1) {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="myButton">My Button</button>
<div class="container">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
<div class="row">row 4</div>
<div class="row">row 5</div>
</div>
Make use of another jQuery-pseudo-selector :first
$(".myButton").click(function() {
$('.container .row:hidden:first').slideDown()
});
and dont forget to close your divs! Look at https://jsfiddle.net/kswmktce/1/
Yet another solution. This one shows just one at a time, and starts over when finished.
$(".myButton").click(function() {
$(".row:visible").next().slideDown();
$(".row:visible").first().hide();
if (!$(".row:visible").length)
$(".row").first().slideDown();
});
.row {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<button class="myButton">Click ME</button>
<div class="container">
<div class="row">a</div>
<div class="row">b</div>
<div class="row">c</div>
<div class="row">d</div>
<div class="row">e</div>
</div>
I want to get the index of the clicked child
<div class="parent">
<div class="child">
<div class="c1"></div>
<div class="c2"></div>
</div>
<div class="child">
<div class="c1"></div>
<div class="c2"></div>
</div>
<div class="child">
<div class="c1"></div>
<div class="c2"></div>
</div>
</div>
jQuery:
$('.child .c1').click(function(){
alert($(this).parent().index())
})
I always get -1. How can i do this work?
EDIT:
I tried this:
$('.child .c1').click(function(){
alert($(this).index())
})
The result is -1 all the time.
What could be wrong?
var child_index = '';
$('.c1').click(function() {
var parent = $(this).parent();
child_index = $(parent).index();
alert(child_index);
});
.div{
position:absolute;
left:45%;
top:0;
}
.child{
margin:1%;
text-align:center;
background-color:gray;
width:100px;
height:100px;
}
.c1,.c2{
color:white;
background-color:blue;
}
.c2{
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="div">
<div class="child">
<div class="c1">c1</div>
<div class="c2">c2</div>
<p>click only work on <strong>c1</strong></p>
</div>
<div class="child">
<div class="c1">c1</div>
<div class="c2">c2</div>
<p>click only work on <strong>c1</strong></p>
</div>
<div class="child">
<div class="c1">c1</div>
<div class="c2">c2</div>
<p>click only work on <strong>c1</strong></p>
</div>
</div>
var child_index = ''; //to store .child class parent index when clicked
$('.c1').click(function() {
var parent = $(this).parent(); //getting the specific parent of c1
//parent variable value now is = .child
child_index = $(parent).index();
alert(child_index);
});
The reason that it returns -1 every time is because in Jquery -1 is a boolean for false and 0 is true. .index() basically asks whether an element exists.
If you want to find what number it is this is a code which I think would work.
var loop = $('.parent .child').length;
$('.child .c1').click(function(){
for(i=1; i<= loop; i++) {
if($(this).parent() === $('.parent').children().eq(i)) {
alert(i);
}
}
});
EDIT Since no one can reproduce the problem, here are some possibilities:
The version of jQuery you're using is conflicting with another script on your page. Since it seems your click event handler is firing because your getting an alert box.
Try using the latest version of jQuery.
Your version of jQuery is conflicting with the current browser you are using. When you're having JavaScript issues you should report the versions of the library you are using (if any) and of your browser.
Check your results in another browser and report back.
Your HTML is being manipulated before your click event is fired. What other code do you have on the page?
Share a more complete source code listing.
alert($(this).parent().prevAll().length);
Use .prevAll to get all previous siblings, then use the length of that set as your index.
edit Use .prevAll(".child") if you are expecting other elements that you want to ignore for indexing purposes.
edit You could try removing jQuery all together
var elms=document.getElementsByClassName("c1");
for(var i=0; i<elms.length; i++)
elms[i].onclick = function() {
var elm = this;
var index = 0;
elm = elm.parentNode;
if(elm) {
while(elm=elm.previousSibling) {
if(elm.nodeType == 1) {
index++;
}
}
} else {
alert("There's no parent node");
}
alert(index);
};
Im having problems with this code to work.. http://jsfiddle.net/whitewiz/z4fpx/
HTML
<h1 id="flip">Title<h1>
<div id="panel">
<p>Description that slides down</p>
</div>
<h1 id="flip">Title<h1>
<div id="panel">
<p>description that DOESN'T slide down</p>
</div>
JavaScript
$(document).ready(function(){
$("#flip").click(function(){
$("#panel").slideToggle("slow");
});
});
and CSS
#panel,#flip
{
padding:5px;
text-align:center;
background-color:#e5eecc;
border:solid 1px #c3c3c3;
}
#panel
{
padding:50px;
display:none;
}
They work for first description, but doesn't work for the rest. I have about 18 #panels that should slide down, when I press on "Title" but only the first works.. Could you please find the missing piece in javascript that doenst allow multiple toggle?
Example on -> http://jsfiddle.net/whitewiz/z4fpx/
The first one works because that is the first element in the DOM with that id. Generally it is bad practice to have the same id assigned to multiple elements. Instead, use classes, like this:
HTML:
<h1 class="flip">Title<h1>
<div class="panel">
<p>Description that slides down</p>
</div>
<h1 class="flip">Title<h1>
<div class="panel">
<p>description that DOESN'T slide down (but does now)</p>
</div>
CSS:
.panel,.flip
{
padding:5px;
text-align:center;
background-color:#e5eecc;
border:solid 1px #c3c3c3;
}
.panel
{
padding:50px;
display:none;
}
I assume you only want to expand the panel following the header that you clicked on, in which case you need to get the closest element with the class name "panel" that follows the "flip" that was clicked on.
$(document).ready(function(){
$(".flip").click(function(){
$(this).next().find(".panel").slideToggle("slow");
});
});
Working example: http://jsfiddle.net/BBQJy/
The initial question seems to be lacking proper closing tags, an error that was duplicated in Nile's answer. Therefore, it didn't work for the original poster.
Based on Anna Brila's updated jsfiddle (http://jsfiddle.net/whitewiz/WuNHz/2), a possible correct solution would be:
$(".flip").click(function(){
$flip = $(this);
$content = $flip.next();
$content.slideToggle();
});
This is predicated on the use of classes instead of ids.
Full working example: http://jsfiddle.net/wy8gq1bj/1
Note: In the example, the only HTML I changed was the removal of the <br> immediately after the third , which was keeping the last item from expanding and collapsing.