JQuery jCarousel with paging dots? - javascript

I was using jCarousel plugin to display a series of items. I was following this example from the web site to get external controls and a paging control.
There's two problems with this approach:
i need to add the items for the numbers manually (instead of just calculating the number of items in the carousel with JS), although I can live with this, and
There seems to be no way to highlight (via a class change) the item for the current slide
What I am doing is using bullets as paging dots, as you can see in this fiddle
<div class="carousel-nav cf">
<table>
<tr>
<td>◀</td>
<td>
<div class="jcarousel-control">
•
•
•
</div>
</td>
<td>►</td>
</tr>
</table>
</div>
and would like to set the class to "active" or similar for the current item.
Any ideas? Or is there a better plugin for this? I tried Cycle but I need two have 2 or more items showing at once. Thanks.

html:
<ul class="jcarousel-control"></ul>
script:
$('.jcarousel-control')
.on('jcarouselpagination:active', 'li', function() {
$(this).addClass('active');
})
.on('jcarouselpagination:inactive', 'li', function() {
$(this).removeClass('active');
})
.jcarouselPagination({
'perPage':1,
'item': function(page, carouselItems) {
return '<li class="' + (page == 1 ? "active" : "") + '"></li>';
}
});
$('.mycarousel-prev').jcarouselControl({target:'-=1'});
$('.mycarousel-next').jcarouselControl({target:'+=1'});

actually you can use call back function for higlighting respective to current active carousel element
function highlighttab1(carousel, state, liindex) {
document.getElementById(liindex).className = "selected";}
function removehighlighttab1(carousel, state, liindex) {
document.getElementById(liindex).className = "unselected";}
few days ago i worked with jcarousel where i had menu label panel (as you have dots) and all static hyperlinks which when clicked will scroll to the intendent carousel element

Related

Multiple Owl V2 sliders using single javascript declaration and .each()

Been trying various things, and searched around expecting others to have done the same, but getting nowhere fast .. the best result i've got is the first instance of the carousel working, but all the rest do not. Why is the .each() function not working?
Note: the main aim is to have multiple carousels with one block of .js control .. the script pulls the individual carousel instance variables such as number of items to show, delay, if lazy-load or not, theme classes, etc from each instance based on the data-variable="xyz" values ... and it works fine with individually identified (used unique classes or ID's) carousels on the page, but not this (more efficient) multi method.
As you see i've tried to find the carousels based on the common class ".galleryowlmulti", then find their parent container ID to uniquely identify it (as i thought this is the issue?) and then apply the variables to each carousel instance. Hope that makes sense?
Example HTML Snippet of one slider repeated in the same page but with unique ID's (please note that ".owl-carousel" is not needed where I use ".owlcarousel") :
<span id="unique-id1" class="slider">
<span class="titleh3">Title</span>
<div class="galleryowlmulti" data-owlitemshow="8" data-owlmargin="10" data-owltimeout="4000" data-owllazy="true" data-owldots="false" data-owlautoplay="false" data-owlslideby="page" data-owlthemes="owltheme-smallnav">
<div class="owlcarousel">
<div class="item">1st slide</div>
<div class="item">2nd slide</div>
</div>
</div>
</span>
<span id="unique-id2" class="slider">
<span class="titleh3">Title</span>
<div class="galleryowlmulti" data-owlitemshow="8" data-owlmargin="10" data-owltimeout="4000" data-owllazy="true" data-owldots="false" data-owlautoplay="false" data-owlslideby="page" data-owlthemes="owltheme-smallnav">
<div class="owlcarousel">
<div class="item">1st slide</div>
<div class="item">2nd slide</div>
</div>
</div>
</span>
The JavaScript:
$(function () {
$('.galleryowlmulti').each(function() {
// *** declare identifier? ***
var owl_id = $(this).closest('.slider').prop('id'); // .attr('id'); // .prop('id');
var owl_declare = $('#' + owl_id + ' .galleryowlmulti'); // owl_id.find('.galleryowlmulti'); // $('#' + owl_id + ' .galleryowlmulti'),
var owl_instance = $('#' + owl_id + ' .owlcarousel'); // $(".owlcarousel", this) // owl_id.find('.owlcarousel'); // $('#' + owl_id + ' .owlcarousel');
// pull variables from page
var owl_owlthemes = owl_declare.data('owlthemes'),
owl_owlitemshow = owl_declare.data('owlitemshow'),
owl_owllazy = owl_declare.data('owllazy'),
owl_owlmargin = owl_declare.data('owlmargin'),
owl_owldots = owl_declare.data('owldots'),
owl_owlautoplay = owl_declare.data('owlautoplay'),
owl_owltimeout = owl_declare.data('owltimeout'),
owl_slidebyf = owl_declare.data('owlslideby');
// calc the items to show breaks
var owl_owlitemshow75=Math.round(owl_owlitemshow*0.75),
owl_owlitemshow50=Math.round(owl_owlitemshow*0.5),
owl_owlitemshow25=Math.round(owl_owlitemshow*0.25);
// calculate item count
var item_count = parseInt(owl_instance.find('.item').length);
var true_false = 0;
if (item_count <=1) {true_false = false; owl_owldots = false;} else {true_false = true;}
//
// control nav visiblity thumbs shown vs thumbs allowed visible
// see: http://stackoverflow.com/a/33252395/3794783
// owl_instance.on('initialized.owl.carousel resized.owl.carousel', function(e) {
// $(e.target).toggleClass('owl-nonav', e.item.count <= e.page.size);
// });
owl_instance.owlCarousel({
themeClass: owl_owlthemes,
autoplay: owl_owlautoplay,
autoplayTimeout: owl_owltimeout,
items: owl_owlitemshow,
margin: owl_owlmargin,
responsive:{
0:{items:1,nav:true},
389:{items:owl_owlitemshow25},
605:{items:owl_owlitemshow50},
1023:{items:owl_owlitemshow75},
1289:{items:owl_owlitemshow}
},
loop: true_false,
nav: true_false,
slideBy: owl_slidebyf,
lazyLoad: owl_owllazy, // IMG markup (lazyOwl = V1 / owl-lazy = v2 ): class="owl-lazy" and data-src="url_to_img" src="" or/and data-src-retina="url_to_highres_img"
dots: owl_owldots,
//
// backport the classes to older used ones
navContainerClass: 'owl-buttons',
dotsClass: 'owl-pagination',
dotClass: 'owl-page',
autoplayHoverPause:true, //false
onInitialized: function() {
if(owl_slidebyf == 'page'){
owl_instance.owlCarousel({slideBy:page})
}
}
});
});
});
Fiddle example:
See JS Fiddle
UPDATE:
I got some way along with getting mutliple instances on page to fire and work (-ish as lazyload isnt happy) ..
In the fiddle, remove or comment out the following:
responsive:{
0:{items:1,nav:true},
389:{items:owl_owlitemshow25},
605:{items:owl_owlitemshow50},
1023:{items:owl_owlitemshow75},
1289:{items:owl_owlitemshow}
},
Ooops ... and this also needs commenting out or removing THEN it works? WTH?!
onInitialized: function() {
if(owl_slidebyf == 'page'){
owl_instance.owlCarousel({slideBy:page})
}
}
UPDATE 2:
Removing the "nav:true" in responsive seemed to fix .... seems to be the culprit for others reading ... if removed the original script code should work for you :)
Simply add some arrows (div, span, whatever) near the each carousel and assign to them class .carousel-arrow-left and .carousel-arrow-right. Next add this javascript to your js file.
The Javascript
// carousel arrows
$('.carousel-arrow-left').click(function(){
$(this).next(".carousel-product-list").trigger('prev.owl.carousel');
});
$('.carousel-arrow-right').click(function(){
$(this).prev(".carousel-product-list").trigger('next.owl.carousel');
});
Let's say every carousel is called .carousel-product-list. Now every right arrow on your page after click finds next class which name is .carousel-product-list and do a command next.owl.carousel, which means the carousel go forward by a one item.

Make current div change relevant menu tab to active

In my mobile project I can press a menu tab (Tab2) and the tab becomes active (with background color for the active class) and the corresponding div (Div2) below will appear on the screen.
If I press another tab, that tab gets active with corr. div etc...all in all, works perfect!
But now I have the opposite problem, I want to press (in my case, swipe) a div onto my screen and have the corresponding tab above to be active (with color). e.g. swipe in Div1 on screen, Tab1 should be active and have a certain background color. Swipe in Div2, then Tab2 should be active instead etc. but can't get it to work.
Below are my li tags:
<ul class="nav nav-pills mobileNavbar">
<li onclick="swipeFunction(0)" class="col-xs-4 tab1" data-index="0">STREAM</li>
<li onclick="swipeFunction(1)" class="col-xs-4 tab2" data-index="1">CHAT</li>
<li onclick="swipeFunction(2)" class="col-xs-4 tab3" data-index="2">IDE</li>
</ul>
And my jQuery:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
var savedIndex = $(this).find('.active').index();
if (savedIndex === 0){
// I want Tab1 to be active here
} else if (savedIndex == 1){
// I want Tab2 to be active here
} else if (savedIndex == 2){
// I want Tab3 to be active here
}
});
For more details into what I'm trying to build, incl. libs, images (and my previous problem, solved by "Pieter"):
Link to a section on horizontal web page
As I commented above, you are doing same thing in all the conditions. All you need to do is, to activate the navigation item by index you are getting from carousel. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a').css('background', 'yellow');
});
EDIT:
I would recommend to play with a CSS class instead of inline css. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a')
.addClass("active") // add active class to the current one
.parent().siblings() // select sibling navigation items
.removeClass("active"); // remove active class from the other navigations
});
You conveniently already have classnames "tab1", "tab2", "tab3" on the tabs, which can be matched easily based on savedIndex:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
$('.nav li').removeClass('active'); // clear the old one
var savedIndex = $(this).find('.active').index();
$('.tab'+ (savedIndex+1)).addClass('active'); // add the new one
});
(I believe index() returns an integer, but if not you may need to parseInt it before adding 1.)

Add dynamic list items to dynamically created panel with a istview

I'am using jquery mobile 1.3.2 for my web project.
The following code creates a panel for all pages:
function injectPanelIntoAllPages(){
console.log("IncetPanel");
var panel = '<div data-role="panel" id="mypanel" data-position="left" data-display="push">' +
'<div><ul data-role="listview" id="history"></ul></div> </div>';
$(document).on('pagebeforecreate', '[data-role=page]', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
$(document).on('pagebeforeshow', '[data-role=page]', function () {
$(this).trigger('pagecreate');
});
});
}
Now i want to add (dynamically) list items to the listview in the panel, but it don't works.
For adding list items i use the following method:
function addToHistory(value) {
$("#history").append(
"<li id='history-element'>" + value + "</li>");
$("#history").listview("refresh");
}
What can i do to solve this issue?
Note that you're using same Id for both panel and listview. This isn't recommended, however, it still can work as long as you specify which element to target within active page.
Another note, you don't need to call any enhancement method once you append panels dynamically, since you append them on pagebeforecreate. They will be created/initialized by jQM on that event.
$(document).on('pagebeforecreate', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
});
To append elements into listview, you need to look for it into active page's. Otherwise, new elements will be added to first element with #history ID.
var listview = $.mobile.activePage.find("#history");
listview.append("elements").listview("refresh");
Demo

Twitter Bootstrap accordion feature

Working with Bootstrap and JavaScript and I am using it as an accordion format - once clicked on the collapsed div it will open and show the items within the div based on the id.
Problem:
If the div doesn't contain any items i want it to open and show a message to the user:
"no items here"
How do I go about doing that? In the JavaScript ?
This is what I have:
View
<div class="accordion-body collapse state-loading" data-group-id="13" data-bind="attr: { 'id': 'GroupMember_' + Id(), 'data-type-id': ModelId() }" id="GroupMember_15" data-type-id="15">
<div class="accordion-inner no_border" data-bind="foreach: Children"></div><!--END: accordion-inner--></div>
</div>
If the Children are 0 i want it to open and have this text show: No items here
Javascript:
OnSuccess: function (data) {
var _groups = linq.From(options.groupData);
var _groupsToUpdate = _groups .Where(function (x) { return x.Id == options.groupId; });
if (_groupsToUpdate.Any()) {
_groupsToUpdate.First().Children = data.Items;
}
Not sure if i am missing anything else to share - let me know.
UPDATE
Div Layout:
<div class='accordion-group'>
<div class='accordion-heading'> Group 1 </div>
<div class='accordion-body'>
<div class='accordion-inner'>
<div class='element'>No items here</div>
</div>
</div>
</div>
I have to click on the 'accordion-heading' class in order to display the 'accordion-body' and get into the accordion-inner items
You'd need to bind to the show event on the accordion elements and perform your check there, from your classes I'm assuming your using Bootstrap v2.3.2:
$('.accordion .collapse').on('show', function () {
var $inner = $(this).find('.accordion-inner');
if($inner.is(':empty')){
$inner.html('No items here');
}
});
Demo fiddle
Note that the :empty selector is very picky, it will not work if there's any white space between the opening and closing tags of .accordion-inner.
You may also use if(!$.trim($inner.html())) to check if the element is empty or as #JL suggested check the length of the children elements just beware that text nodes are not treated like children, so a div with only text would be considered empty
Do you have jQuery installed? You can check if a <div> has children like this:
if ($('#divId').children().length == 0) {
$('#divId').append("no items here");
}
If you don't have jQuery:
if (!document.getElementById('divId').hasChildNodes()) {
document.getElementById('divId').innerHTML = "no items here";
}
Based on your edit, I think we're inspecting accordian-inner for children. If so, give it an ID and substitute that into our code. Note: You don't need a <div> to contain our "no items" message...the message will get printed with javascript (Plus, if you have a <div> there, then you've in effect added a child and the message no longer applies). Change your HTML to this:
<div class='accordion-group'>
<div class='accordion-heading'> Group 1 </div>
<div class='accordion-body'>
<div id='innerId' class='accordion-inner'>
<!-- Remove the 'element' div -->
</div>
</div>
</div>
Then:
if (!document.getElementById('innerId').hasChildNodes()) {
document.getElementById('innerId').innerHTML = "no items here";
}

jqueryui accordion disable specific according tab

hi i am trying to make a wizard for first time i want to disable all accordion tabs when i click on the link it enable next tab and open it..
i hve this code but it disable all tabs :(
thanks
$(function() {
$("#list1a").accordion({
autoHeight: false,
navigation: false
});
});
$("#list1a").accordion("disable");
$("#list1a").accordion("activate", 2 );
Don't use the accordion for that, it's not intended for wizardry. And since there's no wizard component available in jquery UI, lets make our own ;)
html:
<ul class="ui-wizard">
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
</ul>
javascript plugin:
$.fn.wizard = function(){
this.find('.ui-wizard-content').hide();
this.find('.ui-wizard-content:first').show();
this.find('.ui-wizard-content:last .ui-wizard-next').hide(); // just in case
this.delegate('.ui-wizard-next', 'click', function(){
// very long jquery chain...
$(this).closest('.ui-wizard-content')
.hide('fast')
.closest('.ui-wizard-panel')
.next()
.find('.ui-wizard-content')
.show('fast');
});
}
javascript impl:
$(".ui-wizard").wizard();
Ofcourse.. you'd have to theme it yourself, though copy/pasting and renaming accordion styles gets you a long way. A nicer way would be to make an official wizard widget out of this.
Can also check out this code: http://github.com/desdev/jWizard/
Think it's exactly what you need.
Try ui-state-disabled class: http://api.jqueryui.com/theming/css-framework/
Consider this piece of code that allows user go back, but not go to next accordion tab:
function disableAccordionNextTabs () {
var $accordion = $(".accordion");
var active = $accordion.accordion('option', 'active');
var $headers = $accordion.find($accordion.accordion('option', 'header'));
$headers.addClass('ui-state-disabled');
for (var i = active; i >= 0; i--) {
$headers.eq(i).removeClass('ui-state-disabled');
}
}

Categories