DEV Community

Anower Jahan Shofol
Anower Jahan Shofol

Posted on

How to make a fancy date picker for mobile by Angular Virtual Scrolling

What is virtual scrolling? ๐Ÿ˜•

As per the Angular documentation, it says-

Loading hundreds of elements can be slow in any browser; virtual scrolling enables a performant way to simulate all items being rendered by making the height of the container element the same as the height of the total number of elements to be rendered, and then only rendering the items in view. Virtual scrolling is different from strategies like infinite scroll where it renders a set amount of elements and then when you hit the end renders the rest.

Why I needed this? ๐Ÿ˜ฎ

I am working with a client for building a mobile site and he handed over a fancy date picker for mobile last week. Here was the design-

Date Picker

Designed by - Neeraj Aggarwala

After seeing this I have scratched my hair for a long time and searched if there are some existing solutions online for this. For a bit of time, I was planning to implement it by HammerJs but that didn't work out.

head scratching

Then I started to think differently. The thing I needed was something like an infinite scroll. Then I found Virtual Scrolling Feature of Angular. But, I always have seen this used for vertical scrolling. But, thanks, Angular Material team! Angular material has support for horizontal scrolling too! After some tweaking, I got the result. ๐Ÿ˜ƒ ๐Ÿ˜†

Coding Time!

I am not going through all codes. Just sharing the main parts. You can see the final result and codes here-

This is the main part of the code.

<cdk-virtual-scroll-viewport
 orientation="horizontal" 
 itemSize="60" minBufferPx="400" 
 maxBufferPx="1000" 
 class="example-viewport" 
(scrolledIndexChange)="seeChange($event)">

<div *cdkVirtualFor="let item of items" class="example-item">
   <div class="item" (click)="select(item)" [ngClass]=" 
        {'isactive':item===selectedItem}">
     <span class="weekName">{{returnWeekDay(item)}}</span>
     <span> {{item | date:'d'}}</span>
   </div>
</div>

</cdk-virtual-scroll-viewport>
  • The tag is the container show the long list for virtual scrolling. And setting the origin to horizontal just changed as per my need.
  • Angular's virtual scrolling has a strategy called FixedSizeVirtualScrollStrategy which enhances the performance of the scroller when the elements of the scroller are all of the fixed sizes. Angular says by using this strategy - items do not need to be measured as they are rendered. For this, three parameters are introduced in the code. itemSize=60 (the size of each date box), minBufferPx="400" (minimum amount of content buffer (in pixels) that the viewport must render. I set this to a very low buffer size at first. That worked for android but in iPhone that broke down.) and maxBufferPx="1000" (maximum buffer space to render back up to when it detects that buffer is required)
  • *cdkVirtualFor is the substitute of *ngFor in virtual scrolling.

I couldn't test for all cases. So, your opinions will be appreciated.

Top comments (0)