3

Using the method I found here I'm trying to upgrade the functionality of my previous question.

Basically I want to cycle through my elements with previous and next buttons. I cannot use nextAll() and prevAll() functions because they are not all in the same wrapper, so I used the most upvoted solution from the first link. Next cycling works fine, and previous doesn't.

var $content = $(".big_container");
var $loaded_content = $(".details");
var $item_selector = $(".item");
var $previous = $('.previous');
var $next = $('.next');

if ($content.length > 0) {
  $item_selector.on('click', function(e) {
    e.preventDefault();
    var $this = $(this);
    load_gallery_container($this);
  });

  $next.on('click', function(e) {
    e.preventDefault();

    var $next_item = $content.find('.current').findNext('.item');
    if ($content.find('.item').hasClass('current')) {
      if ($next_item.length) {
        $content.find('.item').removeClass('current');
      }
      load_gallery_container_next_prev($next_item);
    }
  });

  $previous.on('click', function(e) {
    e.preventDefault();

    var $prev_item = $content.find('.current').findPrev('.item');
    if ($content.find('.item').hasClass('current')) {
      if ($prev_item.length) {
        $content.find('.item').removeClass('current');
      }
      load_gallery_container_next_prev($prev_item);
    }
  });


}

//Next all items

$.fn.findNextAll = function(selector) {
  var that = this[0],
    selection = $(selector).get();
  return this.pushStack(!that && selection || $.grep(selection, function(n) {
    return that.compareDocumentPosition(n) & (1 << 2);
    // if you are looking for previous elements it should be & (1<<1);
  }));
}

$.fn.findNext = function(selector) {
  return this.pushStack(this.findNextAll(selector).first());
}

//Previous all items

$.fn.findPreviousAll = function(selector) {
  var that = this[0],
    selection = $(selector).get();
  return this.pushStack(!that && selection || $.grep(selection, function(n) {
    return that.compareDocumentPosition(n) & (1 << 1);
    // if you are looking for previous elements it should be & (1<<1);
  }).reverse());
}

$.fn.findPrev = function(selector) {
  return this.pushStack(this.findPreviousAll(selector).first());
}

function load_gallery_container_next_prev($container) {
  $loaded_content.find('.div_content').html($container.data('content'));
  $container.addClass('current');
}

function load_gallery_container($container) {
  if ($container.hasClass("current")) {
    $loaded_content.slideUp('slow', function() {
      $(this).removeClass('open');
      $container.removeClass("current");
    });
  } else {

    var $insert_after = $container.parent('.wrappers'),
      $current = $('.current');
    $current.removeClass('current');

    if ($current.parent('.wrappers').is($insert_after)) {
      $loaded_content.find('.div_content').html($container.data('content'));
      $container.addClass("current");
    } else {
      if ($loaded_content.hasClass("open")) {
        $loaded_content.slideUp('slow', function() {
          $(this).removeClass('open');
          $container.removeClass("current");

          $loaded_content.detach().insertAfter($insert_after);
          $loaded_content.find('.div_content').html($container.data('content'));
        });
      } else {
        $loaded_content.detach().insertAfter($insert_after);
        $loaded_content.find('.div_content').html($container.data('content'));
      }

      $loaded_content.slideDown('slow', function() {
        $container.addClass("current");
        $(this).addClass('open');
      });
    }
  }
  setTimeout(function() {
    $('html, body').animate({
      scrollTop: $loaded_content.offset().top - 300
    }, 500);
  }, 600);
}
.big_container {
  background: #141414;
  display: block;
  padding: 30px;
}
.wrappers {
  width: 500px;
  margin: 0 auto;
  display: block;
}
.item {
  width: 31%;
  height: 100px;
  margin-right: 1%;
  margin-bottom: 30px;
  text-align: center;
  background: #ccc;
  color: #fff;
  display: inline-block;
}
.details {
  background: #ddd;
  width: 100%;
  padding: 30px;
  display: none;
}
.navigation {
  display: block;
  text-align: center;
  color: #fff;
}
.previous,
.next {
  font-size: 18px;
  display: inline-block;
  margin: 0 12px 10px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="big_container">
  <div class="navigation">
    <div class="previous">
      <</div>
        <div class="next">></div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla BLALALA bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla blBLALbla blaaaa">Click on meee!</div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla randomness">Click on meee!</div>
      <div class="item" data-content="blabla bla bla ">Click on meee!</div>
      <div class="item" data-content="blabla bla bla weeee">Click on meee!</div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla bla bla???">Click on meee!</div>
      <div class="item" data-content="I am done with blaaaaing">Click on meee!</div>
    </div>
    <div class="details">The content from div goes here:
      <div class="div_content"></div>
    </div>
  </div>

Basically when I click previous I get sent back to first element in the list, and not to the previous one. So the findPrev() function needs modifying, and I tried a lot: changing .first() to .last() and .prev() and even .prevAll(); tried changing return that.compareDocumentPosition(n) & (1<<1);

Nothing changed that would make this go to previous item. Anybody has an idea what is wrong with it?

ANSWER

Ok, so the solution is this:

$.fn.findPreviousAll = function( selector ){
    var that = this[ 0 ],
    selection = $( selector ).get();
    return this.pushStack(
        !that && selection || $.grep( selection, function(n){
            return that.compareDocumentPosition(n) & (1<<1);
        // if you are looking for previous elements it should be & (1<<1);
        }).reverse()
    );
};

$.fn.findPrev = function( selector ){
    return this.pushStack( this.findPreviousAll( selector ).first() );
};

What the findPreviousAll function was doing was returning an array from first element to the one I clicked on, so I just needed to reverse it! And a simple .reverse() did it :)

I updated the snippet so it works! :)

Community
  • 1
  • 1
dingo_d
  • 11,160
  • 11
  • 73
  • 132

1 Answers1

1

Change this:

var $prev_item = $content.find('.current').findPrev('.item');
    if ($content.find('.item').hasClass('current')) {
      if ($prev_item.length) {
        $content.find('.item').removeClass('current');
      }
      load_gallery_container_next_prev($prev_item);
    }

to this:

var $prev_item = $(".item")[$(".item").index($(".item.current"))-1];
if($prev_item){
        $(".item.current").removeClass('current');
    }
$($prev_item).addClass('current');
load_gallery_container_next_prev($prev_item);

and change this:

function load_gallery_container_next_prev($container) {
  $loaded_content.find('.div_content').html($container.data('content'));
  $container.addClass('current');
}

to this:

function load_gallery_container_next_prev($container) {
    $loaded_content.find('.div_content').html($($container).attr("data-content"));
    $container.addClass('current');
}

Here is the JSFiddle demo :)

Ahs N
  • 8,233
  • 1
  • 28
  • 33
  • Works, kinda, but when you click on the first item in the previous, you cannot click next anymore ;) I'm trying out to see what's wrong with the previous function, I'm stuck at `grep` filtering function, I know that it returns array of items, but I just need to set the filter that it returns previous item and not first. – dingo_d Aug 06 '15 at 08:51
  • I did not understand what you meant by _when you click on the first item in the previous, you cannot click next anymore_, can you please explain? :) – Ahs N Aug 06 '15 at 09:10
  • 1
    I found my answer, I'll update it. What I mean, on your fiddle, once you get to the 1 item by going back, when you click next nothing happens. – dingo_d Aug 06 '15 at 09:11
  • @dingo_d I just updated my code, its working now, was just a missing _if_ statement :) – Ahs N Aug 06 '15 at 09:20
  • Cool, I've given you a +1 since it's working, but I figured what was bothering me, so I'll keep my solution (my real code is already written so I don't feel like redoing it :D) – dingo_d Aug 06 '15 at 09:23
  • 1
    @dingo_d Cool, two solutions to the same problem :D – Ahs N Aug 06 '15 at 09:30