1

I am trying to loop functionality for buttons I've made. I have 3 video collections. and they all need the same script for next and previous.

What I want is that I only have to make one next button and one prev button. This is what it should do:

    $("#next-1").click(function(){
  var $this = $(".video-album-1");
  callback = function() {
      $this.insertBefore($this.siblings(':eq(2)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });

 $("#prev-1").click(function(){
  var $this = $(".video-album-1");
  callback = function() {
      $this.insertAfter($this.siblings(':eq(3)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });

 $("#next-2").click(function(){
  var $this = $(".video-album-2");
  callback = function() {
      $this.insertBefore($this.siblings(':eq(2)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });
 
 $("#prev-2").click(function(){
  var $this = $(".video-album-2");
  callback = function() {
      $this.insertAfter($this.siblings(':eq(3)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });

I've already tried to loop it, but this doesn't work:

for (i = 0; i < 3; i++) { 
 $("#next-"+i).click(function(){
  var $this = $(".video-album-"+i);
  callback = function() {
      $this.insertBefore($this.siblings(':eq(2)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });

 $("#prev-"+i).click(function(){
  var $this = $(".video-album-"+i);
  callback = function() {
      $this.insertAfter($this.siblings(':eq(3)'));
     }
     $this.fadeOut(200, callback).fadeIn(400);
 });
}

Is there anyone that could tell me a solution? I do not want to repeatedly create #next-3 #next-4 ids etc..

Thanks in advance.

Bart. K
  • 63
  • 8
  • [This](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) is why your attempt didn't work, but I'm not marking this as a duplicate question, because while the answers there would answer this (which is the usual criterion), there are *better* answers for this specific issue. – T.J. Crowder May 25 '16 at 11:24
  • Please include your HTML as well. Ideally, include a runnable example using Stack Snippets (the `<>` toolbar button). (You've used that for your code blocks, but incorrectly; for just code blocks, you want the `{}` button. But `<>` lets you make the example run.) – T.J. Crowder May 25 '16 at 11:25
  • Unless I've miss understood you might be going the wrong way to do what you want. Instead of creating multiple events you should give your button a class names and create your click events against the class – Rob White May 25 '16 at 11:27
  • As per linked question in comments: your problem is down to closures - when you click, the `i` is not the `i` it was when the click was assigned. – freedomn-m May 25 '16 at 11:31
  • SO is a **very** active place. When you post a question, don't disappear. Stick around so you can address requests for clarification, etc. – T.J. Crowder May 25 '16 at 11:40

4 Answers4

0

This question and its answers explain why your attempt didn't work correctly.

Based on your attempted for loop, this will work:

$("[id^=next-]").click(function() {
    var i = this.id.substring(5);
    var album = $(".video-album-" + i);
    callback = function() {
        album.insertBefore(album.siblings(':eq(2)'));
    };
    album.fadeOut(200, callback).fadeIn(400);
});
$("[id^=prev-]").click(function() {
    var i = this.id.substring(5);
    var album = $(".video-album-" + i);
    callback = function() {
        album.insertAfter(album.siblings(':eq(3)'));
    };
    album.fadeOut(200, callback).fadeIn(400);
});

That works by using an attribute starts with selector to match all of your next- (and prev-) buttons, then figures out the index from the id of the button actually clicked.

But there's probably a better answer we could give you if you quote your HTML.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Can you take a look at below approach:

$("[id^=next-]").click(function(){
    var current_id = $(this).attr("id");
    var number = current_id.replace("next-","");

    var $this = $(".video-album-"+number);
    callback = function() {
        $this.insertBefore($this.siblings(':eq(2)'));
    }
    $this.fadeOut(200, callback).fadeIn(400);
});

$("[id^=prev-]").click(function(){
    var current_id = $(this).attr("id");
    var number = current_id.replace("prev-","");

    var $this = $(".video-album-"+number);
    callback = function() {
        $this.insertAfter($this.siblings(':eq(3)'));
    }
    $this.fadeOut(200, callback).fadeIn(400);
});

Here we are using jQuery's starts with selector to attach the event to required DOM elements and within event handler we are grabbing the associated number for further process.

vijayP
  • 11,432
  • 5
  • 25
  • 40
0

Use a class with next(),prev(),find() to get the video album class based on the next/prev elements or use this hack

$('[id^="next-"]').click(function(){
        var i = $(this).attr('id').split('-')[1];
        var $this = $(".video-album-"+i);
        callback = function() {
            $this.insertBefore($this.siblings(':eq(2)'));
        }
        $this.fadeOut(200, callback).fadeIn(400);
    });

    $('[id^="prev-"]').click(function(){
         var i = $(this).attr('id').split('-')[1];
         var $this = $(".video-album-"+i);
        callback = function() {
            $this.insertAfter($this.siblings(':eq(3)'));
        }
        $this.fadeOut(200, callback).fadeIn(400);
madalinivascu
  • 32,064
  • 4
  • 39
  • 55
0

I'll emphasize now this is just one way, there might be better ones

Assuming these are your buttons

<button class="next" data-videocollectionname="video1">next</button>
<button class="next" data-videocollectionname="video2">next</button>
<button class="next" data-videocollectionname="video3">next</button>

<button class="previous" data-videocollectionname="video1">previous</button>
<button class="previous" data-videocollectionname="video2">previous</button>
<button class="previous" data-videocollectionname="video3">previous</button>

I've given each button a data attribute to say which collection the button is relevant too.

Forgive me if I've miss understood the question

$(".next").click(function(){
    var videoCollectionName = $(this).data("videocollectionname");
  var videoElement = $("#"+videoCollectionName);

//do whatever code you want for the videocollection

});

$(".previous").click(function(){
    var videoCollectionName = $(this).data("videocollectionname");
  var videoElement = $("#"+videoCollectionName);

//do whatever code you want for the videocollection

});
Rob White
  • 950
  • 1
  • 6
  • 16