I have an array of image IDs.
var images = ['238239', '389943', '989238', ... ];
max = images.length;
Array index obviously starts at 0. The array size can vary.
For example. If there are 5 images in the array, the indexes are 0, 1, 2, 3, 4.
I'm swapping the images with Jquery by incrementing the current index like so:
<script>
currindex = 0
// Previous image, onclick event swap
$("previous").click(function(){
currindex = (currindex+1) % max;
...some more code to swap image...
});
// Next image, onclick event swap
$("next").click(function(){
currindex = (currindex+max-1) % max;
...some more code to swap image...
}
</script>
This allows the images to rotate and begin again at index 0 when user clicks "Next" on last index nr. 4. The same applies to rotating with "Previous".
I want to display a counter of current position like so:
<div>Image 3 of 5</div>
How can I implement the counter which will always begin at 1 at index 0 and will rotate both ways?
function updateCounter(){
document.getElementById("counter").innerHTML = "Image "+(currindex+1)+" of "+max;
}
Add some element to your code with the id of "counter", and add the function updateCounter() to both the click events.
Related
I have owl carousel slider with 5 items. And my problem is that i need first and last element of my slider to be always with opacity. Slider has like 15 elements which 9 cloned, 5 have .active class and one with cloned and .active.
I tryied make it using javascript where i found all ".active" classes in slider, but i don't exactly know what i should do with object which was found.
There is code which found all ".active" classes
var owlCarouselActive = document.getElementById("slider-tour").getElementsByClassName("owl-item active");
I need in order to this .active first and last have :before with my background style when i click on button prev or next.
You could do this with javascript
var owlCarouselActive = document.getElementsByClassName("owl-item active");
var first = owlCarouselActive[0]; //get first item
var last = owlCarouselActive[owlCarouselActive.length - 1]; //get last item
first.style.opacity = 0.8;
last.style.opacity = 0.8;
I'm not at home but try something like this:
function setOpacity() {
var elements = $('.active');
let count = 0;
$(elements).each(function(k,v) {
if (count == 0 || count == elements.length - 1) {
$(v).css('opacity', '0.8');
}
count++;
});
}
$(document).ready(function() {
setOpacity();
});
Run that function everytime you want it to update.
E.G on a button click.
You can use owlCarouselActive [0] to access the first element and owlCarouselActive [owlCarouselActive.length-1] to access the last element. Generally you can access i-th element by owlCarouselActive [i].
http://jsfiddle.net/umpe9a9j/
Currently it auto-plays 1 Popover at a time in a loop. However, I would like to have it auto played 2 Popover at a time. Of course, in a loop.
More Popovers will be added. How do I get this going?
HTML
<div class="container">
Hover Left |
Hover Right |
Click Me |
Click Me
</div>
JS
$(document).ready(function () {
var time = 1000;
var len = $('.myclass').length;
var count = 0;
var fun = setInterval(function () {
count++;
if (count > len) {
$('.p' + (count - 1)).popover('hide');
count = 1;
//clearInterval(fun);
}
$('.p' + count).popover('show');
if (count > 1) {
var pre = count - 1;
$('.p' + pre).popover('hide');
}
}, time);
});
I got a working example of what you are looking for. You can specify the number of popOver items to simultaneously show, and it will continue down the chain (and loop back if necessary) for each interval. The first thing I changed are the popOver class names. They now go from p0-p1-p2-p3, making it consistent with a 0 index array. This makes for less -1's in the code. So Html looks like:
<div class="container">
Hover Left |
Hover Right |
Click Me |
Click Me
</div>
Now the js function is straight forward but a might be a little confusing to look at. You first important variable is numConcrPopOver, this defines the number of simultaneous popOver items you want shown. Then in the interval function the code fills in 2 arrays of indexes; one for the number of popOver items to show and another for the items to hide that were previously shown. Using a for loop and the numConcrPopOver defined, it creates these lists. Take note of the modulo operator used multiple times in this section, its to ensure that elements to show and hide remain within the length of the total number of popOver items, looping back to the beginning when its over this length.
After these 2 arrays have been populated, first we need to remove any items in the popToHide array that also exist in the popsToShow array. This is done for scenarios where the number of simultaneous items to show is greater than half the total items. In this case because of the way the popsToHide array is first filled, it will contain indices that also belong in the popsToShow array. So we just filter through the popsToHide array and remove the duplicates to only hide popOver items that were previously shown but not also being currently shown.
As an example of the sequence of popOver items; if you have 4 total popOver items, and you want to show 3 at a time. The expected order of shown popOvers per interval is:
0-1-2 -> 1-2-3 -> 2-3-0 -> 3-0-1 ...
The javascript for this is:
$(document).ready(function(){
var time = 1000;
var popOverLength = $('.myclass').length;
var popOverIdx = 0;
var numConcrPopOver = 2;
var fun = setInterval(function(){
var popsToShow = []; //Array that will hold index of popOvver items to show
var popsToHide = []; //Array that will hold index of popOvver items to hide
//Loop for the number of simultanious popOver you want to show
for(var popNum=0; popNum<numConcrPopOver; popNum++){
var currPopIdx = popOverIdx+popNum; //Index o fthe current popOver to show
popsToShow.push(currPopIdx%popOverLength); //Alwyas mod index to keep within lenght of popOver items
var hidePopIdx = popOverIdx-1-popNum; //The index of the previous popOver item to hide
if(hidePopIdx < 0){
hidePopIdx = popOverLength-1-popNum
}
popsToHide.push(hidePopIdx%popOverLength);
}
popOverIdx+=numConcrPopOver;
popOverIdx%=popOverLength;
//Remove from popToHide array any items in the popToShow array.
//This is done for the scenarios where the numebr of popovers to
//Show in greater than half the total number of popovers,
//otherwise will hide immediatly after showing
popsToHide = popsToHide.filter(function(itm) {return popsToShow.indexOf(itm) < 0;});
popsToShow.forEach(function(itm){ //Iteratre of popOver items to show them
$('.p'+itm).popover('show');
});
popsToHide.forEach(function(itm){ //Iteratre of popOver items to hide them
$('.p'+itm).popover('hide');
});
}, time);
});
You can test out diffrent numbers of simultaneous popOvers by altering the numConcrPopOver variable. I've updated yous jsfiddle to include the new code: here
I'm puzzled by the function of my JavaScript image slider since it changes the slide only once upon clicking next (I haven't worked on previous yet, but should be logical enough to re-adjust). The code is given by:
$(".room_mdts").click(function(event){
//get the target
var target = event.currentTarget;
var room = $(target).data("room");
currentIndex = parseInt($(target).attr('data-room'));
//First way, by reuse target (only inside this function)
$('#room_details_holder').show();
//The second, by using selectors
//remove all "selected" classes to all which have both "room" and "selected" classes
$('.room_exp.selected').removeClass("selected");
//add "selected" class to the current room (the selector can also be the target variable)
$('.room_exp[data-room='+room+']').addClass("selected");
});
var currentIndex = 0;
var adjIndex = currentIndex - 1,
items = $('.room_details .room_exp'),
itemAmt = items.length;
function cycleItems() {
var item = $('.room_details .room_exp').eq(currentIndex);
items.hide();
item.css('display','inline-block');
}
$('.room_next').click(function() {
adjIndex += 1;
if (adjIndex > itemAmt - 1) {
adjIndex = 0;
}
cycleItems(adjIndex);
cycleItems(currentIndex);
$('#room_name').text($('.room_exp:nth-child('+(adjIndex+2)+')').attr('title'));
});
$('.room_previous').click(function() {
currentIndex -= 1;
if (currentIndex < 0) {
currentIndex = itemAmt - 1;
}
cycleItems(currentIndex);
$('#room_name').text($('.room_exp:nth-child('+(currentIndex+1)+')').attr('title'));
});
$('#room_name').text($('[style*="inline-block"].room_exp').attr('title'));
});
The reason I had to introduce adjIndex is because without '-1' the slide changed by 2 on the first click, again, no idea why.
The Fiddle: https://jsfiddle.net/80em4drd/2/
Any ideas how to fix that it only changes once? (And also, the #room_name only shows after the click, does not show upon expanding).
Try this I rearranged your code a little bit:
made your currentIndex global and assigned with the adjIndex. If that's ok I will improve my answer:
If you click on the right arrow it goes to the end and comes back to the beginning.
url: https://jsfiddle.net/eugensunic/80em4drd/3
code:
function cycleItems() {
currentIndex=adjIndex;
var item = $('.room_details .room_exp').eq(currentIndex);
items.hide();
item.css('display','inline-block');
}
Okay, great thanks to eugen sunic for the little push that got me thinking!
I have finially cracked all of the pieces, although, I might have some extra unecessary bits of code, duplicates etc, but the functionallity is just perfect!
What I have edited:
I moved one of the closing brackets for the cycleFunction () closing bracket to the end of .click functions, that is to make the variable global (at least for those 3 functions)
I changed the title writing function from: $('#room_name').text($('[style*="inline-block"].room_exp').attr('title'));
to:$('#room_name').text($('.room_exp:nth-child('+(adjIndex+2)+')').attr('title'));
Added a few changes regarding .addClass/.removeClass to the $('.room_details_close').click(function(){.
Now, openning any of the thumbnails shows the title immediately (the right title), clicking '<<' or '>>' changes the slide to next and previous, respectively, while the title changes accordingly. Closing the expanded menu and clicking on a different thumbnail results in re-writing the currentIndex (hence, adjIndex too), so the function starts again with no problem.
Please feel free to use!
The new fiddle is: Fiddle
I am trying to use this example as shown HERE in JSFIDDLE, the problem i am having is that I would like when dropping to squeeze the new record in between and not swap. I tried adding a for loop in the drop function that increases the destination record if the target is less than that one or decreases it if the target is more than the destination.
The problem is that I am ending up with repeated positions like 4,4 or 5, 5, 5. Are there any examples of Kendo UI that i can use with this functionality?, instead of swaping?.
example:
id text position
1 world 1
2 cup 2
3 Brazil 3
4 2014 4
5 Soccer 5
If i move record 4 to the top i would like to
id text position
4 2014 1
1 World 2
2 Cup 3
3 Brazil 4
5 Soccer 5
I would appreciate if anyone could point me in the right direction.
The way to insert a row when drag/drop is to use the datasource insert (or add) capability. At the high level you are inserting the row into the new location, and removing it from the old location. Kendo's grid will automatically refresh the display - you just need to get the data right. The next challenge is to get the target row number. You've done this by adding a column in the grid, and executing target.get("position")). I've used the datasource.indexOf method for this, and removed the Position column - cleaning up the display. Ref jsfiddle. Following is a small excerpt of the code (thanks to Lars below for improvements!)
grid.table.kendoDropTargetArea({
filter: "td",
group: "gridGroup",
drop: function (e) {
e.draggable.hint.hide();
var target = dataSource.getByUid($(e.draggable.currentTarget).data("uid")),
destElement = $(e.dropTarget).closest("tr"),
dest = dataSource.getByUid(destElement.data("uid")),
destPosition = dataSource.indexOf(dest);
//not on same item
if (target.get("id") !== dest.get("id")) {
dataSource.remove(target);
dataSource.insert(destPosition, target);
}
}
});
Since you're only trying to modify the order of the rows, your original approach should work. Instead of swapping the position, you need to adjust the position of all other rows depending on their relative position to the source row and target row.
Your drop target definition might then look something like this:
grid.table.kendoDropTargetArea({
filter: "td",
group: "gridGroup",
drop: function (e) {
e.draggable.hint.hide();
var target = dataSource.getByUid($(e.draggable.currentTarget).data("uid")),
destElement = $(e.dropTarget).closest("tr"),
dest = dataSource.getByUid(destElement.data("uid")),
sourcePosition,
targetPosition,
position,
item;
//not on same item
if (target.get("id") !== dest.get("id")) {
// set new position for dropped item
sourcePosition = target.get("position");
targetPosition = dest.get("position");
if (targetPosition > sourcePosition) {
targetPosition -= 1;
}
target.set("position", targetPosition);
// update positions for all other items
for (var i = 0, max = dataSource.total(); i < max; i++) {
item = dataSource.at(i);
if (item.uid === target.uid) continue;
position = item.position;
// items which had a higher position than the source item need to move down by one
if (position >= sourcePosition) {
position -= 1;
}
// items which had a higher position than the target position need to move up by one
if (position >= targetPosition) {
position += 1;
}
item.set("position", position);
}
dataSource.sort({
field: "position",
dir: "asc"
});
}
}
});
(demo)
I have this image table that has two columns and 20 rows. When executing this for loop, all the rows are working okay except for the first row, which only displays the first image on the left. It's really weird; is there something wrong with the order of the execution?
var image= [];
var rows=5;
for (var i = 0; i < test.length; i++) {
var avatar = test[i].image; // The profile image
if(i % 2 === 0){
image[i]= Titanium.UI.createImageView({
top:row,
image:avatar
align:right
});
win.add(image[i]);
//trying to increase the image
row =row+200;
} else if(i % 2 === 1) {
image[i]= Titanium.UI.createImageView({
top:row,
image:avatar
align:left
});
win.add(image[i]);
}
}
i=0, i%2=0, show the image (supposed to be right), row+=200;
i=1, i%2=1, show the image (left side), row stays same
i=2, i%2=0, show the image (right side), row+=200
0%2 = 0, and that represents your right side image, and then it goes to the next line. Just need to play around with where you increment row and which side your loop starts with.