DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • TDD: From Katas to Production Code
  • Difference Between Bootstrap and AngularJS in 2022
  • How to Bootstrap a Spring Boot Application Using STS (Spring Tool Suite)? | Spring Boot Tutorial
  • The Most Popular Angular UI Libraries To Try in 2021

Trending

  • Introduction to ESP32 for Beginners Using the Xedge32 Lua IDE
  • A Better Web3 Experience: Account Abstraction From Flow (Part 1)
  • Continuous Integration vs. Continuous Deployment
  • Message Construction: Enhancing Enterprise Integration Patterns
  1. DZone
  2. Coding
  3. Frameworks
  4. How to Implement a Smart Chunking Bootstrap Carousel With AngularJS

How to Implement a Smart Chunking Bootstrap Carousel With AngularJS

Read on and learn how to create a "smart chunking carousel" (one that displays the optimal amount of images based on a user's screen size) by following Matt Raible's tutorial.

Matt Raible user avatar by
Matt Raible
·
Mar. 26, 16 · Tutorial
Like (3)
Save
Tweet
Share
13.60K Views

Join the DZone community and get the full member experience.

Join For Free

I've been helping a client develop a project management application for the last several months. One of the features I implemented uses UI Bootstrap's carousel directive to display a list of project templates to choose from when creating a new project. Rather than displaying one at a time, we wanted to display as many as the user's screen would allow. That is, if they were on a large monitor, we wanted to display five templates, a medium size monitor would display three and so on. This is a story of how I implemented a smart chunking carousel.

To begin, I made it possible to show groups of items in the carousel using array chunking.

function chunk(arr, size) {
  var newArr = [];
  var arrayLength = arr.length;
  for (var i = 0; i < arrayLength; i += size) {
    newArr.push(arr.slice(i, i + size));
  }
  return newArr;
}

Using UI Bootstrap's example code, I created $scope.chunkedSlides from $scope.slides.

$scope.chunkSize = 5;

// chunk slides so there's two per chunk by default
$scope.chunkedSlides = chunk($scope.slides, $scope.chunkSize);

Next, I changed the HTML template to read the grouped slides, and show each one.

<uib-carousel active="active" interval="0" no-wrap="true">
  <uib-slide ng-repeat="row in chunkedSlides">
    <div class="row">
      <div ng-repeat="slide in row track by $index" class="slide">
        <img ng-src="{{slide.image}}">
        <div class="carousel-caption">
          <h4>Slide {{slide.id}}</h4>
          <p>{{slide.text}}</p>
        </div>
      </div>
    </div>
  </uib-slide>
</uib-carousel>

This was enough to get five squares on a large monitor.

Image title

However, I wanted to go further and reduce the number per group on smaller monitors. I created aSmartChunking service that defined how many per group for each possible width.

angular.module('app').service('SmartChunking', function() {
  var large = 1600;
  var medium = 1200;
  var small = 1024;
  var xsmall = 800;

  this.getChunkSize = function(width) {
    var chunkSize;
    if (width >= large) {
      chunkSize = 5;
    } else if (width >= medium) {
      chunkSize = 4;
    } else if (width >= small) {
      chunkSize = 3;
    } else if (width >= xsmall) {
      chunkSize = 2;
    } else {
      chunkSize = 1;
    }
    return chunkSize;
  }
});

I wrote a smart-chunking directive to fire an event with the chunk size.

angular.module('app').directive('smartChunking', function($window, SmartChunking) {
  return {
    restrict: 'A',
    link: function($scope) {
      var w = angular.element($window);

      // window.outerWidth works on desktop, screen.height on iPad (width returns 768)
      var width = ($window.outerWidth > 0) ? $window.outerWidth : screen.height;
      var chunkSize = SmartChunking.getChunkSize(width);
      if (chunkSize !== 5) {
        $scope.$emit('change-chunk-size', chunkSize);
      }

      $scope.getWidth = function() {
        return ($window.outerWidth > 0) ? $window.outerWidth : screen.width;
      };

      $scope.$watch($scope.getWidth, function(newValue, oldValue) {
        if (newValue !== oldValue) {
          var chunkSize = SmartChunking.getChunkSize(newValue);
          $scope.$emit('change-chunk-size', chunkSize);
        }
      });

      w.bind('resize', function() {
        $scope.$apply();
      });
    }
  }
});

Then I added a listener for this in the controller that populated the carousel.

$scope.$on('change-chunk-size', function(event, data) {
  if (data !== $scope.chunkSize) {
    $scope.chunkedSlides = chunk($scope.slides, data);
    $scope.chunkSize = data;
  }
});

The final step was adding the smark-chunking directive to each slide and dynamically determining its col-sm-*class.

<div ng-repeat="slide in row track by $index" class="slide" ng-class="getSlideClass(chunkSize)" smart-chunking>

The controller contains a map of classes that map to chunk sizes:

var classMap = {
  5: 'col-sm-2',
  4: 'col-sm-3',
  3: 'col-sm-4',
  2: 'col-sm-5',
};

$scope.getSlideClass = function(chunkSize) {
  if (classMap[chunkSize]) {
    return classMap[chunkSize];
  } else {
    return 'col-sm-10';
  }
}

I did find that adding some CSS made things look quite a bit better.

.carousel-caption {
  padding-bottom: 0;
}

.carousel-control.left,
.carousel-control.right {
  background-image: none;
}

.carousel-indicators {
  display: none;
}

.carousel-inner {
  padding-left: 10%;
  overflow: visible;
}

.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
  font-size: 100px;
  margin-top: -60px;
  font-style: normal;
  font-weight: 100;
}

.carousel-control .glyphicon-chevron-left {
  margin-left: -100px;
}

.carousel-control .glyphicon-chevron-right {
  margin-right: -40px;
}

/* make slide widths more responsive */
@media only screen and (min-width: 1600px) {
  .col-sm-2 {
    width: 18%;
  }
}

@media only screen and (min-width: 1200px) {
  .col-sm-3 {
    width: 22%;
  }
  .carousel-control .glyphicon-chevron-left {
    margin-left: -70px;
  }
  .carousel-control .glyphicon-chevron-right {
    margin-right: -20px;
  }
}

@media only screen and (max-width: 1200px) {
  .col-sm-4 {
    width: 29%;
  }
  .carousel-control .glyphicon-chevron-left {
    margin-left: -70px;
  }
  .carousel-control .glyphicon-chevron-right {
    margin-right: -20px;
  }
}

@media only screen and (max-width: 800px) {
  .col-sm-10 {
    width: 90%;
  }
}

I hope this tip helps you if you need to implement a similar feature. I've published a demo on Plunkr (best experienced in embedded view).

Image title


Bootstrap (front-end framework) Chunking (division)

Published at DZone with permission of Matt Raible, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • TDD: From Katas to Production Code
  • Difference Between Bootstrap and AngularJS in 2022
  • How to Bootstrap a Spring Boot Application Using STS (Spring Tool Suite)? | Spring Boot Tutorial
  • The Most Popular Angular UI Libraries To Try in 2021

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: