Multiple instances of jQuery plugin on same page is not working - javascript

I have searched on this site but did not get what I need.
My issue is that I have created a jquery plugin for carousels, its working fine on 1 instance, but if I created multiple instance its only working on last.
ex:
$('#one').smartCarousel(); // its not working
$('#two').smartCarousel(); // its working
Here is the plugin code:
;(function($){
// default options
var defaults = {
slide : 1,
autoPlay : false,
autoPlayTime : 3000,
speed : 400,
next : false,
prev : false,
reverse : false,
show : 4
}
// function
function sc(el, o){
this.config = $.extend({}, defaults, o);
this.el = el;
this.init();
return this;
}
// set init configurations
sc.prototype.init = function(){
$this = this;
// get children
$this.children = $this.el.children();
// wrape element, add basic css properties
$this.el.wrap('<div class="smartCarouselWrapper clearfix"></div>')
.css({
position: 'absolute',
}).parent().css({
height: $this.el.outerHeight(true), // Height is setting on line 57
width: '100%',
overflow: 'hidden',
position: 'relative'
});
// Show element by config
// Calculate width by deviding wraper width
// Set width of items
$elw = $this.el.parent().width()/$this.config.show;
$this.children.each(function(index, el) {
$(this).width($elw);
});
w = $elw*$this.config.slide; // init width
// get width, hadle diffrent width
$this.children.each(function(index, el) {
w += $(this).outerWidth(true);
});
// set lement width
$this.el.width(w);
// Set height for wrapper
$this.el.parent().height($this.el.outerHeight(true));
// check if next handle assigned
if ($this.config.next != false ) {
$(this.config.next).click(function(e) {
e.preventDefault()
$this.next();
});
};
// check if prev handle assigned
if ($this.config.prev != false ) {
$(this.config.prev).click(function(e) {
e.preventDefault()
$this.prev();
});
};
$this.ready();
} // end of inti
sc.prototype.autoPlay = function(){
// if reverse enabled
if (this.config.reverse != false) { this.prev(); } else { this.next(); };
}
// do stuffs when ready
sc.prototype.ready = function(){
if(this.config.autoPlay != false){
this.timeOut = setTimeout('$this.autoPlay()', this.config.autoPlayTime);
}
}
sc.prototype.next = function(){
$this = this;
clearTimeout($this.timeOut);
l = 0; // left
i = 0; // index
// Add width to l from each element, limiting through slide
$this.children.each(function(index, el) {
if (i < $this.config.slide) {
l -= $(this).outerWidth(true);
//Clone first item after last for smooth animation
$this.el.append($this.children.eq(i).clone());
$this.children = $this.el.children();
};
i++;
});
// animat to show next items and appent prev items to end
$this.el.stop().animate({
left: l},
$this.config.speed, function() {
i = 0; // index
$this.children.each(function(index, el) {
if (i < $this.config.slide) {
$this.children.last().remove();
$this.children = $this.el.children();
};
i++;
});
i = 0;
$this.children.each(function(index, el) {
if (i < $this.config.slide) {
$(this).appendTo($this.el);
$this.el.css('left', parseInt($this.el.css('left'))+$(this).outerWidth(true));
};
i++;
});
$this.children = $this.el.children();
$this.ready();
});
} // end of next
sc.prototype.prev = function(){
$this = this;
clearTimeout($this.timeOut);
l = 0; // left
i = 0; // index
//move last item to first through slide
$this.children.each(function(index, el) {
if (i < $this.config.slide) {
//Clone first item after last for smooth animation
$this.el.prepend($this.children.eq(($this.children.length-1)-i).clone());
l -= $this.children.eq(($this.children.length-1)-i).outerWidth(true);
$this.el.css('left', l);
console.log(1);
};
i++;
});
console.log(l);
$this.children = $this.el.children();
// animate back to 0
$this.el.stop().animate({left: 0}, $this.config.speed, function(){
i = 0;
$this.children.each(function(index, el) {
if (i <= $this.config.slide) {
$this.children.eq($this.children.length-i).remove();
};
i++;
});
$this.children = $this.el.children();
$this.ready();
});
} // end of prev
// plugin
if (typeof $.smartCarousel != 'function') {
$.fn.smartCarousel = function(o){
if (this.length > 0) {
new sc(this.first(), o);
};
return this;
}
}else{
console.log('Function already declared.');
return this;
}
}(jQuery))
Here the html:
<ul class="smart-carousel-list clearfix" id="one">
<li><!-- Image here -->
<h3>Premium Quality DATES</h3>
</li>
<li><!-- Image here -->
<h3>Variety of Export Quality RICE</h3>
</li>
<li><!-- Image here -->
<h3>Sports Goods</h3>
</li>
<li><!-- Image here -->
<h3>Surgical Items</h3>
</li>
<li><!-- Image here -->
<h3>Bad Sheets</h3>
</li>
<li><!-- Image here -->
<h3>Towals</h3>
</li>
<li><!-- Image here -->
<h3>Fruits & Vegetable</h3>
</li>
</ul>
HERE IS THE CSS:
`
.smart-carousel{
width: 100%;
position: relative;
}
.smart-carousel-list{
list-style: none;
margin: 0;
padding: 0;
}
.smart-carousel-list li {
float: left;
-webkit-box-sizing: border-box !important; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box !important; /* Firefox, other Gecko */
box-sizing: border-box !important; /* Opera/IE 8+ */
}
.smart-carousel-nav{
position: absolute;
top: 0;
z-index: 1000;
opacity: 0;
transition: opacity 0.4s;
width: 100%;
}
.smart-carousel:hover .smart-carousel-nav{
opacity: 1;
}
.smart-carousel-nav a{
display: block;
width: 29px;
height: 28px;
text-indent: -999999px;
outline: none;
}
.smart-carousel-nav a.sc_next{
background-image: url('next.png');
margin-right: 10px;
float: right;
}
.smart-carousel-nav a.sc_prev{
background-image: url('prev.png');
margin-left: 10px;
float: left;
}
/**
* STYLE FOR TYPE : Images;
*/
.smart-carousel.type-images .smart-carousel-list li img{
max-width: 100%;
display: block;
margin: 0 auto;
}
/**
* STYLE FOR TYPE : Products;
*/
.smart-carousel.type-products .smart-carousel-list li{
border: solid 1px #efefef;
}
.smart-carousel.type-products .smart-carousel-list li img{
max-width: 100%;
display: block;
margin: 0 auto;
}
.smart-carousel.type-products .smart-carousel-list li h3{
width: 100%;
font-size: 18px;
margin: 0;
padding: 0;
}
.smart-carousel.type-products .smart-carousel-list li h3 a{
display: block;
padding: 10px;
font-weight: bold;
}
.smart-carousel.type-products .smart-carousel-list li h3 a span{
float: right;
font-weight: normal;
}
/**
* STYLE FOR TYPE : Posts;
*/
.smart-carousel.type-posts .smart-carousel-list li{
/*border: solid 1px #efefef;*/
}
.smart-carousel.type-posts .smart-carousel-list li img{
max-width: 100%;
display: block;
margin: 0 auto;
}
.smart-carousel.type-posts .smart-carousel-list li h3{
width: 100%;
font-size: 18px;
margin: 0;
padding: 0;
}
.smart-carousel.type-posts .smart-carousel-list li h3 a{
display: block;
padding: 10px;
font-weight: bold;
text-align: center;
}
.smart-carousel.type-posts .smart-carousel-list li h3 a span{
float: right;
font-weight: normal;
}
`

Your plugin is written to only connect to a single jQuery element at a time. You can improve that like this:
// plugin
if (typeof $.smartCarousel != 'function') {
$.fn.smartCarousel = function (o) {
this.each(function(){
// Connect to each jQuery element
new sc($(this), o);
});
return this;
}
} else {
console.log('Function already declared.');
return this;
}
As for the other problems, you have a single global $this shared all over the place. I added all the missing var $this where required for you and correctly reference it in the timer (via an anonymous function wrapper, so that I can reference the local $this):
JSFiddle: http://jsfiddle.net/TrueBlueAussie/b7u4635x/4/
;
(function ($) {
// default options
var defaults = {
slide: 1,
autoPlay: true,
autoPlayTime: 1000,
speed: 400,
next: false,
prev: false,
reverse: false,
show: 4
}
// function
function sc(el, o) {
this.config = $.extend({}, defaults, o);
this.el = el;
this.init();
return this;
}
// set init configurations
sc.prototype.init = function () {
var $this = this;
// get children
$this.children = $this.el.children();
// wrape element, add basic css properties
$this.el.wrap('<div class="smartCarouselWrapper clearfix"></div>')
.css({
position: 'absolute',
}).parent().css({
height: $this.el.outerHeight(true), // Height is setting on line 57
width: '100%',
overflow: 'hidden',
position: 'relative'
});
// Show element by config
// Calculate width by deviding wraper width
// Set width of items
var $elw = $this.el.parent().width() / $this.config.show;
$this.children.each(function (index, el) {
$(this).width($elw);
});
var w = $elw * $this.config.slide; // init width
// get width, hadle diffrent width
$this.children.each(function (index, el) {
w += $(this).outerWidth(true);
});
// set lement width
$this.el.width(w);
// Set height for wrapper
$this.el.parent().height($this.el.outerHeight(true));
// check if next handle assigned
if ($this.config.next != false) {
$(this.config.next).click(function (e) {
e.preventDefault()
$this.next();
});
};
// check if prev handle assigned
if ($this.config.prev != false) {
$(this.config.prev).click(function (e) {
e.preventDefault()
$this.prev();
});
};
$this.ready();
} // end of inti
sc.prototype.autoPlay = function () {
var $this = this;
// if reverse enabled
if ($this.config.reverse != false) {
$this.prev();
} else {
$this.next();
};
}
// do stuffs when ready
sc.prototype.ready = function () {
var $this = this;
if ($this.config.autoPlay != false) {
$this.timeOut = setTimeout(function(){$this.autoPlay();}, $this.config.autoPlayTime);
}
}
sc.prototype.next = function () {
var $this = this;
clearTimeout($this.timeOut);
var l = 0; // left
var i = 0; // index
// Add width to l from each element, limiting through slide
$this.children.each(function (index, el) {
if (i < $this.config.slide) {
l -= $(this).outerWidth(true);
//Clone first item after last for smooth animation
$this.el.append($this.children.eq(i).clone());
$this.children = $this.el.children();
};
i++;
});
// animat to show next items and appent prev items to end
$this.el.stop().animate({
left: l
},
$this.config.speed, function () {
i = 0; // index
$this.children.each(function (index, el) {
if (i < $this.config.slide) {
$this.children.last().remove();
$this.children = $this.el.children();
};
i++;
});
i = 0;
$this.children.each(function (index, el) {
if (i < $this.config.slide) {
$(this).appendTo($this.el);
$this.el.css('left', parseInt($this.el.css('left')) + $(this).outerWidth(true));
};
i++;
});
$this.children = $this.el.children();
$this.ready();
});
} // end of next
sc.prototype.prev = function () {
var $this = this;
clearTimeout($this.timeOut);
var l = 0; // left
var i = 0; // index
//move last item to first through slide
$this.children.each(function (index, el) {
if (i < $this.config.slide) {
//Clone first item after last for smooth animation
$this.el.prepend($this.children.eq(($this.children.length - 1) - i).clone());
l -= $this.children.eq(($this.children.length - 1) - i).outerWidth(true);
$this.el.css('left', l);
console.log(1);
};
i++;
});
console.log(l);
$this.children = $this.el.children();
// animate back to 0
$this.el.stop().animate({
left: 0
}, $this.config.speed, function () {
i = 0;
$this.children.each(function (index, el) {
if (i <= $this.config.slide) {
$this.children.eq($this.children.length - i).remove();
};
i++;
});
$this.children = $this.el.children();
$this.ready();
});
} // end of prev
// plugin
if (typeof $.smartCarousel != 'function') {
$.fn.smartCarousel = function (o) {
this.each(function () {
new sc($(this), o);
});
return this;
}
} else {
console.log('Function already declared.');
return this;
}
}(jQuery));
//$('.smart-carousel-list').smartCarousel();
$('#one').smartCarousel();
$('#two').smartCarousel();

You have a global variable in your plugin, thus making it impossible for the plugin to work with more than one element because each call to the plugin will overwrite the $this for the previous instance to target the new element.
you simply need to add var in each location where it is missing.
var $this = this;
This will of course break any other place where you attempted to use a global $this (such as the setTimeout('$this.autoplay()',200), so you will need to re-write that portion of the code to not execute autoplay() in that way.

Related

Pre selecting checkboxes based on array content

I've got a multi select dropdown that displays a selection of countries. I want to have some of these preselected based on the content of an array.
Based on a similar question here How can I check checkboxes based on values? I tried using
var arrayValues = (246,247,248,249,250,251,252,253,254,255,256,257,258,259,261,262,263,265,266,267,268,270,271,272,273,274,275);
var i = 0;
while (arrayValues.length < i) {
var val = arrayValues[i];
$('#restrictCountry input[value="' + val + '"]').prop('checked', 'checked');
i++;
}
but it isn't pre selecting the checkboxes with the values shown in the array.
I've set up a fiddle so you can see how my multi select dropdown works. The pre select script is at the bottom of the javascript pane.
What have I done wrong here?
First you'are mistaken in the array syntax ,
also the loop condition is also falsy ,
and finnaly the selector you made couldn't reach newly created multi select wrapper ,
What I suggest ( a bit tricky ) is to rectify selector , then trigger a click on the check input foreach value ,( this will check the select hidden and genrated wrapper input same time )
while (i < arrayValues.length) {
var val = arrayValues[i];
$('#restrictCountry').next(".ms-options-wrap").find(` input[value=${val}]`).not(":checked").click();
i++;
}
check below snippet :
(function($) {
var defaults = {
placeholder: 'Select options', // text to use in dummy input
columns: 1, // how many columns should be use to show options
search: false, // include option search box
// search filter options
searchOptions: {
'default': 'Search', // search input placeholder text
showOptGroups: false, // show option group titles if no options remaining
onSearch: function(element) {} // fires on keyup before search on options happens
},
selectAll: false, // add select all option
selectGroup: false, // select entire optgroup
minHeight: 200, // minimum height of option overlay
maxHeight: null, // maximum height of option overlay
showCheckbox: true, // display the checkbox to the user
jqActualOpts: {}, // options for jquery.actual
// Callbacks
onLoad: function(element) { // fires at end of list initialization
$(element).hide();
},
onOptionClick: function(element, option) {}, // fires when an option is clicked
// #NOTE: these are for future development
maxWidth: null, // maximum width of option overlay (or selector)
minSelect: false, // minimum number of items that can be selected
maxSelect: false, // maximum number of items that can be selected
};
var msCounter = 1;
function MultiSelect(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this.load();
}
MultiSelect.prototype = {
/* LOAD CUSTOM MULTISELECT DOM/ACTIONS */
load: function() {
var instance = this;
// make sure this is a select list and not loaded
if ((instance.element.nodeName != 'SELECT') || $(instance.element).hasClass('jqmsLoaded')) {
return true;
}
// sanity check so we don't double load on a select element
$(instance.element).addClass('jqmsLoaded');
// add option container
$(instance.element).after('<div class="ms-options-wrap"><button>None Selected</button><div class="ms-options"><ul></ul></div></div>');
var placeholder = $(instance.element).next('.ms-options-wrap').find('> button:first-child');
var optionsWrap = $(instance.element).next('.ms-options-wrap').find('> .ms-options');
var optionsList = optionsWrap.find('> ul');
var hasOptGroup = $(instance.element).find('optgroup').length ? true : false;
var maxWidth = null;
if (typeof instance.options.width == 'number') {
optionsWrap.parent().css('position', 'relative');
maxWidth = instance.options.width;
} else if (typeof instance.options.width == 'string') {
$(instance.options.width).css('position', 'relative');
maxWidth = '100%';
} else {
optionsWrap.parent().css('position', 'relative');
}
var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
if (instance.options.maxHeight) {
maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxheight;
}
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxHeight;
optionsWrap.css({
maxWidth: maxWidth,
minHeight: instance.options.minHeight,
maxHeight: maxHeight,
overflow: 'auto'
}).hide();
// isolate options scroll
// #source: https://github.com/nobleclem/jQuery-IsolatedScroll
optionsWrap.bind('touchmove mousewheel DOMMouseScroll', function(e) {
if (($(this).outerHeight() < $(this)[0].scrollHeight)) {
var e0 = e.originalEvent,
delta = e0.wheelDelta || -e0.detail;
if (($(this).outerHeight() + $(this)[0].scrollTop) > $(this)[0].scrollHeight) {
e.preventDefault();
this.scrollTop += (delta < 0 ? 1 : -1);
}
}
});
// hide options menus if click happens off of the list placeholder button
$(document).off('click.ms-hideopts').on('click.ms-hideopts', function(event) {
if (!$(event.target).closest('.ms-options-wrap').length) {
$('.ms-options-wrap > .ms-options:visible').hide();
}
});
// disable button action
placeholder.bind('mousedown', function(event) {
// ignore if its not a left click
if (event.which != 1) {
return true;
}
// hide other menus before showing this one
$('.ms-options-wrap > .ms-options:visible').each(function() {
if ($(this).parent().prev()[0] != optionsWrap.parent().prev()[0]) {
$(this).hide();
}
});
// show/hide options
optionsWrap.toggle();
// recalculate height
if (optionsWrap.is(':visible')) {
optionsWrap.css('maxHeight', '');
var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
if (instance.options.maxHeight) {
maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxheight;
}
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxHeight;
optionsWrap.css('maxHeight', maxHeight);
}
}).click(function(event) {
event.preventDefault();
});
// add placeholder copy
if (instance.options.placeholder) {
placeholder.text(instance.options.placeholder);
}
// add search box
if (instance.options.search) {
optionsList.before('<div class="ms-search"><input type="text" value="" placeholder="' + instance.options.searchOptions['default'] + '" /></div>');
var search = optionsWrap.find('.ms-search input');
search.on('keyup', function() {
// ignore keystrokes that don't make a difference
if ($(this).data('lastsearch') == $(this).val()) {
return true;
}
$(this).data('lastsearch', $(this).val());
// USER CALLBACK
if (typeof instance.options.searchOptions.onSearch == 'function') {
instance.options.searchOptions.onSearch(instance.element);
}
// search non optgroup li's
optionsList.find('li:not(.optgroup)').each(function() {
var optText = $(this).text();
// show option if string exists
if (optText.toLowerCase().indexOf(search.val().toLowerCase()) > -1) {
$(this).show();
}
// don't hide selected items
else if (!$(this).hasClass('selected')) {
$(this).hide();
}
// hide / show optgroups depending on if options within it are visible
if (!instance.options.searchOptions.showOptGroups && $(this).closest('li.optgroup')) {
$(this).closest('li.optgroup').show();
if ($(this).closest('li.optgroup').find('li:visible').length) {
$(this).closest('li.optgroup').show();
} else {
$(this).closest('li.optgroup').hide();
}
}
});
});
}
// add global select all options
if (instance.options.selectAll) {
optionsList.before('Select all');
}
// handle select all option
optionsWrap.on('click', '.ms-selectall', function(event) {
event.preventDefault();
if ($(this).hasClass('global')) {
// check if any selected if so then select them
if (optionsList.find('li:not(.optgroup)').filter(':not(.selected)').length) {
optionsList.find('li:not(.optgroup)').filter(':not(.selected)').find('input[type="checkbox"]').trigger('click');
}
// deselect everything
else {
optionsList.find('li:not(.optgroup).selected input[type="checkbox"]').trigger('click');
}
} else if ($(this).closest('li').hasClass('optgroup')) {
var optgroup = $(this).closest('li.optgroup');
// check if any selected if so then select them
if (optgroup.find('li:not(.selected)').length) {
optgroup.find('li:not(.selected) input[type="checkbox"]').trigger('click');
}
// deselect everything
else {
optgroup.find('li.selected input[type="checkbox"]').trigger('click');
}
}
});
// add options to wrapper
var options = [];
$(instance.element).children().each(function() {
if (this.nodeName == 'OPTGROUP') {
var groupOptions = [];
$(this).children('option').each(function() {
groupOptions[$(this).val()] = {
name: $(this).text(),
value: $(this).val(),
checked: $(this).prop('selected')
};
});
options.push({
label: $(this).attr('label'),
options: groupOptions
});
} else if (this.nodeName == 'OPTION') {
options.push({
name: $(this).text(),
value: $(this).val(),
checked: $(this).prop('selected')
});
} else {
// bad option
return true;
}
});
instance.loadOptions(options);
// COLUMNIZE
if (hasOptGroup) {
// float non grouped options
optionsList.find('> li:not(.optgroup)').css({
float: 'left',
width: (100 / instance.options.columns) + '%'
});
// add CSS3 column styles
optionsList.find('li.optgroup').css({
clear: 'both'
}).find('> ul').css({
'column-count': instance.options.columns,
'column-gap': 0,
'-webkit-column-count': instance.options.columns,
'-webkit-column-gap': 0,
'-moz-column-count': instance.options.columns,
'-moz-column-gap': 0
});
// for crappy IE versions float grouped options
if (this._ieVersion() && (this._ieVersion() < 10)) {
optionsList.find('li.optgroup > ul > li').css({
float: 'left',
width: (100 / instance.options.columns) + '%'
});
}
} else {
// add CSS3 column styles
optionsList.css({
'column-count': instance.options.columns,
'column-gap': 0,
'-webkit-column-count': instance.options.columns,
'-webkit-column-gap': 0,
'-moz-column-count': instance.options.columns,
'-moz-column-gap': 0
});
// for crappy IE versions float grouped options
if (this._ieVersion() && (this._ieVersion() < 10)) {
optionsList.find('> li').css({
float: 'left',
width: (100 / instance.options.columns) + '%'
});
}
}
// BIND SELECT ACTION
optionsWrap.on('click', 'input[type="checkbox"]', function() {
$(this).closest('li').toggleClass('selected');
var select = optionsWrap.parent().prev();
// toggle clicked option
select.find('option[value="' + $(this).val() + '"]').prop(
'selected', $(this).is(':checked')
).closest('select').trigger('change');
if (typeof instance.options.onOptionClick == 'function') {
instance.options.onOptionClick();
}
instance._updatePlaceholderText();
});
// hide native select list
if (typeof instance.options.onLoad === 'function') {
instance.options.onLoad(instance.element);
} else {
$(instance.element).hide();
}
},
/* LOAD SELECT OPTIONS */
loadOptions: function(options, overwrite) {
overwrite = (typeof overwrite == 'boolean') ? overwrite : true;
var instance = this;
var optionsList = $(instance.element).next('.ms-options-wrap').find('> .ms-options > ul');
if (overwrite) {
optionsList.find('> li').remove();
}
for (var key in options) {
var thisOption = options[key];
var container = $('<li></li>');
// optgroup
if (thisOption.hasOwnProperty('options')) {
container.addClass('optgroup');
container.append('<span class="label">' + thisOption.label + '</span>');
container.find('> .label').css({
clear: 'both'
});
if (instance.options.selectGroup) {
container.append('Select all')
}
container.append('<ul></ul>');
for (var gKey in thisOption.options) {
var thisGOption = thisOption.options[gKey];
var gContainer = $('<li></li>').addClass('ms-reflow');
instance._addOption(gContainer, thisGOption);
container.find('> ul').append(gContainer);
}
}
// option
else if (thisOption.hasOwnProperty('value')) {
container.addClass('ms-reflow')
instance._addOption(container, thisOption);
}
optionsList.append(container);
}
optionsList.find('.ms-reflow input[type="checkbox"]').each(function(idx) {
if ($(this).css('display').match(/block$/)) {
var checkboxWidth = $(this).outerWidth();
checkboxWidth = checkboxWidth ? checkboxWidth : 15;
$(this).closest('label').css(
'padding-left',
(parseInt($(this).closest('label').css('padding-left')) * 2) + checkboxWidth
);
$(this).closest('.ms-reflow').removeClass('ms-reflow');
}
});
instance._updatePlaceholderText();
},
/* RESET THE DOM */
unload: function() {
$(this.element).next('.ms-options-wrap').remove();
$(this.element).show(function() {
$(this).css('display', '').removeClass('jqmsLoaded');
});
},
/* RELOAD JQ MULTISELECT LIST */
reload: function() {
// remove existing options
$(this.element).next('.ms-options-wrap').remove();
$(this.element).removeClass('jqmsLoaded');
// load element
this.load();
},
/** PRIVATE FUNCTIONS **/
// update selected placeholder text
_updatePlaceholderText: function() {
var instance = this;
var placeholder = $(instance.element).next('.ms-options-wrap').find('> button:first-child');
var optionsWrap = $(instance.element).next('.ms-options-wrap').find('> .ms-options');
var select = optionsWrap.parent().prev();
// get selected options
var selOpts = [];
select.find('option:selected').each(function() {
selOpts.push($(this).text());
});
// UPDATE PLACEHOLDER TEXT WITH OPTIONS SELECTED
placeholder.text(selOpts.join(', '));
var copy = placeholder.clone().css({
display: 'inline',
width: 'auto',
visibility: 'hidden'
}).appendTo(optionsWrap.parent());
// if the jquery.actual plugin is loaded use it to get the widths
var copyWidth = (typeof $.fn.actual !== 'undefined') ? copy.actual('width', instance.options.jqActualOpts) : copy.width();
var placeWidth = (typeof $.fn.actual !== 'undefined') ? placeholder.actual('width', instance.options.jqActualOpts) : placeholder.width();
// if copy is larger than button width use "# selected"
if (copyWidth > placeWidth) {
placeholder.text(selOpts.length + ' selected');
}
// if options selected then use those
else if (selOpts.length) {
placeholder.text(selOpts.join(', '));
}
// replace placeholder text
else {
placeholder.text(instance.options.placeholder);
}
// remove dummy element
copy.remove();
},
// Add option to the custom dom list
_addOption: function(container, option) {
container.text(option.name);
container.prepend(
$('<input type="checkbox" value="" title="" />')
.val(option.value)
.attr('title', option.name)
.attr('id', 'ms-opt-' + msCounter)
);
if (option.checked) {
container.addClass('default');
container.addClass('selected');
container.find('input[type="checkbox"]').prop('checked', true);
}
var label = $('<label></label>').attr('for', 'ms-opt-' + msCounter);
container.wrapInner(label);
if (!this.options.showCheckbox) {
container.find('input[id="ms-opt-' + msCounter + '"]').hide();
}
msCounter = msCounter + 1;
},
// check ie version
_ieVersion: function() {
var myNav = navigator.userAgent.toLowerCase();
return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
}
};
// ENABLE JQUERY PLUGIN FUNCTION
$.fn.multiselect = function(options) {
var args = arguments;
var ret;
// menuize each list
if ((options === undefined) || (typeof options === 'object')) {
return this.each(function() {
if (!$.data(this, 'plugin_multiselect')) {
$.data(this, 'plugin_multiselect', new MultiSelect(this, options));
}
});
} else if ((typeof options === 'string') && (options[0] !== '_') && (options !== 'init')) {
this.each(function() {
var instance = $.data(this, 'plugin_multiselect');
if (instance instanceof MultiSelect && typeof instance[options] === 'function') {
ret = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
}
// special destruct handler
if (options === 'unload') {
$.data(this, 'plugin_multiselect', null);
}
});
return ret;
}
};
}(jQuery));
$('#restrictCountry').multiselect({
columns: 4,
placeholder: 'Select Restricted Countries',
search: true,
selectAll: true
});
$(function() {
var arrayValues = [246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 261, 262, 263, 265, 266, 267, 268, 270, 271, 272, 273, 274, 275];
var i = 0;
while (i < arrayValues.length) {
var val = arrayValues[i];
$('#restrictCountry').next(".ms-options-wrap").find(` input[value=${val}]`).not(":checked").click();
i++;
}
})
.ms-options-wrap,
.ms-options-wrap * {
box-sizing: border-box;
list-style-type: none;
}
.ms-options-wrap>button:focus,
.ms-options-wrap>button {
position: relative;
width: 100%;
text-align: left;
border: 1px solid #aaa;
background-color: #fff;
padding: 5px 20px 5px 5px;
margin-top: 1px;
font-size: 13px;
color: #aaa;
outline: none;
white-space: nowrap;
}
.ms-options-wrap>button:after {
content: ' ';
height: 0;
position: absolute;
top: 50%;
right: 5px;
width: 0;
border: 6px solid rgba(0, 0, 0, 0);
border-top-color: #999;
margin-top: -3px;
}
.ms-options-wrap>.ms-options {
position: absolute;
left: 0;
width: 100%;
margin-top: 1px;
margin-bottom: 20px;
background: white;
z-index: 2000;
border: 1px solid #aaa;
text-align: left;
}
.ms-options-wrap>.ms-options>.ms-search input {
width: 100%;
padding: 4px 5px;
border: none;
border-bottom: 1px groove;
outline: none;
}
.ms-options-wrap>.ms-options .ms-selectall {
display: inline-block;
font-size: .9em;
text-transform: lowercase;
text-decoration: none;
}
.ms-options-wrap>.ms-options .ms-selectall:hover {
text-decoration: underline;
}
.ms-options-wrap>.ms-options>.ms-selectall.global {
margin: 4px 5px;
}
.ms-options-wrap>.ms-options>ul>li.optgroup {
padding: 5px;
}
.ms-options-wrap>.ms-options>ul>li.optgroup+li.optgroup {
border-top: 1px solid #aaa;
}
.ms-options-wrap>.ms-options>ul>li.optgroup .label {
display: block;
padding: 5px 0 0 0;
font-weight: bold;
}
.ms-options-wrap>.ms-options>ul label {
position: relative;
display: inline-block;
width: 100%;
padding: 8px 4px;
margin: 1px 0;
}
.ms-options-wrap>.ms-options>ul li.selected label,
.ms-options-wrap>.ms-options>ul label:hover {
background-color: #efefef;
}
.ms-options-wrap>.ms-options>ul input[type="checkbox"] {
margin-right: 5px;
position: absolute;
left: 4px;
top: 7px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
<p class="col-sm-3 control-label">Restricted Countries:</p>
<div class="col-sm-9 col-md-6">
<select rel="dropdown" name="restrictCountry[]" multiple id="restrictCountry">
<option value="253">Austria</option>
<option value="252">Belgium</option>
<option value="266">Bulgaria</option>
<option value="270">Croatia</option>
<option value="274">Czech Republic</option>
<option value="254">Denmark</option>
<option value="262">Estonia</option>
<option value="258">Finland</option>
<option value="247">France</option>
<option value="248">Germany</option>
<option value="260">Gibraltar</option>
<option value="265">Greece</option>
<option value="243">Guernsey</option>
<option value="267">Hungary</option>
<option value="264">Iceland</option>
<option value="246">Ireland</option>
<option value="244">Isle of Man</option>
<option value="255">Italy</option>
<option value="245">Jersey</option>
<option value="263">Latvia</option>
<option value="259">Lithuania</option>
<option value="275">Luxembourg</option>
<option value="273">Malta</option>
<option value="242">Montenegro</option>
<option value="249">Netherlands</option>
<option value="268">Norway</option>
<option value="241">Palestine, State of</option>
<option value="250">Poland</option>
<option value="261">Portugal</option>
<option value="272">Romania</option>
<option value="277">Serbia</option>
<option value="271">Slovakia</option>
<option value="256">Slovenia</option>
<option value="251">Spain</option>
<option value="257">Sweden</option>
<option value="269">Switzerland</option>
<option value="276">Turkey</option>
</select>
</div>
</div>
fix your lines:
var arrayValues = [246,247,248,249,250,251,252,253,254,255,256,257,258,259,261,262,263,265,266,267,268,270,271,272,273,274,275];
var i = 0;
while (arrayValues.length > i) {
var val = arrayValues[i];
$('li input[value=' + val + ']').prop('checked', true);
i++;
}
the problem is comming the fact the dropdown is built from the options defined..If you see the picture, you cant access to input from the id of select tag.

jQuery - Image replacement transition [issues in Safari]

Okay I have the following code:-
[SEE JSFIDDLE]
HTML:
<div id="header">
<span class="mobile-menu"></span>
</div>
CSS:
#header {
width: 100%;
background: #000000;
height: 100px;
}
.mobile-menu {
position: absolute;
right: 25px;
top: 20px;
background: url(http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-01.png);
background-repeat: no-repeat;
background-size: 26px !important;
height: 26px;
width: 26px;
display: inline-block;
margin: 7px 0;
-webkit-transition-duration: 0.8s;
-moz-transition-duration: 0.8s;
-o-transition-duration: 0.8s;
transition-duration: 0.8s;
}
.mobile-menu-hover {
background: url(http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/mobile-menu-hover.png);
}
jQuery:
var imagesArray = ["http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-01.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-02.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-03.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-04.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-05.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-06.png",
"http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-07.png"];
function preloadImg(pictureUrls, callback) {
var i, j, loaded = 0;
var imagesArray = [];
for (i = 0, j = pictureUrls.length; i < j; i++) {
imagesArray.push(new Image());
}
for (i = 0, j = pictureUrls.length; i < j; i++) {
(function (img, src) {
img.onload = function () {
if (++loaded == pictureUrls.length && callback) {
callback(imagesArray);
}
};
img.src = src;
}(imagesArray[i], pictureUrls[i]));
}
};
function changeImage(background, imagesArray, index, reverse) {
background.css("background-image", "url('" + imagesArray[index].src + "')").fadeIn(10, function() {
if (reverse) {
index--;
if (index == -1) {
return; // stop the interval
}
} else {
index++;
if (index == imagesArray.length) {
return; // stop the interval
}
}
//Fade in the top element
background.fadeOut(10, function () {
//Set the background of the top element to the new background
background.css("background-image", "url('" + imagesArray[index] + "')");
changeImage(background, imagesArray, index, reverse);
});
});
}
jQuery(function () {
/* Preload Image */
preloadImg(imagesArray, function (imagesArray) {
jQuery(".mobile-menu").css("background-image", "url('" + imagesArray[0].src + "')")
jQuery('.mobile-menu').on('click', {imgs: imagesArray}, function (event) {
var background = jQuery(".mobile-menu");
var bi = background.css('background-image');
var index = 0;
var reverse = false;
if (imagesArray[0].src != bi.replace('url("', '').replace('")', '')) {
index = imagesArray.length - 1;
reverse = true;
}
changeImage(background, event.data.imgs, index, reverse);
});
});
});
The Issue:
This works fine in Firefox and Chrome, it transitions between the 7 different images on click, then does the reverse on the second click (toggling).
The problem is when I try this in Safari, it basically goes through the image replacement process then reverts back to the first image for some reason and I can't figure out why?
Any ideas?
It seems to be because Safari returns the background-image without double quotes, but your replace function checks for url(", so it doesn't replace and reverse never gets true.
Instead of replacing you can check using either indexOf or matching using a RegExp, it would be safer and more straightforward. Either:
if ( bi.indexOf(imagesArray[0].src) == -1) {
or
if (imagesArray[0].src != bi.match(/http.+png/)[0]) {
With indexOf: http://jsfiddle.net/u9ske14r/

Slider with rslides rezising itself due to different size images

When trying use the, otherwise brilliant, rslides js plugin I bump into this annoying problem. I want the images to be imported to the site via links which means I can't resize them but the slider handles this rather poorly; it expands. Now, the slider is responsive, it scales with the page width. One solution might be to set static values for the size but I would prefer not doing this as it would probably break the responsive %scaling.
Edit: forgot to link site http://208.69.30.150/build/age_past.html
Some clarification that's come up in the comments:
The images are resized within the slider. But the slider is resizing to some of the images sizes, only on the height, this is because the images do not all have the same aspect ratios. So I want to resize the images width, and if the height overflows I want to crop of that overflow.
CSS
/*SLIDER*/
.slider{
background-color: #222;
}
.rslides_container {
position: relative;
margin: 50px auto;
width: 100%;
background: #222;
}
.slider .slider_medium{
max-width: 900px;
}
.rslides {
border-radius:200px;
-moz-border-radius:20px;
-webkit-border-radius:20px;
position: relative;
list-style: none;
overflow: hidden;
width: 100%;
padding: 0;
margin: 0 auto;
}
.rslides li {
-webkit-backface-visibility: hidden;
position: absolute;
display: none;
width: 100%;
left: 0;
top: 0;
}
.rslides li:first-child {
position: relative;
display: block;
float: left;
}
.rslides img {
display: block;
height: auto;
float: left;
width: 100%;
border: 0;
}
/*SLIDER OVERLAY IMAGES*/
#banner_image_1 img{
position: absolute;
z-index: 5;
top: 10%;
left: 3%;
height:auto;
width:auto;
max-height: 100px;
background: #FFF;
}
#banner_image_2 img{
position: absolute;
z-index: 5;
bottom: 3%;
right: 1%;
height: 20%;
max-height:60px;
}
#banner_image_3 img{
position: absolute;
z-index: 5;
bottom: 3%;
right: 7%;
height: 20%;
max-height:60px;
}
HTML
<div class="block slider">
<div class="rslides_container slider_medium">
<!--<a id="banner_image_1" href="" target="">
<img src="">
</a>-->
<ul class="rslides">
<li>
<a href="http://www.agepast.com/">
<img src="http://fc00.deviantart.net/fs70/i/2010/194/2/5/Age_Past_Wallpaper_by_Tsabo6.jpg"/>
</a>
</li>
<li>
<a href="http://www.agepast.com/">
<img src="http://fc03.deviantart.net/fs71/i/2011/211/c/6/age_past_by_tsabo6-d424m3v.jpg"/>
</a>
</li>
<li>
<a href="http://www.agepast.com/">
<img src="http://fc00.deviantart.net/fs70/i/2010/257/7/e/age_past_earth_magic_by_tsabo6-d2yp0v0.jpg"/>
</a>
</li>
<li>
<a href="http://www.agepast.com/">
<img src="http://fc01.deviantart.net/fs71/i/2010/244/8/2/age_past_wall_2_by_tsabo6-d2xr9g0.jpg"/>
</a>
</li>
</ul>
</div>
<script>
$(function() {
$(".rslides").responsiveSlides({
auto: true, speed: 1500, timeout: 5000, pause: true,
});
});
</script>
</div>
& LOTS of JS (which just won't be formatted right.)
(function ($, window, i) {
$.fn.responsiveSlides = function (options) {
// Default settings
var settings = $.extend({
"auto": true, // Boolean: Animate automatically, true or false
"speed": 500, // Integer: Speed of the transition, in milliseconds
"timeout": 4000, // Integer: Time between slide transitions, in milliseconds
"pager": false, // Boolean: Show pager, true or false
"nav": false, // Boolean: Show navigation, true or false
"random": false, // Boolean: Randomize the order of the slides, true or false
"pause": false, // Boolean: Pause on hover, true or false
"pauseControls": true, // Boolean: Pause when hovering controls, true or false
"prevText": "Previous", // String: Text for the "previous" button
"nextText": "Next", // String: Text for the "next" button
"maxwidth": "", // Integer: Max-width of the slideshow, in pixels
"navContainer": "", // Selector: Where auto generated controls should be appended to, default is after the <ul>
"manualControls": "", // Selector: Declare custom pager navigation
"namespace": "rslides", // String: change the default namespace used
"before": $.noop, // Function: Before callback
"after": $.noop // Function: After callback
}, options);
return this.each(function () {
// Index for namespacing
i++;
var $this = $(this),
// Local variables
vendor,
selectTab,
startCycle,
restartCycle,
rotate,
$tabs,
// Helpers
index = 0,
$slide = $this.children(),
length = $slide.size(),
fadeTime = parseFloat(settings.speed),
waitTime = parseFloat(settings.timeout),
maxw = parseFloat(settings.maxwidth),
// Namespacing
namespace = settings.namespace,
namespaceIdx = namespace + i,
// Classes
navClass = namespace + "_nav " + namespaceIdx + "_nav",
activeClass = namespace + "_here",
visibleClass = namespaceIdx + "_on",
slideClassPrefix = namespaceIdx + "_s",
// Pager
$pager = $("<ul class='" + namespace + "_tabs " + namespaceIdx + "_tabs' />"),
// Styles for visible and hidden slides
visible = {"float": "left", "position": "relative", "opacity": 1, "zIndex": 2},
hidden = {"float": "none", "position": "absolute", "opacity": 0, "zIndex": 1},
// Detect transition support
supportsTransitions = (function () {
var docBody = document.body || document.documentElement;
var styles = docBody.style;
var prop = "transition";
if (typeof styles[prop] === "string") {
return true;
}
// Tests for vendor specific prop
vendor = ["Moz", "Webkit", "Khtml", "O", "ms"];
prop = prop.charAt(0).toUpperCase() + prop.substr(1);
var i;
for (i = 0; i < vendor.length; i++) {
if (typeof styles[vendor[i] + prop] === "string") {
return true;
}
}
return false;
})(),
// Fading animation
slideTo = function (idx) {
settings.before(idx);
// If CSS3 transitions are supported
if (supportsTransitions) {
$slide
.removeClass(visibleClass)
.css(hidden)
.eq(idx)
.addClass(visibleClass)
.css(visible);
index = idx;
setTimeout(function () {
settings.after(idx);
}, fadeTime);
// If not, use jQuery fallback
} else {
$slide
.stop()
.fadeOut(fadeTime, function () {
$(this)
.removeClass(visibleClass)
.css(hidden)
.css("opacity", 1);
})
.eq(idx)
.fadeIn(fadeTime, function () {
$(this)
.addClass(visibleClass)
.css(visible);
settings.after(idx);
index = idx;
});
}
};
// Random order
if (settings.random) {
$slide.sort(function () {
return (Math.round(Math.random()) - 0.5);
});
$this
.empty()
.append($slide);
}
// Add ID's to each slide
$slide.each(function (i) {
this.id = slideClassPrefix + i;
});
// Add max-width and classes
$this.addClass(namespace + " " + namespaceIdx);
if (options && options.maxwidth) {
$this.css("max-width", maxw);
}
// Hide all slides, then show first one
$slide
.hide()
.css(hidden)
.eq(0)
.addClass(visibleClass)
.css(visible)
.show();
// CSS transitions
if (supportsTransitions) {
$slide
.show()
.css({
// -ms prefix isn't needed as IE10 uses prefix free version
"-webkit-transition": "opacity " + fadeTime + "ms ease-in-out",
"-moz-transition": "opacity " + fadeTime + "ms ease-in-out",
"-o-transition": "opacity " + fadeTime + "ms ease-in-out",
"transition": "opacity " + fadeTime + "ms ease-in-out"
});
}
// Only run if there's more than one slide
if ($slide.size() > 1) {
// Make sure the timeout is at least 100ms longer than the fade
if (waitTime < fadeTime + 100) {
return;
}
// Pager
if (settings.pager && !settings.manualControls) {
var tabMarkup = [];
$slide.each(function (i) {
var n = i + 1;
tabMarkup +=
"<li>" +
"<a href='#' class='" + slideClassPrefix + n + "'>" + n + "</a>" +
"</li>";
});
$pager.append(tabMarkup);
// Inject pager
if (options.navContainer) {
$(settings.navContainer).append($pager);
} else {
$this.after($pager);
}
}
// Manual pager controls
if (settings.manualControls) {
$pager = $(settings.manualControls);
$pager.addClass(namespace + "_tabs " + namespaceIdx + "_tabs");
}
// Add pager slide class prefixes
if (settings.pager || settings.manualControls) {
$pager.find('li').each(function (i) {
$(this).addClass(slideClassPrefix + (i + 1));
});
}
// If we have a pager, we need to set up the selectTab function
if (settings.pager || settings.manualControls) {
$tabs = $pager.find('a');
// Select pager item
selectTab = function (idx) {
$tabs
.closest("li")
.removeClass(activeClass)
.eq(idx)
.addClass(activeClass);
};
}
// Auto cycle
if (settings.auto) {
startCycle = function () {
rotate = setInterval(function () {
// Clear the event queue
$slide.stop(true, true);
var idx = index + 1 < length ? index + 1 : 0;
// Remove active state and set new if pager is set
if (settings.pager || settings.manualControls) {
selectTab(idx);
}
slideTo(idx);
}, waitTime);
};
// Init cycle
startCycle();
}
// Restarting cycle
restartCycle = function () {
if (settings.auto) {
// Stop
clearInterval(rotate);
// Restart
startCycle();
}
};
// Pause on hover
if (settings.pause) {
$this.hover(function () {
clearInterval(rotate);
}, function () {
restartCycle();
});
}
// Pager click event handler
if (settings.pager || settings.manualControls) {
$tabs.bind("click", function (e) {
e.preventDefault();
if (!settings.pauseControls) {
restartCycle();
}
// Get index of clicked tab
var idx = $tabs.index(this);
// Break if element is already active or currently animated
if (index === idx || $("." + visibleClass).queue('fx').length) {
return;
}
// Remove active state from old tab and set new one
selectTab(idx);
// Do the animation
slideTo(idx);
})
.eq(0)
.closest("li")
.addClass(activeClass);
// Pause when hovering pager
if (settings.pauseControls) {
$tabs.hover(function () {
clearInterval(rotate);
}, function () {
restartCycle();
});
}
}
// Navigation
if (settings.nav) {
var navMarkup =
"<a href='#' class='" + navClass + " prev'>" + settings.prevText + "</a>" +
"<a href='#' class='" + navClass + " next'>" + settings.nextText + "</a>";
// Inject navigation
if (options.navContainer) {
$(settings.navContainer).append(navMarkup);
} else {
$this.after(navMarkup);
}
var $trigger = $("." + namespaceIdx + "_nav"),
$prev = $trigger.filter(".prev");
// Click event handler
$trigger.bind("click", function (e) {
e.preventDefault();
var $visibleClass = $("." + visibleClass);
// Prevent clicking if currently animated
if ($visibleClass.queue('fx').length) {
return;
}
// Adds active class during slide animation
// $(this)
// .addClass(namespace + "_active")
// .delay(fadeTime)
// .queue(function (next) {
// $(this).removeClass(namespace + "_active");
// next();
// });
// Determine where to slide
var idx = $slide.index($visibleClass),
prevIdx = idx - 1,
nextIdx = idx + 1 < length ? index + 1 : 0;
// Go to slide
slideTo($(this)[0] === $prev[0] ? prevIdx : nextIdx);
if (settings.pager || settings.manualControls) {
selectTab($(this)[0] === $prev[0] ? prevIdx : nextIdx);
}
if (!settings.pauseControls) {
restartCycle();
}
});
// Pause when hovering navigation
if (settings.pauseControls) {
$trigger.hover(function () {
clearInterval(rotate);
}, function () {
restartCycle();
});
}
}
}
// Max-width fallback
if (typeof document.body.style.maxWidth === "undefined" && options.maxwidth) {
var widthSupport = function () {
$this.css("width", "100%");
if ($this.width() > maxw) {
$this.css("width", maxw);
}
};
// Init fallback
widthSupport();
$(window).bind("resize", function () {
widthSupport();
});
}
});
};
})(jQuery, this, 0);
I think you can add width: auto; and overflow: hidden to your slider container
I could not find a proper solution. I solved my issue by switching slider. If anyone finds an answer please do share, meanwhile I suggest trying this: http://www.builtbyevolve.com/work/plugins/nerve-slider

get Slot Machine Effect using jquery

I am trying to create a slot machine using the following jquery plugin: jquery slot machine
I started with the simple Demo und entered my own list. The Problem I am having is that I need more than just that block which shows 1 line of the list. I need to show what is above and beneath the middle line of the lists. So I made the jSlotsWrapper box bigger.
Now I have the problem that when the lists spin, at the end of the list you see empty space. How can I make that the list has no end? So where the last item in the list is, I want to start again with the list.
EDIT
here is my html file
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Datengut Spielautomat</title>
<style type="text/css">
body {
text-align: center;
position: absolute;
height: 600px;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
}
ul {
padding: 0;
margin: 0;
list-style: none;
}
li {
height: 62px;
}
.jSlots-wrapper {
overflow: hidden;
text-align: center;
font-family:arial,helvetica,sans-serif;
font-size: 40px;
text-shadow: 2px 2px 2px #888888;
height: 600px;
width: 1242px;
margin: 10px auto;
border: 2px solid;
border-color: #ffa500;
box-shadow: 5px 5px 5px #888888;
box-shadow: inset 0 200px 100px -100px #555555, inset 0 -200px 100px -100px #555555;
}
.jSlots-wrapper::after {
content: "";
background:url("blumen.jpg");
opacity: 0.5;
z-index: -1;
}
.slot {
z-index: -1;
width: 410px;
text-align: center;
margin-left: 5px auto;
margin-right: 5px auto;
float: left;
border-left: 2px solid;
border-right: 2px solid;
border-color: #ffa500;
}
.line {
width: 410px;
height: 2px;
-webkit-transform:
translateY(-20px)
translateX(5px)
}
</style>
</head>
<body>
<ul class="slot">
<li>Bauakte</li>
<li></li>
<li>Bautagebuch</li>
<li></li>
<li>Mängelverwaltung</li>
<li></li>
<li>Störungsverwaltung</li>
<li></li>
<li>Personalakte</li>
<li></li>
<li>Maschinenakte</li>
<li></li>
</ul>
<script src="jquery.1.6.4.min.js" type="text/javascript" charset="utf-8"></script>
<script src="jquery.easing.1.3.js" type="text/javascript" charset="utf-8"></script>
<script src="jquery.jSlots.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
// normal example
$('.slot').jSlots({
number : 3,
spinner : 'body',
spinEvent : 'keypress',
easing: 'easeOutSine',
time : 7000,
loops : 6,
});
</script>
</body>
</html>
and here is my js file:
(function($){
$.jSlots = function(el, options){
var base = this;
base.$el = $(el);
base.el = el;
base.$el.data("jSlots", base);
base.init = function() {
base.options = $.extend({},$.jSlots.defaultOptions, options);
base.setup();
base.bindEvents();
};
// --------------------------------------------------------------------- //
// DEFAULT OPTIONS
// --------------------------------------------------------------------- //
$.jSlots.defaultOptions = {
number : 3, // Number: number of slots
winnerNumber : 1, // Number or Array: list item number(s) upon which to trigger a win, 1-based index, NOT ZERO-BASED
spinner : '', // CSS Selector: element to bind the start event to
spinEvent : 'click', // String: event to start slots on this event
onStart : $.noop, // Function: runs on spin start,
onEnd : $.noop, // Function: run on spin end. It is passed (finalNumbers:Array). finalNumbers gives the index of the li each slot stopped on in order.
onWin : $.noop, // Function: run on winning number. It is passed (winCount:Number, winners:Array)
easing : 'swing', // String: easing type for final spin
time : 7000, // Number: total time of spin animation
loops : 6 // Number: times it will spin during the animation
};
// --------------------------------------------------------------------- //
// HELPERS
// --------------------------------------------------------------------- //
base.randomRange = function(low, high) {
return Math.floor( Math.random() * (1 + high - low) ) + low;
};
// --------------------------------------------------------------------- //
// VARS
// --------------------------------------------------------------------- //
base.isSpinning = false;
base.spinSpeed = 0;
base.winCount = 0;
base.doneCount = 0;
base.$liHeight = 0;
base.$liWidth = 0;
base.winners = [];
base.allSlots = [];
// --------------------------------------------------------------------- //
// FUNCTIONS
// --------------------------------------------------------------------- //
base.setup = function() {
// set sizes
var $list = base.$el;
var $li = $list.find('li').first();
base.$liHeight = $li.outerHeight();
base.$liWidth = $li.outerWidth();
base.liCount = base.$el.children().length;
base.listHeight = base.$liHeight * base.liCount;
base.increment = (base.options.time / base.options.loops) / base.options.loops;
$list.css('position', 'relative');
$li.clone().appendTo($list);
base.$wrapper = $list.wrap('<div class="jSlots-wrapper"></div>').parent();
// remove original, so it can be recreated as a Slot
base.$el.remove();
// clone lists
for (var i = base.options.number - 1; i >= 0; i--){
base.allSlots.push( new base.Slot() );
}
};
base.bindEvents = function() {
$(base.options.spinner).bind(base.options.spinEvent, function(event) {
if (event.which == 32) {
if (!base.isSpinning) {
base.playSlots();
}
}
});
};
// Slot constructor
base.Slot = function() {
this.spinSpeed = 0;
this.el = base.$el.clone().appendTo(base.$wrapper)[0];
this.$el = $(this.el);
this.loopCount = 0;
this.number = 0;
};
base.Slot.prototype = {
// do one rotation
spinEm : function() {
var that = this;
that.$el
.css( 'top', -base.listHeight )
.animate( { 'top' : '0px' }, that.spinSpeed, 'linear', function() {
that.lowerSpeed();
});
},
lowerSpeed : function() {
this.spinSpeed += base.increment;
this.loopCount++;
if ( this.loopCount < base.options.loops ) {
this.spinEm();
} else {
this.finish();
}
},
// final rotation
finish : function() {
var that = this;
var endNum = base.randomRange( 1, base.liCount );
while (endNum % 2 == 0) {
endNum = base.randomRange( 1, base.liCount );
}
var finalPos = - ( (base.$liHeight * endNum) - base.$liHeight );
var finalSpeed = ( (this.spinSpeed * 0.5) * (base.liCount) ) / endNum;
that.$el
.css( 'top', -base.listHeight )
.animate( {'top': finalPos}, finalSpeed, base.options.easing, function() {
base.checkWinner(endNum, that);
});
}
};
base.checkWinner = function(endNum, slot) {
base.doneCount++;
// set the slot number to whatever it ended on
slot.number = endNum;
// if its in the winners array
if (
( $.isArray( base.options.winnerNumber ) && base.options.winnerNumber.indexOf(endNum) > -1 ) ||
endNum === base.options.winnerNumber
) {
// its a winner!
base.winCount++;
base.winners.push(slot.$el);
}
if (base.doneCount === base.options.number) {
var finalNumbers = [];
$.each(base.allSlots, function(index, val) {
finalNumbers[index] = val.number;
});
if ( $.isFunction( base.options.onEnd ) ) {
base.options.onEnd(finalNumbers);
}
if ( base.winCount && $.isFunction(base.options.onWin) ) {
base.options.onWin(base.winCount, base.winners, finalNumbers);
}
base.isSpinning = false;
}
};
base.playSlots = function() {
base.isSpinning = true;
base.winCount = 0;
base.doneCount = 0;
base.winners = [];
if ( $.isFunction(base.options.onStart) ) {
base.options.onStart();
}
$.each(base.allSlots, function(index, val) {
this.spinSpeed = 250*index;
this.loopCount = 0;
this.spinEm();
});
};
base.onWin = function() {
if ( $.isFunction(base.options.onWin) ) {
base.options.onWin();
}
};
// Run initializer
base.init();
};
// --------------------------------------------------------------------- //
// JQUERY FN
// --------------------------------------------------------------------- //
$.fn.jSlots = function(options){
if (this.length) {
return this.each(function(){
(new $.jSlots(this, options));
});
}
};
})(jQuery);
The core functionality is the same as in the github repository.
The important part, I think, is the function spinEm:
spinEm : function() {
var that = this;
that.$el
.css( 'top', -base.listHeight )
.animate( { 'top' : '0px' }, that.spinSpeed, 'linear', function() {
that.lowerSpeed();
});
}
here the list is placed above the jSlotsWrapper and with the animate function it moves down. Now what I need is for the animation to continue, and not to place the list at the top again. How can I achieve that.
EDIT
Ok, i tried the following to avoid the empty space, everytime the animation has finished:
spinEm : function() {
var that = this;
that.$el
.css( 'bottom', $("body").height() )
.animate( { 'top' : '0px' }, that.spinSpeed, 'linear', function() {
that.lowerSpeed();
});
}
I try to place the list at the bottom of the box and move it down until the top appears. But somehow the list doesn't really move. It just moves for 1 word and then stops comletely. What is wrong in the animation code?
EDIT
Ok I found the solution to my problem. Apparently, I can't use bottom in the css function. Instead, I used top and calculated the position of the top border of the list. That way I have an animation without all the empty space at the beginning. To avoid the jumping from the bottom to the top of the list I modified the height of the jSlots-Wrapper and the order of the list items, so that the items that are displayed before and after the jump are the same. That way, the user doesn't see the list jumping.
here is my new animate function.
spinEm : function() {
var that = this;
that.$el
.css( 'top', -(base.listHeight - $("body").height()) )
.animate( { 'top' : '0px'}, that.spinSpeed, 'linear', function() {
that.lowerSpeed();
});
}
I found a way to make the animation so that the user doesn't see the jumping. What I did, is, I configured the list in a way so that the beginning and the end are the same. So that when the end of the list is reached and it jumps to the beginning again, there is no difference. The jump is still there, but not visible for the user.

How to modify this jQuery plugin slider for scrolling and orientation?

I found a jQuery slider plugin that does almost what I need. I need to change the tabs so it is on the right side (by adding an option). Also, I would like to add scrolling to the tabs in case there is more than 3 tabs (also by an option). I am trying to make it look like this which is an artist mock up:
http://i.stack.imgur.com/nR8RY.png
This is the script I am trying to modify with the code below it:
http://jqueryglobe.com/labs/feature_list/
/*
* FeatureList - simple and easy creation of an interactive "Featured Items" widget
* Examples and documentation at: http://jqueryglobe.com/article/feature_list/
* Version: 1.0.0 (01/09/2009)
* Copyright (c) 2009 jQueryGlobe
* Licensed under the MIT License: http://en.wikipedia.org/wiki/MIT_License
* Requires: jQuery v1.3+
*/
;(function($) {
$.fn.featureList = function(options) {
var tabs = $(this);
var output = $(options.output);
new jQuery.featureList(tabs, output, options);
return this;
};
$.featureList = function(tabs, output, options) {
function slide(nr) {
if (typeof nr == "undefined") {
nr = visible_item + 1;
nr = nr >= total_items ? 0 : nr;
}
tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');
output.stop(true, true).filter(":visible").fadeOut();
output.filter(":eq(" + nr + ")").fadeIn(function() {
visible_item = nr;
});
}
var options = options || {};
var total_items = tabs.length;
var visible_item = options.start_item || 0;
options.pause_on_hover = options.pause_on_hover || true;
options.transition_interval = options.transition_interval || 5000;
output.hide().eq( visible_item ).show();
tabs.eq( visible_item ).addClass('current');
tabs.click(function() {
if ($(this).hasClass('current')) {
return false;
}
slide( tabs.index( this) );
});
if (options.transition_interval > 0) {
var timer = setInterval(function () {
slide();
}, options.transition_interval);
if (options.pause_on_hover) {
tabs.mouseenter(function() {
clearInterval( timer );
}).mouseleave(function() {
clearInterval( timer );
timer = setInterval(function () {
slide();
}, options.transition_interval);
});
}
}
};
})(jQuery);
This is the CSS:
body {
background: #EEE;
font-family: "Trebuchet MS",Verdana,Arial,sans-serif;
font-size: 14px;
line-height: 1.6;
}
#content {
width: 750px;
margin: 50px auto;
padding: 20px;
background: #FFF;
border: 1px solid #CCC;
}
h1 {
margin: 0;
}
hr {
border: none;
height: 1px; line-height: 1px;
background: #CCC;
margin-bottom: 20px;
padding: 0;
}
p {
margin: 0;
padding: 7px 0;
}
.clear {
clear: both;
line-height: 1px;
font-size: 1px;
}
a {
outline-color: #888;
}
Can anyone help with this?
Answer: jsFiddle: features box that slides and scrolls
Features:
Slides over time
Click next and previous
Support for lots of slides
Smooth scrolling
Move to item on click
Stop movement on hover
Easily extended because it uses the cycle plug-in.
Time spent on project: 4hrs
Ok, no fancy scrollbars or anything, but it will iterate through each one bringing it to the top index. I spent ages getting this working properly.
You can test it by adding additional items to the Lists.
/*
* FeatureList - simple and easy creation of an interactive "Featured Items" widget
* Examples and documentation at: http://jqueryglobe.com/article/feature_list/
* Version: 1.0.0 (01/09/2009)
* Copyright (c) 2009 jQueryGlobe
* Licensed under the MIT License: http://en.wikipedia.org/wiki/MIT_License
* Requires: jQuery v1.3+
*/
;(function($) {
$.fn.featureList = function(options) {
var tabs = $(this);
var output = $(options.output);
new jQuery.featureList(tabs, output, options);
return this;
};
$.featureList = function(tabs, output, options)
{
function slide(nr) {
if (typeof nr == "undefined") {
nr = visible_item + 1;
nr = nr >= total_items ? 0 : nr;
}
tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');
output.stop(true, true).filter(":visible").fadeOut();
output.filter(":eq(" + nr + ")").fadeIn(function() {
visible_item = nr;
});
$(tabs[(nr - 1 + total_items) % total_items]).parent().slideUp(500,function(){
var order = "";
for(var i = total_items; i > 0; i--)
{
var nextInd = ((nr - 1) + i) % total_items;
var tab = $(tabs[nextInd]);
if(i == total_items)
tab.parent().slideDown(500);
tab.parent().prependTo(tab.parent().parent());
order += nextInd + ", ";
}
});
}
var options = options || {};
var total_items = tabs.length;
var visible_item = options.start_item || 0;
options.pause_on_hover = options.pause_on_hover || true;
options.transition_interval = options.transition_interval || 2000;
output.hide().eq( visible_item ).show();
tabs.eq( visible_item ).addClass('current');
tabs.click(function() {
if ($(this).hasClass('current')) {
return false;
}
slide( tabs.index( this) );
});
if (options.transition_interval > 0) {
var timer = setInterval(function () {
slide();
}, options.transition_interval);
if (options.pause_on_hover) {
tabs.mouseenter(function() {
clearInterval( timer );
}).mouseleave(function() {
clearInterval( timer );
timer = setInterval(function () {
slide();
}, options.transition_interval);
});
}
}
};
})(jQuery);
To increase the height of the box simply change the height of div#feature_list and to add additional items simply add an additional li item in both the ul's within feature_list

Categories