2

I need to have two synced carousels, one above the other both controlled by the same set of custom buttons.

I have managed to get them to sync and have implemented custom buttons that control both of them but here's the problem; whilst the custom buttons can control them both in a synced manner, when I swipe or drag one or the other, they don't seem to be synced. i.e. If I swipe/drag the top carousel the bottom one is unaffected. In doing so, the active state of the custom buttons works but it doesn't if I swipe/drag the bottom carousel.

Additionally, In just implementing the custom buttons javascript I can hide the standard button controls (the dots and the previous/next arrow navigation buttons) so that just the custom buttons are in view.

But by adding the synced javascript the standard buttons can't be hidden it seems, as well as the other issue I mentioned initially.

Here's the code:

HTML

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>CodePen - Flickity - custom UI, jQuery</title>
  <meta name="viewport" content="width=device-width">
  <link rel='stylesheet' href='https://npmcdn.com/flickity@2/dist/flickity.css'>
  <link rel="stylesheet" href="style.css">

</head>
<body>
  <h1>Flickity - sync</h1>

  <!-- Flickity HTML init -->
  <div class="gallery gallery-main" data-flickity='{ "sync": ".gallery-nav" }'>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
  </div>

  <div class="button-row">
    <button class="button button--previous">&larr;</button>
    <div class="button-group button-group--cells">
      <button class="button is-selected">1</button>
      <button class="button">2</button>
      <button class="button">3</button>
      <button class="button">4</button>
    </div>
    <button class="button button--next">&rarr;</button>
  </div>
  
  <div class="gallery gallery-nav"
    data-flickity='{ "contain": true }'>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
    <div class="gallery-cell"></div>
  </div>
  

<!-- partial -->
<script src='https://code.jquery.com/jquery-3.1.0.min.js'></script>
<script src='https://npmcdn.com/flickity@2/dist/flickity.pkgd.js'></script>
<script  src="script.js"></script>
<script  src="flickity-sync.js"></script>

<script>
  $('.gallery-main').flickity({
  sync: '.gallery-nav'
});
// only need to set sync on one of the Flickity galleries
$('.gallery-nav').flickity();
</script>

</body>
</html>

CSS

/* external css: flickity.css */

* { box-sizing: border-box; }

body { font-family: sans-serif; }

.gallery {
  background: #FAFAFA;
  margin-bottom: 40px;
}

.gallery-cell {
  width: 66%;
  height: 200px;
  background: #8C8;
  border-radius: 5px;
  counter-increment: gallery-cell;
}

/* cell number */
.gallery-cell:before {
  display: block;
  text-align: center;
  content: counter(gallery-cell);
  line-height: 200px;
  font-size: 80px;
  color: white;
}

.gallery-nav .gallery-cell {
  width: 66%;
  height: 200px;
}

.gallery-nav .gallery-cell:before {
  line-height: 200px;
  font-size: 80px;
}

.gallery-cell.is-selected {
  background: #ED2;
}


.button {
  display: inline-block;
  padding: 10px 22px;
  font-size: 18px;
  border: 1px solid #DDD;
  border-radius: 6px;
  background-color: #FAFAFA;
  background-image: linear-gradient( hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.1) )
}

.button:hover {
  background-color: white;
  border-color: #BBB;
  cursor: pointer;
}

.button:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
  background-color: white;
}

.button:active {
  background-color: #EEE;
  box-shadow: inset 0 2px 10px hsla(0, 0%, 0%, 0.3);
}

.button.is-selected {
  background-color: #09F;
  color: white;
}

/* ---- button-group ---- */

.button-group {
  display: inline-block;
  vertical-align: bottom;
}

.button-group:after {
  content: '';
  display: block;
  clear: both;
}

.button-group .button {
  float: left;
  border-radius: 0;
  border-right-width: 0;
}

.button-group .button:first-child {
  border-radius: 6px 0 0 6px;
}

.button-group .button:last-child {
  border-radius: 0 6px 6px 0;
  border-right-width: 1px;
}

/* ---- button-row ---- */

.button-row {
  text-align: center;
}

JavaScript

// external js: flickity.pkgd.js

var $carousel = $('.gallery').flickity({
  prevNextButtons: false,
  pageDots: false
});
// Flickity instance
var flkty = $carousel.data('flickity');
// elements
var $cellButtonGroup = $('.button-group--cells');
var $cellButtons = $cellButtonGroup.find('.button');

// update selected cellButtons
$carousel.on( 'select.flickity', function() {
  $cellButtons.filter('.is-selected')
    .removeClass('is-selected');
  $cellButtons.eq( flkty.selectedIndex )
    .addClass('is-selected');
});

// select cell on button click
$cellButtonGroup.on( 'click', '.button', function() {
  var index = $(this).index();
  $carousel.flickity( 'select', index );
});
// previous
$('.button--previous').on( 'click', function() {
  $carousel.flickity('previous');
});
// next
$('.button--next').on( 'click', function() {
  $carousel.flickity('next');
});

/*!
 * Flickity sync v2.0.0
 * enable sync for Flickity
 */

/*jshint browser: true, undef: true, unused: true, strict: true*/

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( [
      'flickity/js/index',
      'fizzy-ui-utils/utils'
    ], factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('flickity'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    window.Flickity = factory(
      window.Flickity,
      window.fizzyUIUtils
    );
  }

}( window, function factory( Flickity, utils ) {

'use strict';

// -------------------------- sync prototype -------------------------- //

// Flickity.defaults.sync = false;

Flickity.createMethods.push('_createSync');

Flickity.prototype._createSync = function() {
  this.syncers = {};
  var syncOption = this.options.sync;

  this.on( 'destroy', this.unsyncAll );

  if ( !syncOption ) {
    return;
  }
  // HACK do async, give time for other flickity to be initalized
  var _this = this;
  setTimeout( function initSyncCompanion() {
    _this.sync( syncOption );
  });
};

/**
 * sync
 * @param {Element} or {String} elem
 */
Flickity.prototype.sync = function( elem ) {
  elem = utils.getQueryElement( elem );
  var companion = Flickity.data( elem );
  if ( !companion ) {
    return;
  }
  // two hearts, that beat as one
  this._syncCompanion( companion );
  companion._syncCompanion( this );
};

/**
 * @param {Flickity} companion
 */
Flickity.prototype._syncCompanion = function( companion ) {
  var _this = this;
  function syncListener() {
    var index = _this.selectedIndex;
    // do not select if already selected, prevent infinite loop
    if ( companion.selectedIndex != index ) {
      companion.select( index );
    }
  }
  this.on( 'select', syncListener );
  // keep track of all synced flickities
  // hold on to listener to unsync
  this.syncers[ companion.guid ] = {
    flickity: companion,
    listener: syncListener
  };
};

/**
 * unsync
 * @param {Element} or {String} elem
 */
Flickity.prototype.unsync = function( elem ) {
  elem = utils.getQueryElement( elem );
  var companion = Flickity.data( elem );
  this._unsync( companion );
};

/**
 * @param {Flickity} companion
 */
Flickity.prototype._unsync = function( companion ) {
  if ( !companion ) {
    return;
  }
  // I love you but I've chosen darkness
  this._unsyncCompanion( companion );
  companion._unsyncCompanion( this );
};

/**
 * @param {Flickity} companion
 */
Flickity.prototype._unsyncCompanion = function( companion ) {
  var id = companion.guid;
  var syncer = this.syncers[ id ];
  this.off( 'select', syncer.listener );
  delete this.syncers[ id ];
};

Flickity.prototype.unsyncAll = function() {
  for ( var id in this.syncers ) {
    var syncer = this.syncers[ id ];
    this._unsync( syncer.flickity );
  }
};

// -----  ----- //

return Flickity;

}));

and here's the pen:

[https://codepen.io/creativezest/pen/BazVMgZ][1]

I would really appreciate any help anyone can give.

Many thanks. Marc

Marc
  • 348
  • 1
  • 3
  • 9

0 Answers0