How to select between a list css classes - javascript

I have a div with a next and previous button
<div class="b1"></div>
<input type="button" class="btnP" value="Prev"/>
<input type="button" class="btnN" value="Next"/>
and a list of css classes
.b1 { background-color:#fff;}
.b2 { background-color:#000;}
.b3 { background-color:#123;}
.b4 { background-color:#444;}
.b5 { background-color:#bbb;}
which i want to use for that div when the user press the next or previous button by that numbering order.
This is what i did so far:
http://jsfiddle.net/51dq5num/
var size_ini = 1;
$(".btnN").click(function () {
var size_increase = size_ini++;
var size_increase1 = size_ini;
$("#content").html("<span>" + size_increase + "</span>").removeClass().addClass("b" + size_increase);
if (size_increase > 4) {
size_ini = 1;
}
});
I manage to get the next button working but i'm not sure how to do it for the previous button
Is there a better way to do this rather then adding and removing css classes from the div?

Try this :
$(".btnP").click(function () {
var size_increase = $("#content").attr("class").substring(2, 1);
size_increase--;
if (size_increase < 1) {
size_increase = 5;
}
$("#content").html("<span>" + size_increase + "</span>").removeClass().addClass("b" + size_increase);
});
jsFiddle : http://jsfiddle.net/51dq5num/7/

You can do something like this:
var newClass = function(div, next) {
div[0].className = div[0].className.replace(/b\d+/, "b" + newClass[next ? 'next' : 'prev']());
};
newClass.atual = 1;
newClass.last = 5;
newClass.next = function(){
this.atual = (this.atual == this.last ? 1 : this.atual + 1);
return this.atual;
};
newClass.prev = function(){
this.atual = (this.atual == 1 ? this.last : this.atual - 1);
return this.atual;
};
var myDiv = $("#content");
$(".btnN").click(function () {
newClass(myDiv, true);
});
$(".btnP").click(function () {
newClass(myDiv, false);
});
Jsfiddle here.

This is a combined solution for both buttons.
var size_ini = 0;
$("input[type='button']").click(function () {
if($(this).hasClass("btnN"))
{
size_ini=size_ini+1;
var c="b"+size_ini;
$("#content").removeClass().addClass(c).html("TG"+size_ini);
}
else
{
size_ini=size_ini-1;
var c="b"+size_ini;
$("#content").removeClass().addClass(c).html("TG"+size_ini);
}
});
Note as it is not mentioned i have not checked on the max condition thus btnP can increase the counter infinitely.You can put it in a condn and limit it to a max value.

http://jsfiddle.net/n8dLgh3L/1/
Here is js code to increase and decrease.
var size_ini = 0;
$(".btnN").click(function () {
if (size_ini > 4) {
size_ini = 1;
} else {
size_ini++
}
$("#content").html("<span>" + size_ini + "</span>").removeClass().addClass("b" + size_ini);
});
$(".btnP").click(function () {
var size_decrease = $("#content").attr("class").substring(1, 2);
if (size_decrease <= 1) {
size_decrease = 5;
} else {
size_decrease--;
}
$("#content").html("<span>" + size_decrease + "</span>").removeClass().addClass("b" + size_decrease);
});

You ca achieve this with the help of .substr() for incrementing the number of class. Have a look.
function Getnumber(classNumber,nav)
{
var no=0;
if(nav=="P")
{
no=parseInt(classNumber.substr(1,2))-1;
}
else
{
no=parseInt(classNumber.substr(1,2))+1;
}
return no;
}
$(".btnN").on("click",function(){
var oldClass=$('div').attr("class");
var num=Getnumber(oldClass,"N");
if(num<6)
$('div').addClass("b"+num).removeClass(oldClass);
});
$(".btnP").on("click",function(){
var oldClass=$('div').attr("class");
var num=Getnumber(oldClass,"P");
if(num>0)
$('div').addClass("b"+num).removeClass(oldClass);
});
Feel free to ask.

Related

Issue linking images to dynamically created jquery elements

So, I'm very new, so apologies if this is a silly question. I have worked out a Trivia Quiz for my learning to code classes I'm taking. I want to display an image on the confirmation screen that shows whether the user was right or wrong. I think the code is correct-ish? I'm not sure what isn't working.
I left out the main Question and answer object for space. Sorry if I didn't format this ideally? I'm still kinda figuring out how things work here.
Here is my code for reference:
//array to help me iterate and insert images
var imgArray = ["question1", "question2", "question3", "question4", "question5", "question6", "question7", "question8", "question9", "question10", "question11", "question12", "question13"];
var currentQuestion = 0;
var win = 0;
var lose = 0;
var unanswered = 0;
var time = 30;
//set up divs to contain our info
var rightDiv = $("<div class='rightAns'></div>");
var timerDiv = $("<div class='countdown'><h3></h3></div>");
var questionDiv = $("<div class='question'><h1></h1></div><br>");
var answerDiv = $("<div class='answers'></div>");
//object keys to return questions in order
var keys = Object.keys(questions);
var key = keys[n];
var n = 0;
//function to setup and restart game
function reset() {
$("#start-button").hide("slow");
$("#start-here").hide("slow");
win = 0;
lose = 0;
unanswered = 0;
n = 0;
key = keys[n];
currentQuestion = 0;
$("#question-block").empty();
var reset = function () {
time = 30;
$(".rightAns").empty();
$(".rightAns").remove();
// $("#image").empty();
$("#time-remaining").append(timerDiv);
$(".countdown h3").html("Time Remaining: " + time);
$("#question-block").append(questionDiv);
$("#question-block").append(answerDiv);
}
reset();
//function to show questions
function showQuestion() {
$(".question h1").html(questions[key].question);
for (var i = 0; i < questions[key].answers.length; i++) {
$(".answers").append("<button class='answer btn btn-danger btn-lg m-1'>" + questions[key].answers[i] + "</button>");
}
$(".answers button").on("click", function () {
var selected = $(this).text();
//if then to check question correctness
if (selected === questions[key].correct) {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$(answerDiv).remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").text("That's Correct!!");
$("#image").html('<img src = ".assets/images/' + imgArray[currentQuestion] + '" width = "400px">');
win++;
currentQuestion++;
} else {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$(answerDiv).remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").text("Nope! The correct answer was: " + questions[key].correct);
$("#image").html('<img src = ".assets/images/' + imgArray[currentQuestion] + '" width = "400px">');
lose++;
currentQuestion++;
}
n++;
key = keys[n];
//checking to see if there are more questions left
if (checkForLast()) {
finalScore();
} else {
setTimeout(countReset, 3 * 1000);
setTimeout(reset, 3 * 1000);
setTimeout(showQuestion, 3 * 1000);
}
});
}
showQuestion();
var counter = setInterval(count, 1000);
//show time remaining for each question
function count() {
time--;
$(".countdown h3").html("Time Remaining: " + time);
if (time < 1) {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").html("You took too long! The correct answer was: " + questions[key].correct);
unanswered++;
n++;
key = keys[n];
if (checkForLast()) {
finalScore();
} else {
setTimeout(countReset, 3 * 1000);
setTimeout(reset, 3 * 1000);
setTimeout(showQuestion, 3 * 1000);
}
}
}
function checkForLast() {
if (key === undefined) {
return true;
}
return false;
}
//timer for the message after you choose your answer
function countReset() {
counter = setInterval(count, 1000);
}
//showthe final score screen
function finalScore() {
$(".rightAns").remove();
$("#image").empty();
$("#question-block").prepend("<h2>Unanswered: " + unanswered + "</h2>");
$("#question-block").prepend("<h2>Incorrect: " + lose + "</h2>");
$("#question-block").prepend("<h2>Correct: " + win + "</h2>");
$("#start-button").show();
$("#start-here").show();
}
};
//function to start game on button click
$(document).on("click", "#start-button", reset);
});
After tinkering for a bit, I dropped the "." at the beginning of the call and added the .jpg to the section after imgArray[currentQuestion]. That solved it. Thanks for the suggestions.

Auto Increment width of an input tag

I am trying to code an counter.
Here is my JsFiddle
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1)
{ }
else
$('#how-many').val(val-1);
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
});
I want the size of the input tag to auto-increment when the content inside the input tag will become 2digit or 3digit.
is it possible only with css.
I think the best solution in this case would be not to use input tag, instead replace it with span tag. span is an inline element and the width will auto increment based on its content.
As i am moving to span, the jquery will change. and instead of val() we should use text()
Demo fiddle http://jsfiddle.net/ssxx8/11/
You can do something roughly similar to this:
$(function() {
var $howMany = $('#how-many'); // cache that
$('.substract-value').click(function(){
var val = $howMany.val();
if (val == 1) { }
else {
$howMany.val(val-1);
checkSize(val);
}
});
$('.add-value').click(function(){
var val = $('#how-many').val();
$howMany.val(parseInt(val)+1);
checkSize(val);
});
function checkSize(v) {
if ( v > 9 ) {
$howMany.css('width', '80px');
} else if ( v < 9 ) {
$howMany.css('width', '20px');
};
}
});
Try this
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1) { }
else
$('#how-many').val(val-1);
setWidth();
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
setWidth();
});
var oneLetterWidth = 10;
var minCharacters = 2;
function setWidth() {
var len = $("#how-many").val().length;
if (len > minCharacters) {
// increase width
$("#how-many").width(len * oneLetterWidth);
} else {
// restore minimal width;
$("#how-many").width(50);
}
}
DEMO
Try this
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1) { }
else
$('#how-many').val(val-1);
updateWidth();
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
updateWidth();
});
function updateWidth(){
size = $('#how-many').val().length;
size = size*7; // average width of a char is 7px
$('#how-many').css('width',size);
}
JSFIDDLE : http://jsfiddle.net/ssxx8/9/
You need to approach this way:
var obj = $('#how-many');
$('.substract-value').click(function () {
var content = obj.val();
if (content > 1)
obj.val(parseInt(obj.val()) - 1);
obj.css("width", (obj.val().length * 10) + "px");
});
$('.add-value').click(function () {
obj.val(parseInt(obj.val()) + 1);
obj.css("width", (obj.val().length * 10) + "px");
});
Refer LIVE DEMO

get interval ID from else statement when set in IF

I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});

jQuery rearrange DOM elements

I'm a little confused why this is not working how it's supposed to.
I have a list of <div>s that wrap around based on the size of the page. But clicking the div it .animate() the width of the clicked div and animates the divs after it closer together and stacks them.
This all works except the last stacked div, despite having plenty of room still gets knocked down to the next row.
please see my code on jsfiddle:
http://jsfiddle.net/ZHYRq/2/
$.each($('.employee-box'), function(i, el) {
$(el).addClass("top-" + (Math.round($(el).offset().top)));
return $(el).css('position', 'relative').attr('data-left', Math.round($(el).offset().left));
});
$('.employee-image').hover(function(e) {
var $employee;
$employee = $(e.target).parents('.employee-box');
if (e.type === 'mouseenter') {
return $($employee.find('a.bio')).addClass('highlight');
} else {
return $($employee.find('a.bio')).removeClass('highlight');
}
});
$('.employee-image, a.bio').click(function(e) {
var $employee, is_expanded, speed;
speed = 150;
$employee = $(e.target).parents('.employee-box');
is_expanded = $employee.hasClass('bio-expanded');
if ($('.bio-expanded').length > 0) {
$.when(collapse_previous_bio(speed)).then(function() {
if (!is_expanded) {
return expand_bio_box($employee, speed);
}
});
} else {
expand_bio_box($employee, speed);
}
return false;
});
var collapse_previous_bio = function(speed) {
var klass;
klass = "." + $('.bio-expanded').attr('class').match(/top-\d{1,5}/)[0];
$('.bio-expanded .bio-block').fadeOut(speed, function() {
$('.bio-expanded').animate({
width: "185px"
}, speed);
$(klass).animate({
left: '0px'
}, speed);
$('.bio-expanded').removeClass('bio-expanded');
});
};
var expand_bio_box = function($employee, speed) {
var curr_left, klass;
klass = "." + $employee.attr('class').match(/top-\d{1,5}/)[0];
curr_left = parseInt($employee.data('left'));
// comment out the $.when block and un-comment out the collapse_others() to see the other elements collapse as they should
$.when(collapse_others(klass, curr_left)).then(function() {
$employee.animate({
width: "392px"
}, speed, function() {
$employee.find('.bio-block').fadeIn(speed);
$employee.addClass('bio-expanded');
});
});
// collapse_others(klass, curr_left)
};
var collapse_others = function(klass, curr_left) {
var left_pos;
left_pos = 0;
$.each($(klass), function(i, el) {
var el_left;
el_left = parseInt($(el).data('left'));
$(el).css({
zIndex: 100 - i
});
if (el_left > curr_left) {
$(el).animate({
left: "-" + left_pos + "px"
}, 100);
left_pos += 100;
}
});
};
I'm not sure what is wrong here. Any thoughts?

Jquery - Animate innerHTML possible?

I'm trying to have a function that does setTimeout, then changes the innerHTML:
<script type="text/javascript">
$(document).ready(function(){
setTimeout(function(){
document.getElementById("middlecolor").innerHTML='new text new text';
}, 1000);
});
</script>
Question: How could I animate the new text that appears, i.e. line by line as opposed to being written all at once?
Thanks for any suggestions!!
Try something like this:
<div id="text">
</div>
$(document).ready(function () {
var interval = setInterval(function () {
$('#text').append('<p style="display: none;">new text</p>');
$('#text p:last').fadeIn('slow');
}, 5000);
});
See the example here
If you want to kill the interval, can be doing this:
clearInterval(interval);
Greatings.
Line-by-line is a bit tricky, but possible.
var ps = document.getElementById("text").children;
var i = 0;
var $p = $(ps[i]);
setTimeout(function newline(){
$p.css("height", function(index, h){
h = parseInt(h);
h += parseInt($p.css("line-height"));
console.log(h, ps[i].scrollHeight);
if (h > ps[i].scrollHeight)
$p = $(ps[++i]);
return h;
});
if (i < ps.length)
setTimeout(newline, 200);
}, 200);​
I'd suggest to use a typewriter effect, which is also very likable: http://jsfiddle.net/pZb8W/1/
var ps = document.getElementById("text").children;
var i = 0;
var $p, text;
var speed = 20;
setTimeout(function newchar(){
if (!text) {
$p = $(ps[i++]);
text = $p.text();
$p.empty().show();
}
$p.append(document.createTextNode(text.charAt(0)));
text = text.slice(1);
if (text.length || i < ps.length)
setTimeout(newchar, Math.random()*speed+speed);
}, 3*speed);​
Here's a function that would animate in multiple lines of text, one after the other:
<script type="text/javascript">
$(document).ready(function(){
function animateAddText(id, text, delta) {
var lines = text.split("\n");
var lineCntr = 0;
var target = $("#" + id);
function addLine() {
if (lineCntr < lines.length) {
var nextLine = "";
if (lineCntr != 0) {
nextLine = "<br>";
}
nextLine += lines[lineCntr++];
$("<span>" + nextLine + "</span>").hide().appendTo(target).fadeIn(1000);
setTimeout(addLine, delta);
}
}
addLine();
}
var multilineText = "First line\nSecond Line\nThird Line\nFourth Line\nFifth Line";
animateAddText("middlecolor", multilineText, 1000);
});
</script>
And a working demo: http://jsfiddle.net/jfriend00/Gcg5T/

Categories

Resources