Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Creating Resizable Columns in Angular 2

DZone's Guide to

Creating Resizable Columns in Angular 2

In this quick tutorial, we go over how to make column size customizable using the Angular 2 framework, the jQuery library, and a little HTML and CSS.

· Web Dev Zone ·
Free Resource

Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

I am working on HTML table and trying to implement some features using Angular 2 and jQuery.

I prefer primeng components but found a similar solution for resizing the columns for my custom grid.

Initial Table:

First, we need to create header columns. I added a <span> tag in <th> and placed it near the right border.

HTML:

<th>
    <span class="ui-column-resizer"></span>
    <span class="gridHeader">{{ name }}</span>
</th>

CSS:

thead tr th {
  position: relative;
}
span.ui-column-resizer {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  width: 8px;
  height: 100%;
  padding: 0;
  cursor: col-resize;
  border: 1px solid transparent;
}

I highlighted the <span> in the following image.

Adding functionality to grab the table border:

<th>
    <span 
       class = "ui-column-resizer"
       (mousedown) = "onMouseDown($event)">
    </span>
    <span class = "gridHeader">{{ name }}</span>
</th>

Add a (mousedown) event to <span> to grab table border (resizer span element)

private onMouseDown(event){
  this.start = event.target;
  this.pressed = true;
  this.startX = event.x;
  this.startWidth = $(this.start).parent().width();
  this.initResizableColumns();
}

Assign ‘true’ to this.start to start the column resize.

Here we will save the information in variables, such as which column we need to resize and the current width and x-position for the header column. Then call the initResizableColumns() function.

We will use the Angular 2 Renderer to track the mouse move and mouse up events.

import {Component,Renderer} from '@angular/core';

Add the renderer in the constructor

constructor(public renderer: Renderer) {}

Use the initResizableColumns() function :-

private initResizableColumns() {
     this.renderer.listenGlobal('body', 'mousemove', (event) => {
        if(this.pressed) {
           let width = this.startWidth + (event.x - this.startX);
           $(this.start).parent().css({'min-width': width, 'max-   width': width});
           let index = $(this.start).parent().index() + 1;
           $('.glowTableBody tr td:nth-child(' + index + ')').css({'min-width': width, 'max-width': width});
        }
     });
     this.renderer.listenGlobal('body', 'mouseup', (event) => {
     if(this.pressed) {
         this.pressed = false;
     }
   });
}

Bind the mousemove event to track mouse movements and calculate the current width.

let width = this.startWidth + (event.x - this.startX);

Assign the calculated width to <th> i.e. $(this.start).parent()

Now we resized the header column but we need to resize the body column as well.

For that, get the index of the resized header column.

let index = $(this.start).parent().index() + 1;

Then apply the header column width to body column by using nth-child(index).

$('.tableBody tr td:nth-child(' + index + ')').css({'min-width': width, 'max-width': width});

Then bind the moveup event to complete the column resize by making this.pressed ‘false’.

this.renderer.listenGlobal('body', 'mouseup', (event) => {
   if(this.pressed) {
       this.pressed = false;
   }
});

Resized columns:

Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

Topics:
angular 2 ,css ,jquery ,javascript ,web dev ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}