Angular 14 Draggable Grid Blocks using angular-gridster2 Tutorial

In this angular tutorial, we will discuss how to create dynamic draggable grid boxes using the angular-gridster2 library in Angular application.

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, Angular 12 and Angular 13

A gridster is a UI component, having draggable and resizable grid boxes. Such kind of components can have multiple use-cases like sorting of items, solving puzzels, priortizing sections etc.

Angular Gridster 2 helps in creating robust draggable sections which support number of configurations. We can easily setup a grid and dynamically add or remove grid sections at realtime. Moreover, the gridster supports mobile layout and small screens as well.


How to Add Draggable Gridster in Angular using angular-gridster2 ?

Step 1 – Create Angular App

Step 2 – Install Angular Gridster 2 Library

Step 3 – Add Dynamic Grid

Step 4 – Add Configuration

Step 5 – See In Action


Step 1 – Create Angular App

Before we start creating Angular app, make sure you have installed latest version of Angular CLI tool:

npm install -g @angular/cli


Now create a new Angular application by executing below ng command with the name provided:

ng new my-angular-app


Move inside the application directory:

cd my-angular-app


Step 2 – Install Angular Gridster 2 Library

Head towards the terminal and install the Angular Gridster 2 library by executing below command at the root path:

npm install angular-gridster2 --save


After installing the package library, we need to import the required module to use its components inside our Angular application. Open the app.module.ts file and update the imports array with GridsterModule

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { GridsterModule } from "angular-gridster2";

import { AppComponent } from "./app.component";

  imports: [BrowserModule, FormsModule, GridsterModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
export class AppModule {}


Step 3 – Add Dynamic Grid

Now, we will setup the Gridster HTML template. Open the app.component.html file and add the <gridster> and <gridster-item> component with required properties:

<button (click)="addItem()">Add New</button>
<gridster [options]="options">
  <gridster-item [item]="item" *ngFor="let item of dashboard">
    <div class="button-holder">
      <div class="gridster-item-content" *ngIf="item.hasContent">
        <div class="stuff">
          <img src="..logo.png">
      <div class="item-buttons" *ngIf="item.hasContent">
        <button class="remove-button" (mousedown)="removeItem($event, item)" (touchstart)="removeItem($event, item)">
      <label *ngIf="!item.hasContent">{{ item.label }}</label>
      <button *ngIf="!item.hasContent" (mousedown)="removeItem($event, item)" (touchstart)="removeItem($event, item)">

We have added few action button and content elements like image which are optional. The action buttons include Add and Delete button to call the methods defined inside the component class.

Inside the [options] object we can configure variour options for the gridster as a whole.


Step 4 – Add Configuration

Open the app.component.ts class file and add the options and methods required for the gridstere to populate grid sections and handle actions buttons:

import { Component, VERSION } from "@angular/core";
import {
} from "angular-gridster2";

interface Safe extends GridsterConfig {
  draggable: Draggable;
  resizable: Resizable;
  pushDirections: PushDirections;

  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
export class AppComponent {
  name = "Angular " + VERSION.major;
  options: Safe;
  dashboard: Array<GridsterItem>;

  ngOnInit(): void {
    this.options = {
      gridType: GridType.Fit,
      compactType: CompactType.None,
      margin: 5,
      outerMargin: true,
      outerMarginTop: null,
      outerMarginRight: null,
      outerMarginBottom: null,
      outerMarginLeft: null,
      useTransformPositioning: true,
      mobileBreakpoint: 640,
      useBodyForBreakpoint: false,
      minCols: 1,
      maxCols: 100,
      minRows: 1,
      maxRows: 100,
      maxItemCols: 100,
      minItemCols: 1,
      maxItemRows: 100,
      minItemRows: 1,
      maxItemArea: 2500,
      minItemArea: 1,
      defaultItemCols: 1,
      defaultItemRows: 1,
      fixedColWidth: 105,
      fixedRowHeight: 105,
      keepFixedHeightInMobile: false,
      keepFixedWidthInMobile: false,
      scrollSensitivity: 10,
      scrollSpeed: 20,
      enableEmptyCellClick: false,
      enableEmptyCellContextMenu: false,
      enableEmptyCellDrop: false,
      enableEmptyCellDrag: false,
      enableOccupiedCellDrop: false,
      emptyCellDragMaxCols: 50,
      emptyCellDragMaxRows: 50,
      ignoreMarginInRow: false,
      draggable: {
        enabled: true,
      resizable: {
        enabled: true,
      swap: false,
      pushItems: true,
      disablePushOnDrag: false,
      disablePushOnResize: false,
      pushDirections: { north: true, east: true, south: true, west: true },
      pushResizeItems: false,
      displayGrid: DisplayGrid.Always,
      disableWindowResize: false,
      disableWarnings: false,
      scrollToNewItems: false,

    this.dashboard = [
      { cols: 4, rows: 1, y: 0, x: 0 },
      { cols: 2, rows: 2, y: 0, x: 2, hasContent: true },
        cols: 2,
        rows: 2,
        y: 3,
        x: 5,
        minItemRows: 2,
        minItemCols: 2,
        label: "Min rows & cols = 2",
        cols: 2,
        rows: 1,
        y: 2,
        x: 2,
        dragEnabled: true,
        resizeEnabled: true,
        label: "Drag&Resize Enabled",
        cols: 1,
        rows: 1,
        y: 2,
        x: 4,
        dragEnabled: false,
        resizeEnabled: false,
        label: "Drag&Resize Disabled",
      { cols: 1, rows: 1, y: 2, x: 6 },

  changedOptions(): void {
    if (this.options.api && this.options.api.optionsChanged) {

  removeItem($event: MouseEvent | TouchEvent, item): void {
    this.dashboard.splice(this.dashboard.indexOf(item), 1);

  addItem(): void {
    this.dashboard.push({ x: 0, y: 0, cols: 1, rows: 1 });

Step 5 – See In Action

After adding the required changes, run your Angular application by hitting the following command:

npm start

This will start the development webserver at local at the following URL:



Notify of

Inline Feedbacks
View all comments