I have several div elements with incremental IDs (e.g. div0, div1, div2 (I know this is bad practice - I'm developing a dynamic CSV-to-HTML converter for Outlook calendar exports)) and I'd like to switch between them using jQuery linked to forward/back buttons . What I'm trying to do is as follows (in meaningless pseudo-code):
int pos = 0
forward.onclick
hide ("#div"+pos)
pos++
show ("#div"+pos)
back.onclick
if pos != 0
hide ("#div"+pos)
pos--
show ("#div"+pos)
Since I know next to nothing about jQuery, my questions are 1. What would the syntax be for implementing the above example (assuming I'm on the right track), and 2. Is there a way in jQuery to somehow check for an upper boundary so the counter doesn't increase above the number of divs?
If you want to know how many divs you have in jQuery, select them and take the length of your selection:
$('.div').length
You could even just use that selection to cycle through which divs to show:
var $divs = $('.div');
var upperLimit = $divs.length - 1;
var index = 0;
// on arrow click
$($divs[index]).hide();
index++ (or index--, depending on the arrow)
$($divs[index]).show();
int is not a data type in JavaScript. Use var. Declaration would be var pos = Number(0). To prevent exceeding the boundaries of number of divs, declare a variable with the number of divs you have, and inside your hide and show calls, use pos℅divLength instead of pos. Suppose you have total divs as 4, you will never exceed div3 this way. It will iterate from div0 to div3. Refer this to learn how to use show and hide methods.
Here's a demo.
var index = 0;
$('#div' + index).show();
$('#next').click(function () {
index++;
$('#back').prop('disabled', false);
if (index === fakeData.length - 1) {
$('#next').prop('disabled', true);
}
$('.items').hide();
$('#div' + index).show();
});
$('#back').click(function () {
index--;
$('#next').prop('disabled', false);
if (index === 0) {
$('#back').prop('disabled', true);
}
$('.items').hide();
$('#div' + index).show();
});
The above code will disable and enable the next and back buttons based on whether you are at the beginning or the end of your list of data. It hides all elements and then shows the specific one that should be shown.
Related
I am trying to write some javascript to change the css of 4 different classes 1 after the other.
So I click a button for the first time i want it to change class of the first element, then a second click of the same button will change the class of a second element and then the same for the 3rd and 4th.
I have the first click changing the first element but if I add in the code with the intention for it the change the class for the second element it is changed with the first click. I've tried using separate 'if' statements and an 'else if' but it always changes all the classes together or just the first class.
FIRST TRY
With 1 count element - Even though the critcount increases to 2, with the second click it does not get access to the else part of the if statement on a second click of the button.
var critcount = 1;
$(function () {
$('#criteriasubmit').click(function () {
if (critcount = 1) {
var criteria1 = document.querySelector('.criteria1');
criteria1.classList.add('criteria1selected')
critcount++;
} else if (critcount= 2) { *//this part of the if statement is intended to work for the second
click the second click*
var criteria2 = document.querySelector('.criteria2');
criteria2.classList.add('criteria2selected')
critcount++;
}
console.log("The crit count is : " + critcount);
})
});
SECOND TRY
Separate IF statements just change the class of both elements with a single click. Even though crit2count should not increase to 2
var crit1count = 1;
var crit2count = 1;
$(function () {
$('#criteriasubmit').click(function () {
if (crit1count = 1) {
var criteria1 = document.querySelector('.criteria1');
criteria1.classList.add('criteria1selected')
crit1count++;
}
if ((crit2count= '1') && (crit1count= '2')) { //*even if I put this above the 1st if it still
actives on the first
click*
var criteria2 = document.querySelector('.criteria2');
criteria2.classList.add('criteria2selected')
crit2count++;
}
console.log("The crit1 count is : " + crit1count);
console.log("The crit2 count is : " + crit2count);
})
});
I have tried different combinations of the second if statement it always activates on the first click with the 2 separate if statement methods.
I hope this is clear and makes sense, please let me know if you think you need some more info.
Thank you in advance!
I am building a small app, that lets you go through people businesscards, 3d style.
Basically, I have an unordered list, containing 10 list items. Each time I press the down arrow on the left, I want to remove the first (the one at the front) and push it at the back (so it becomes the last in the list).
Also, since all of the items, except the first one, have negative transformZ values to push them back, I want to rearrange them so they come closer to the user, each time the down btn is pushed. Right now each of them has a 80*i for a transformZ value and I have no idea how to push them towards without messing up the same layout.
I tried doing something like, but unfortunately it doesn't do the trick:
btnDown.addEventListener('click', function() {
listItems[0].parentNode.removeChild(listItems[0]);
for (i=0; i<=listItems.length-1;i++) {
list.style.webkitTransform = "rotateX(0deg) translateZ(-" + (100*i) + "px)";
}
}, false);
You can also find the complete project here:
http://codepen.io/gbnikolov/pen/cbdwl
Thanks in advance, all help is much appreciated!
btnDown.addEventListener('click', function() {
listItems[0].parentNode.appendChild(listItems[0]);
// re-index list
listItems = document.querySelectorAll('#primary ul li')
for (i=0; i<=listItems.length-1; i++) {
listItems[i].style.webkitTransform = "rotateX(0deg) translateZ(-" + (80*i) + "px) translateY(-" + i*20 + "px)";
}
}, false);
You were close. Instead of removing the item, move it to the end of the node. Then re-apply the webkitTransform.
btnUp.addEventListener('click', function() {
var lastItem = listItems[listItems.length-1]
listItems[0].parentNode.insertBefore(lastItem, listItems[0]);
listItems = document.querySelectorAll('#primary ul li');
applyWebkitTransform();
}, false);
For the up button use the insertBefore() function. See: http://codepen.io/anon/pen/cAbKI
I've been working on this JSFiddle to practice my understanding of jquery, but now I'm stuck.
How do you wrap a child element in a div to follow this pattern: child elements 1-5, then child elements 6-10, then child elements 11-15, and so on?
I'm working on a tally counter, so I want every 5 tallies to cluster together. That way, I can more easily select the last child and apply a class to make it rotate, in order to "cross out" the previous 4 tallies.
edit: (To clarify: I've been looking into selecting by index and by nth-child/nth-of-type, but those methods can only really grab the fifth element, or maybe even multiples of five? It doesn't grab the previous divs, too.)
edit 2: (So, you can actually use those selectors! I figured I was getting something wrong. It's always something simple.)
$(".button").click(function() {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
if ($button.text() == "+") {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 0) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 0;
}
}
$("#counternumber").val(newVal);
});
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally)
});
$(function(){
$('#scratchpad.tally:nth-of-type(5)').wrap('tallyfamily');
});
JSFiddle.
Here is a general solution to wrap elements in groups of 5:
$(".holder > div:nth-child(5n-4)")
.addClass("first-of-group")
.each(function(){
$(this).nextUntil(".first-of-group")
.addBack()
.wrapAll("<div class='wrapper'>");
})
.removeClass("first-of-group");
http://jsfiddle.net/nJJM8/1/
Basically, :nth-child(5n-4) gets the first element in each group of 5. Then a class is temporarily added to keep track of these. nextUntil is used to find all elements up until the next element with that class. And finally wrapAll is used to wrap the matched elements in a div.
EDIT: Even easier:
var $divs = $(".holder > div");
for (var i = 0; i < $divs.length; i += 5) {
$divs.slice(i, i + 5).wrapAll("<div class='wrapper'>");
}
http://jsfiddle.net/kMzeN/1/
You're almost there, but a couple of things to note. You will only call your "wrap" function once, as it's outside of the click event. If you are dynamically adding, then you'll want to call it each time.
Secondly, with the HTML in your fiddle, you will never get the 5th record because you are appending your selector is looking for the 5th element with ID "scratchpad" with the class of tally. You'd need to change your selector to something that looks for all tallies, like so:
$(".tally:nth-of-type(5)").css('color', 'red');
I've updated the fiddle you were working on, and my code highlights each 5th record, so you can see what's going on. You were close, but you'll also want to add to your "nth-of-type" selector the use of "n", this way it gets every 5th record, not just the 5th one. So the full function becomes this
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally);
$(".tally:nth-of-type(5n)").css('color', 'red');
});
Fiddle: http://jsfiddle.net/Hfz9L/16/
To rotate (or apply any other property) to each 5th element, you don't even need to wrap them. Just specify a css class using the nth-of-type(5n) and it will affect every 5th element.
#scratchpad .tally:nth-of-type(5n) {
display: inline-block;
transform:rotate(20deg);
-ms-transform:rotate(20deg); /* IE 9 */
-webkit-transform:rotate(20deg); /* Opera, Chrome, and Safari */
}
Here is your fiddle updated: http://jsfiddle.net/Hfz9L/20/
Check this Working Demo Fiddle
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally);
$('#scratchpad .tally:nth-of-type(5n+1)').prevUntil('span').wrapAll('<span style="margin-right:5px;color:red;text-decoration:line-through;"></span>');
});
$('#scratchpad .tally:nth-of-type(5n+1)').prevUntil('span').wrapAll('<span style="margin-right:5px;color:red;text-decoration:line-through;"></span>');
Some changes:
$('#scratchpad .tally:nth-of-type(5n+1)') and not $('#scratchpad.tally:nth-of-type(5)'). - .tally is the child of #scratchpad ; selector to be used :nth-of-type(5n+1)
Use .wrapAll() - to wrap the selected elements in a <span> or any other element.
.prevUntil() - get all the previous elements.
You can make a for loop and do this:
for(i=1;i<=noOfChildElements/5;i++)
{
$('.child:nth-child('+i+'), .child:nth-child('+(i+1)+'), .child:nth-child('+(i+2)+'), .child:nth-child('+(i+3)+'), .child:nth-child('+(i+4)+')').wrapAll("<div />");
}
Basically I'm going through the child elements in the for loop and at every turn of the loop I'm selecting the 5 next child elements and wrapping them in a div using the .wrapAll() function. Hope this helps.
i'm building a webpage where many span needs to be transitioned from one class to another to create a bg-color fadein effect. Distribution of elements of same classes is mixed through the page, but they are all grouped under common classes.
I want to create a behavior that does the following: when you click any elements of class-n, the other elements of that class transitions, with the clicked element acting as the starting point.
This is mostly figured out, thanks to some help on SO; see the jsfiddle.
$(".div").click(function () {
var itemClasses = this.classList;
var itemThread = itemClasses[1];
colorThread($(this), itemThread);
console.log(itemThread);
});
function colorThread($div, tId) {
tId = '.'+tId;
$div.toggleClass('div-clicked');
setTimeout(function () {
(function togglePrev($div) {
$div.toggleClass('div-clicked');
setTimeout(function () {
togglePrev($div.prev(tId));
}, 100);
})($div.prev(tId));
(function toggleNext($div) {
$div.toggleClass('div-clicked');
setTimeout(function () {
toggleNext($div.next(tId));
}, 100);
})($div.next(tId));
}, 100);
}
However, I am still struggling around a particular issue: I don't want the transition to stop if if encounter different class, I just want it not to toggle and keep iterating. If the jsfiddle, that would translate in all of the same color div to transition, regardless of their placement in the DOM tree.
In my togglePrev/toggleNext function, I have tried something along
if($div.hasClass(".classToTransition"))
{
$div.toggleClass(".div-clicked");
}
but couldn't get it to work properly (it doesn't ieterate to the next elements). There is something that I can't seem to grasp in the structure of that conditional. Anyone has a lead?
You really did manage to complicate something that should be pretty simple ?
$(".div").click(function () {
var coll = $('.'+this.className.replace(/(div-clicked|div)/g, '').trim()),
idx = coll.index($(this).toggleClass('div-clicked'));
$.each(coll, function(i) {
setTimeout(function() {
if (idx + i <= coll.length) coll.eq(idx + i).toggleClass('div-clicked');
if (idx - i >= 0) coll.eq(idx - i).toggleClass('div-clicked');
},i*200);
});
});
FIDDLE
It gets all the elements with the same class as the one currently clicked, and the index of the currently clicked, and then just adds and subtract 1 to the current index to get the next and previous elements. The checks are to make sure it stops when it reaches the end.
I don't want the transition to stop if if encounter different class, I just want it not to toggle and keep iterating
You might want to use nextAll(tId).first()/prevAll(tId).first() to select the next to-be-toggled element: http://jsfiddle.net/35uNW/4/. .next() does only look at the next sibling, and if that doesn't match your tId selector, no element will be selected.
If you want to iterate the different-classed elements so that you wait for each one, but don't want to toggle it, you can use your if-condition but you must remove the tId selector from the next()/prev() calls: http://jsfiddle.net/35uNW/3/.
This was a fun one. I did it a slightly different way, getting all of the matched elements and splitting them into before and after arrays.
var $allItems = $(".div");
$(".div").click(function () {
var itemClasses = this.classList;
var itemThread = itemClasses[1];
colorThread($(this), itemThread);
});
function colorThread($div, classname) {
var tId = '.'+classname,
$divs = $allItems.filter(tId),
index = $divs.index($div),
$before = $divs.slice(0, index),
before = $before.get().reverse(),
$after = $divs.slice(index+1);
$div.toggleClass('div-clicked');
$(before).each(function(i, item){
setTimeout(function () {
$(item).toggleClass('div-clicked');
}, i*100);
});
$($after).each(function(i, item){
setTimeout(function () {
$(item).toggleClass('div-clicked');
}, i*100);
});
}
Here's a working fiddle: http://jsfiddle.net/5sUr4/
I have three divs and I want to execute a command on a div that happens to be on top of the other divs in a container without referencing it's name or id.I am randomizing the position of the divs and I basically want the div whose height is equal to 10px to change it's color attribute to red when a specific number is generated, whilst the other divs maintain their default color. I have tried the following but I can't think of any way to do this without using the div's id.
var current = 0;
current++;
var topArrtcard = document.getElementById("card-answer");
var topArrtcard1 = document.getElementById("card-answer1");
var topArrtcard2 = document.getElementById("card-answer2");
if(current === 0 ){
topArrtcard.style.color = "red"; // is it possible not use the id in order to make the change
topArrtcard1.style.color = " #996600";
topArrtcard2.style.color = " #996600";
}else if(current === 1 )
{
topArrtcard.style.color = "#996600";
topArrtcard1.style.color = "red";
topArrtcard2.style.color = " #996600";
}else if(current === 2){
topArrtcard.style.color = "#996600";
topArrtcard1.style.color = " #996600";
topArrtcard2.style.color = "red";
}else {
topArrtcard.style.color = "#996600";
topArrtcard1.style.color = " #996600";
topArrtcard2.style.color = "#996600";
}
the variable current increments by 1 each time the page is loaded. I hope this is clear. Thank you in advance.
If you are not opposed to using jQuery (and why would you be? In many ways it's simpler than javascript with much less to type)...
I cannot see from your code (at this moment) what will trigger an event that you can use to do the testing that you want.
However, if something does happen to the DIV, then perhaps you can use that event to make the changes you want. You would reference the changed DIV as this.
Here is an example that looks somewhat similar