Filter jcarousel content - javascript

I don't know if it's a bug or not, but here's my problem: I filter the jcarousel content using jquery. Everything goes ok until i start to use the next/prev buttons. On the default stage of filtering, buttons are working ok, but after i start to filter the content (images) the jcarousel start to work all crazy. For example, if i have 10 images in default state, showing 3 on stage, after filtering (let's say i have only 4 now) if i get to the last picture, the next button it's still enabled and i can scroll another 10-15px area even there is only blank space.
Images that are removed by the filter are going out by fadeOut animation.
I tried to call the jcarousel after every filtering action but i get the same result. In some cases, after i apply the filter, the prev btn. it's not enabled but i can scroll 100-200px area of blank space.
I tried to solve this issue for the last 3 days but i couldn't find the right solution.
Sorry for my english and thanks :-)
Update:
Here's my code maybe it will help understanding the issue:
$(".anim").jcarousel();
$("#menu ul li").click(function() {
var flt = $('a', this).attr('rel');
$('.anim li').each(function() {
if(!$(this).hasClass(flt)) {
$(this).fadeOut('normal');
} else {
$(this).fadeIn('normal');
}
});
return false;
});
The jCarousel structure (.anim) is:
<ul class="anim">
<li class="flt1"><img ... /></li>
<li class="flt1"><img ... /></li>
<li class="flt1"><img ... /></li>
<li class="flt2"><img ... /></li>
<li class="flt3"><img ... /></li>
</ul>
Where flt1..3 are my filters and the 'rel' value of menu links. The filtering works ok.

You need to explicitly tell jCarousel how many items still remain.
For example, here is an anonymous function that I give to the config of jCarousel
function(carousel, state) {
if (state != 'init') return;
getProperties(function(properties) {
$.each(properties, function(i, property) {
carousel.add(i + 1, getPropertyHtml(property));
});
carousel.size(properties.length);
});
}
Notice how at the end I have to set the size? What you need to do is find a suitable callback in the configuration, and then set the new length of items.

Related

Change elements/classes in/with jquery

I'm new in jQuery and used it right now for a navigation, that slides in and out in mobile or small views. That works fine and correct, but I'm using a plus-icon to open a submenu, that changes into a minus-icon, when the submenu is opened.
But it doesn't change back into the plus-icon, when the submenu is closed.
The code is the following:
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$(this).next('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
});
});
I think the "interesting" part might be the second function, the first is still for a hamburger-icon, that opens the navigation, that works (okay, it doesn't show a sliding animation, what the second one do... no idea, why it don't works...).
So the second part is for the plus. When I click on the plus, the submenu slides in and the plus changes to the minus, but when I click back to the the minus it doesn't change back to the plus.
Has somebody any idea why it doesn't work or can explain me, how I can do it work?
Regards,
Markus
The problem is that your selector is trying to find a span with both plusicon and vertical classes but after the first call to this:
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
wich removes said classes, it is not able to find your target span.
To work around this you could assign an id (iconId on the next example) or another class to your icon so it can be allways found
$('<span class="menu-expander"><span id="iconId" class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
...
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('#iconId').toggleClass('plusicon vertical');
});
Do this :
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
var $icon = $(this).children('#ID OF ELEMENT'); // Would be easier to add an ID to your element whcih you want to alter - limits the error possibilties :)
if($icon.hasClass("CLASS YOU WANT TO GET RID OF"){
$icon.removeClass("CLASS YOU WANT TO GET RID OF");
$icon.addClass("THE CLASS YOU NEED");
else{
$icon.addClass("THE CLASS YOU WANT TO ADD");
}
});
I am at work now so pardon any typing errors.
You basically need to check whether the class that changes the icon to a MINUS symbol is still active - if so you change it back.
I hope it will help.
Points:
to find element good to use find();
better toggle 1 class to show hide element like "show" in example;
With elements inserted with js code better use .on() (for future);
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal">horizontal</span><span class="plusicon vertical show">vertical</span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).find('.plusicon').toggleClass('show');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.plusicon {display:none}
.show {display:block!important}
</style>
<ul>
<li id="menu-toggle" class="level_2">Toggle</li>
</ul>
<ul id="navigation-main">
<li>test</li>
</ul>

How do I generate these jQuery links inside of a <ul> element after the first <li> child element?

Hi, I'm having real trouble trying to solve this problem of mine. Although in my last 6-7 hours of despair I have come up with several viable options to make the problem go away, I haven't by any means been able to figure it out. I am trying to edit some source code (included) to achieve what the Title of this question suggests.
I am using the following jQuery plugin: jQuery Cycle Plugin - Pager Demo with Prev/Next Controls
What I am trying to get this to do with my own markup is generate the links that contain the <a> elements within the <li> elements come after and before the first and last <li> elements contained in the targeted parent element...(<ul>). Here's the plugins configuration:
$(function() {
$('.recent_slider').cycle({
fx: 'scrollHorz',
timeout: 0,
prev: '.slide_l',
next: '.slide_r',
pager: '.slide_nav',
pagerAnchorBuilder: pagerFactory
});
function pagerFactory(idx, slide) {
var s = idx > 4 ? ' style="display:none"' : '';
return '<li'+s+'>'+idx+'</li>';
};
});
Where pager: '.slide_nav', refers to the parent <ul> element, I have this plugin's next and previous controls being used as <li></li> (with slide_l meaning "slide left" / previous) and <li></li> (meaning "slide right" / next).
What I want to be able to do is insert the pager links generated from return <li'+s+'>'+idx+'</li> in between .slide_l and .slide_r so it appears something like:
<ul class="slide_nav">
<li></li>
<li'+s+'>'+idx+'</li>
<li'+s+'>'+idx+'</li>
<li'+s+'>'+idx+'</li>
<li></li>
</ul>
The issue is that is adds them after so in effect I get something along the lines of "previous","next", "slide1", "slide2", "slide 3" where as what I need is "previous","slide1", "slide2", "slide3", "next"...
Here's the plugin's almighty 1500+ lines of source code which together with the above configuration and markup containing the class names: .slide_nav, .slide_l and slide_rwill cause the headache I'm having...
Please help.
Since you want to change how the UI is displayed, and not the structure of the content, CSS would be a better way to solve this.
Change your html to this:
<span class="slide_l">Prev</span>
<ul class="slide_nav"></ul>
<span class="slide_r">Next</span>
And add this CSS (note this is just a starting point, add onto it to make it look nice):
.slide_nav, .slide_nav li, .slide_l, .slide_r {
display: inline-block;
margin: 0;
padding: 0;
}
The CSS makes all the elements flow horizontally (using display: inline-block) to make it similar to a standard paginator.
Fiddle: http://jsfiddle.net/dwx1v9c7/1/
You could also get the html of the .slide_nav and then mess with it as a string.
var x = $('.slide_nav').html();
var arr=x.split('</li>');
var mystr = '';
for (var r=0, len=arr.length; r<len; r++) {
mystr += arr[r];
if (r===0) {
//your code to add additional LI's
}
}
$('.slide_nav').html(mystr)
It's far from the most elegant solution but it should work.

Rotating through divs (hide/fade in) with jQuery

I'm currently in the process of creating a news carousel. On the left panel i have the three titles of each news item, to the right i have an image associated with that news item, and in the bottom right i have three "navigational blocks" for each item.
In my example, when you click a link on the left, it will display the associated content in the larger right hand panel. This also applies for the navigational blocks in the bottom right. If you click one of those, the associated item will be displayed in the larger panel.
The last thing i need to achieve is an auto rotation of these news items. On load, item one will be displayed with "link 1" highlighted, and "block one" of the navigational blocks highlighted. After say, 10 seconds, "link 2" will become highlighted with the "block 2" highlighted and the associated content in the middle being displayed. So on, so forth.
http://codepen.io/anon/pen/wDiGy - Here's a code pen version of it so far.
Code highlighted below:
<div id="title-container">
<ul>
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</div>
<div id="image-container">
<div class="image1 image" itemID="1">1</div>
<div class="image2 image" itemID="2">2</div>
<div class="image3 image" itemID="3">3</div>
<div id="circular-nav">
<li></li>
<li></li>
<li></li>
</div>
jQuery for selecting each item
$('.image:first').show();
$('.title, .circle-title').click(function(){
$('.image').hide();
var itemID = $(this).attr('itemID');
$('.image[itemID="' + itemID + '"]').fadeIn('fast');
});
I will be changing the HTML to integrate into the CMS i'm using, but the class names won't be changing.
Any assistance would be greatly appreciated.
UPDATE: I've managed to get 99% of the way there by fiddling around with it. I now have one hurdle. I'm using .next() to reach each item. If there are three items and it reaches the end, how do you return to the beginning? (PEN Updated)
Use a setInterval to trigger the tile change/image change function for every 10 seconds.
setInterval(function(){
//Code for changing the tile/image
},10000); //Milliseconds
You can put your existing function in a variable and use it for click as well as for interval. Also, since you're passing some information with the click, you can store the ids in an array and increment/reset counter after all the images have been cycled through.
Update:
Working Fiddle!
http://jsfiddle.net/hc4py/ (with only links stylized, not bullets)
setInterval(function () {
var $cur = $('a.active');
var i = $cur.closest('li').index(); //parent 'li' of first active link
$('.image:visible').hide(); //hide visible image
$cur.removeClass('active');
//if active 'a's parent li is the last one
if ($cur.closest('li').is(':last-child')) {
$('.image').eq(0).fadeIn('fast'); //show first image
$cur.closest('ul').find('li:first-child').find('a.title').addClass('active');
}
else {
$('.image').eq(i + 1).fadeIn('fast');//show next image
$cur.closest('li').next().find('a.title').addClass("active");
}
}, 2000);
.title.active{color:red;}
I found a simple solution which just involved an if statement to check the length of the item. Once it ended, it was able to loop around correctly.
setInterval(function () {
if ($('.image:visible').next().length === 0) {
$('.image').hide();
$('.image:first').fadeIn();
} else {
$('.image:visible').hide().next().fadeIn('fast');
}
}, 2000); //Milliseconds

Continuously fade a list of thumbnails on top of each other w/ Jquery (only showing 4 at all times?)

I'm not exactly sure how to tackle this one. I've checked out the jQuery "Cycle" plugin, but haven't seen any exmaples of what I really need.
How would you achieve fading in a list of thumbnails from the HTML (maybe something like:
<ul id="container">
<li class="thumbnail"> <img src="1.jpg"/> </li>
<li class="thumbnail"> <img src="2.jpg"/> </li>
<li class="thumbnail"> <img src="3.jpg"/> </li>
<li class="thumbnail"> <img src="4.jpg"/> </li>
<li class="thumbnail"> <img src="5.jpg"/> </li>
...more
</ul>
I've created a sample .GIF to explain what i'm trying to do:
-There are a total of 4 boxes showing at all times
-Jquery will pull the next image on the list, and fade it into one of the 4 boxes (random box every time). (image will fade in over the last image in the box).
-This should only happen if there are more than 4 images inside the list. (stay static if we only have 4)
-Would like to have the ability to add more images via HTML, not inside the JS...
----UPDATE------
Kalle seems to have the correct solution, the only thing missing is the ability to control how many visible thumbnails you see at all times.
I worked 5 (+ 2, ver 1.1) hours on your question. The biggest problem was the switch between two elements. It turns out, that there isn't any "swapping" function.. So I made an alternative.. You cant make this fading transition any better, but it is fairly close your GIF. If you want just to swap them nice and dirty, without any fade.. then that's very easy to make.
Anyways, I composed into a plugin:
JoeShuffle v1.1
A simple jQuery plugin to shuffle list. Very easy to install and use. Works like any other jQuery plugin. Just add jQuery to your page, include the script with necessary css file. Then, call it to some list and voila! You can change the interval-speed like this: $('#JoeShuffle').JoeShuffle({intervalSpeed: 2000});
As of Ver 1.1 also randomizes the list on the first load and enables to have this script hooked to multiple lists. Also you can set the max. number of displayed elements:
$('#JoeShuffle').JoeShuffle({displayElements: 4});.
JoeShuffle v1.1 [ Download (33.54 KB) - View demo (jsfiddle) ]
JoeShuffle v1.0 [ Download (65.12 KB) - View demo (jsfiddle) ]
NOTES
I'm not sure how crossbrowser it is and also it is very dirty and raw plugin. Surely could use some optimization, however it does work.
My examples use colorful boxes, but it really doesn't matter if there are images or whatever in the li element.
Some features:
Remembers the last slot/position, where the swap was made, and wont use it again. Otherwise it will look kinda a weird
You can set your own custom interval-speed
Shuffles whatever you put between the list tags. However, you should keep all of them in one size
(v1.1) Randomizes all the elements in the ul list on the first load.
(v1.1) Allows you to set the max. number of elements displayed at once
(v1.1) Enables you to have this script hooked to multiple lists at once
Currently it works like this. Whatever you put inside the li elements, it will shuffle them. If you have 5 elements, then it will hide one. And then basically take the hidden element and swap it with some random element. However, I will revisit it in ~15 hours and add the option, that you can set how many are being displayed. So you can actually have 10 elements in the list, but you will only display 4 at the time, there for making the randomization more dynamic.
Rev 1 notes
Since you wanted to randomize them on the first load. Then I added the rand() plugin to this script. This way it makes the first hide() loop very neat and also works as randomizer on the full list..even thought it actually doesn't randomize the list separately..meaning its faster. As I mentioned in the comments inside the scrip, rand() plugin by Alexander Wallin, is a must have in your jQuery collection.
As you can see, you can hook it to multiple lists from now on. That and also adding more elements to the list came up a new problem. That the script was loading slow and all the elements would be shown for few ms, on the first load. I fixed the problem, by adding the scripts includes inside the <head> and not after the contents of the page. This way the scripts get loaded before the elements.. and that means everything is smooth.
Though I have no idea what happens, if the displayElements option is set lower, then the actual elements count inside the list. Best avoid such situations.
Also if you noticed that the elements get floated together in CSS. You could also use display: inline-block;, but inline-block isn't very crossbrowser, so I used float. This however means, that under the elements you should have clear: both; in some form.. Or maybe even some wrapper around the list.
http://jsfiddle.net/MbQrw/
This should cover the basic stuff you're needing. It's not very elegant and stuff like initialization is missing, but the main technique is shown.
http://jsfiddle.net/rkw79/VETmf/
The concept is similar: grab an element in a list, do an action, move onto the next element, and if it is the end; loop back to the beginning.
$('input').click(function (e) {
toggleImg($('div img:first'));
});
function toggleImg(I) {
var nextI = I.next();
if (nextI.length == 0) nextI = $('div img:first');
I.toggle('slow', function() {
toggleImg(nextI);
});
}
Now this doesn't pre-populate the divs with images and it doesn't handle getting the link code in with the images as they display but you can handle that with just a little extra work.
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>
<script>
var maxDisplay = 4;
var displayBox;
$(document).ready(function() {
StartShow();
});
function StartShow() {
var interval = 5000;
var slideShowID;
slideShowID = setInterval(Gallery, interval);
}
function Gallery() {
var nextImage = $("#container li.selected").next().length;
displayBox = Math.floor(Math.random() * maxDisplay);
if (nextImage > 0){
$("#container li.selected").removeClass("selected").next().addClass("selected");
imgSrc = $("#container li.selected").children().attr("src");
if(imgSrc != null) {
$("#" + displayBox).fadeOut('slow', function() { $("#" + displayBox).css("background-image", imgSrc); }).fadeIn();
}
}
else {
$("#container li.selected").removeClass("selected").siblings(':first').addClass("selected");
imgSrc = $("#container li.selected").children().attr("src");
if (imgSrc != null) {
$("#" + displayBox).fadeOut('slow', function() { $("#" + displayBox).css("background-image", imgSrc); }).fadeIn();
}
}
}
</script>
</head>
<body>
<ul id="container" style="display: none;">
<li class="thumbnail selected"> <img src="1.jpg"/> </li>
<li class="thumbnail"> <img src="2.jpg"/> </li>
<li class="thumbnail"> <img src="3.jpg"/> </li>
<li class="thumbnail"> <img src="4.jpg"/> </li>
<li class="thumbnail"> <img src="5.jpg"/> </li>
<li class="thumbnail"> <img src="6.jpg"/> </li>
<li class="thumbnail"> <img src="7.jpg"/> </li>
<li class="thumbnail"> <img src="8.jpg"/> </li>
<li class="thumbnail"> <img src="9.jpg"/> </li>
</ul>
<div>
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
</div>
</body>
</html>
So I have a jsFiddle with much more in the way of settings but i'm only posting the sinmplest part of the code here. I didn't use images just <li> elements with background colours.
var floor = Math.floor;
var random = Math.random;
function randomindex(num, style) {
return floor(random() * num);
};
$.fn.continuousFade = function(options) {
var settings = $.extend({
"max_visible": 4,
"delay": 2000, // in ms.
"speed": 500, // in ms.
"style": "normal"
}, options);
var children = this.children(".thumbnail").css("display", "");
for (var i = 0; i < settings.max_visible; i++) {
children.eq(i).css("display", "inline-block");
}
function fadeone() {
var visibleChild = this.children(".thumbnail:visible").eq(randomindex());
var hiddenChild = this.children(".thumbnail:not(:visible)").first();
var parent = this;
visibleChild.before(hiddenChild);
hiddenChild.css({
"position": "absolute",
"opacity": 0,
"display": "inline-block"
}).animate({
opacity: 1
}, settings.speed, function() {
hiddenChild.css("position", "");
parent.append(visibleChild.css("display", "")); // Need to put this one at the end so it will get displayed again last.
});
setTimeout(function() {
fadeone.call(parent);
}, settings.delay);
}
fadeone.call(this);
};
The jsFiddle has options for other ways of getting a random image and the ability to change the settings and it shows more children.
Current jsfiddle:- http://jsfiddle.net/Nft5a/42/
It's been a while, but maybe this will work for your defining # of images problem:
what I would do involves doing a bit of math, but say I want 4 pictures showing at all times, and they are 50px each with no margin or padding (margins and padding is where the math really comes into play) then I would put them in a div that is 200px wide (4*50) with overflow set to hidden in the html (where your list should be with the images). this is explained a bit more in this question: "http://web.enavu.com/tutorials/making-an-infinite-jquery-carousel/"
hope that helps.

Removing all panels from AnythingSlider and re-starting plugin

I'm using the AnythingSlider to display a mashup of tweets, blog posts, flickr photos, and youtube videos, and initially it works great. I'm trying to add sort functionality, but to do so I need to remove all slides on a button click -> add the new slides -> and re-initialize the plugin.
The AnythingSlider documentation (as well as the code) hints at the ability to remove slides and the plugin should just take it in stride. I haven't been able to find any kind of remove code anywhere, so I fiugured something like this would work:
$("#slider li:not(.cloned)").remove();
but so far i've had no luck. Anyone have any experience with something like this? Many Thanks.
There isn't any built in code to remove slides, so you could use the code above, or if you really want to just remove all the slides, do this (no need to avoid removing the cloned slides):
$('#slider li').remove();
Then add in whatever new slides you want (sorted or whatever)
$('<li>New Stuff</li>').appendTo('#slider');
Then update the slider
$('#slider').anythingSlider(); // don't include options
The above code is essentially the same code as see on the AnythingSlider demo page (the buttons next to the theme selector). I've included it below with more comments :)
// Add a slide
var imageNumber = 1;
$('button.add').click(function(){
$('#slider1')
// add a new slide, but cycle between two images
.append('<li><img src="images/slide-tele-' + (++imageNumber%2 + 1) + '.jpg" alt="" /></li>')
// update the slider
.anythingSlider();
});
$('button.remove').click(function(){
// don't let the last slide get deleted - it's ok if you do delete it, it's just not purdy ;)
if ($('#slider1').data('AnythingSlider').pages > 1) {
// remove the last slide (the cloned slide is actually the last, that's why there is a ":not()" in there
$('#slider1 > li:not(.cloned):last').remove();
// update the slider
$('#slider1').anythingSlider();
}
});

Categories