I am researching and testing with forms. So far, I succeeded in moving items in select box list up and down one by one with following fiddle.
Instance of code (to move up):
function moveUp() {
$("#list-box option:selected").each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == 1) return false;
listItem.insertBefore(listItem.prev());
});
}
But now I need to move a selected value, either to be at extreme top in the list or at very bottom. Please try to experiment up with this fiddle and suggest me possible jQuery tree traversal method if it applies.
Thanks in advance!
Use prependTo and appendTo
function moveTop(){
$('#list-box option:selected').prependTo('#list-box');
}
function moveBottom(){
$('#list-box option:selected').appendTo('#list-box');
}
FIDDLE
To move it to the very top:
var listItem = $(this);
listItem.insertBefore(listItem.siblings().first());
To move it to the very bottom:
var listItem = $(this);
listItem.insertBefore(listItem.siblings().last());
http://jsfiddle.net/mblase75/cYw6R/
http://jsfiddle.net/b7Yct/7/
You need to change your insertBefore and insertAfter statement to insert before the first option and after the last option.
function moveUp() {
$("#list-box option:selected").each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == 1) return false;
listItem.insertBefore($("#list-box option:first"));
});
}
function moveDown() {
var itemsCount = $("#list-box option").length;
$($("#list-box option:selected").get().reverse()).each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == itemsCount) return false;
listItem.insertAfter($("#list-box option:last"));
});
}
Related
The current way is providing invalid output.
This is the object i'm trying to sort through
please check it
$('.childboxes').each(function () {
var divs = $(this);
var divID = $(this).attr('id');
var position = divs.position();
var left = position.left;
var top = position.top;
AllDivsCoor.push({ "id": divID, "leftcoor": left, "topcoor": top });
});
AllDivsCoor.sort('leftcoor');
You've to write a own sort function like this:
function compareCoords(a, b) {
if (a.leftcoor < b.leftcoor) return -1;
if (a.leftcoor > b.leftcoor) return 1;
return 0;
}
AllDivsCoor.sort(compareCoords);
DEMO: JSFiddle
Further informations about sort()
I have an interactive illustration where you can hover over elements and then if you click on them you can see a popover and the clicked element gets black. It works quite good, but there is a problem with the click and hover code. If one clicks on the same element twice in a row and then on another element, the first element gets black. Try for yourself: http://labs.tageswoche.ch/grafik_osze
Here is the code:
var sourceSwap = function () {
var $this = $(this);
if (!$this.hasClass('active')) {
var newSource = $this.data('alt-src');
$this.data('alt-src', $this.attr('src'));
$this.attr('src', newSource);
}
};
var makeActive = function() {
var $this = $(this);
// bring the active back (if any) to the first state
if ($('img.active').length) {
var newSource = $('img.active').data('alt-src');
$('img.active').data('alt-src', $('img.active').attr('src'));
$('img.active').attr('src', newSource);
$('img.active').removeClass('active');
}
$this.toggleClass('active');
}
$(function() {
$('img[data-alt-src]')
.each(function() {
new Image().src = $(this).data('alt-src');
})
.hover(sourceSwap, sourceSwap);
$('img[data-alt-src]').on('click', makeActive);
});
To try for yourself: http://jsfiddle.net/8wtvvka5/
i tried this on fiddle:
function swap(e)
{
var src = e.attr('src');
var active = e.hasClass('active');
var dark = src.indexOf('_h.png', src.length - '_h.png'.length) !== -1;
e.attr('data-src-dark', dark);
if (active || e.attr('data-src-dark') == true) return;
e.attr('src', e.attr('data-alt-src'));
e.attr('data-alt-src', src);
return active;
}
var sourceSwap = function ()
{
if (!$(this).hasClass('active'))
{
swap($(this));
}
};
var makeActive = function()
{
var active = $(this).hasClass('active');
$('img.active').each(function()
{
$(this).removeClass('active'); swap($(this));
});
if (active) $(this).removeClass('active');
else $(this).addClass('active');
swap($(this));
}
$(function() {
$('img[data-alt-src]')
.each(function() {
new Image().src = $(this).data('alt-src');
})
.hover(sourceSwap, sourceSwap);
$('img[data-alt-src]').on('click', makeActive);
});
$('img.active') is a complete set of elements so you should use the 'each' function to handle them all
JUST COPY-AND-PASTE to fiddle to check it out yorself :)
I'm trying to run each animation function one after the other instead of all at once.
This is what I've got so far:
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(){
var widthpercent = $(this).attr("data-percent");
$(this).fadeIn();
$(this).animate({width:widthpercent},500);
});
});
I've tried using .delay() and setTimeout() in various combinations to no avail.
Could anyone point me in the right direction? Thank you!
It sounds to me like you're looking for animate's complete function. You can write a recursive function to keep calling the function in the complete function until all the items have been animated. To simplify: every time one element is animated, a callback is fired that animates the next element. That is the purpose of the complete parameter, so I'm certain that is what you're looking for.
Here's an example you can adapt to your specific needs.
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).animate({height: '30px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}
var current = 0;
animate($divs[current]);
Further, this same logic can be applied to your fadeIn. Just wrap fadeIn's callback around that logic, like this:
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).fadeIn(function() { //now the animation is a callback to the fadeIn
$(element).animate({height: '70px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
});
}
var current = 0;
animate($divs[current]);
And here's your code: live demo here (click).
$(document).ready(function(){
var $divs = $('.bar');
function animate(element) {
$(element).fadeIn(function() { //you could unwrap this depending on what you're looking for
var widthpercent = $(element).attr("data-percent");
$(element).animate({
width:widthpercent,
duration: '500ms'
}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}); //end fadeIn callback
}
var current = 0;
animate($divs[current]);
});
Try this:
var animate = function (el) {
return function () {
var widthpercent = el.data('percent');
el.fadeIn();
el.animate({
width: widthpercent
}, 500);
}
}
var bars = $('.bar');
bars.each(function (index) {
var $this = $(this);
setTimeout(animate($this), index * 500);
});
Fiddle
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(i){
var widthpercent = $(this).attr("data-percent");
$(this).delay(i*800).animate({width:widthpercent,opacity:1,},500);
});
});
This will animate after delaying 800 * i milliseconds.
See this JSFiddle example.
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() { ... }
});
I have a bug in Javascript where I am animating the margin left property of a parent container to show its child divs in a sort of next/previous fashion. Problem is if clicking 'next' at a high frequency the if statement seems to be ignored (i.e. only works if click, wait for animation, then click again) :
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
//roll margin back to 0
}
An example can be seen on jsFiddle - http://jsfiddle.net/ZQg5V/
Any help would be appreciated.
Try the below code which will basically check if the container is being animated just return from the function.
Working demo
$next.click(function (e) {
e.preventDefault();
if($contain.is(":animated")){
return;
}
var marLeft = $contain.css('margin-left'),
$this = $(this);
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
$contain.animate({
marginLeft: 0
}, function () {
$back.fadeOut('fast');
});
} else {
$back.fadeIn(function () {
$contain.animate({
marginLeft: "-=" + regWidth + "px"
});
});
}
if (marLeft > -combinedWidth) {
$contain.animate({
marginLeft: 0
});
}
});
Sometimes is better if you create a function to take care of the animation, instead of writting animation code on every event handler (next, back). Also, users won't have to wait for the animation to finish in order to go the nth page/box.
Maybe this will help you:
if (jQuery) {
var $next = $(".next"),
$back = $(".back"),
$box = $(".box"),
regWidth = $box.width(),
$contain = $(".wrap")
len = $box.length;
var combinedWidth = regWidth*len;
$contain.width(combinedWidth);
var currentBox = 0; // Keeps track of current box
var goTo = function(n) {
$contain.animate({
marginLeft: -n*regWidth
}, {
queue: false, // We don't want animations to queue
duration: 600
});
if (n == 0) $back.fadeOut('fast');
else $back.fadeIn('fast');
currentBox = n;
};
$next.click(function(e) {
e.preventDefault();
var go = currentBox + 1;
if (go >= len) go = 0; // Index based, instead of margin based...
goTo(go);
});
$back.click(function(e) {
e.preventDefault();
var go = currentBox - 1;
if (go <= 0) go = 0; //In case back is pressed while fading...
goTo(go);
});
}
Here's an updated version of your jsFiddle: http://jsfiddle.net/victmo/ZQg5V/5/
Cheers!
Use a variable to track if the animation is taking place. Pseudocode:
var animating = false;
function myAnimation() {
if (animating) return;
animating = true;
$(this).animate({what:'ever'}, function() {
animating = false;
});
}
Crude, but it should give you the idea.
Edit: Your current code works fine for me as well, even if I jam out on the button. On firefox.