Skip to main content Skip to footer

Pasting Images into FlexGrid in Angular

FlexGrid with image pasted inside

Background:

FlexGrid has built-in clipboard support that handles text and numeric data when pasting. You can also capture the paste before it’s processed and handle it yourself, for example, to accept image data from the system clipboard and insert it into a cell.

Steps to Complete:

  1. Disable the grid’s built-in clipboard behavior so we can intercept paste events.
  2. Attach a paste DOM event handler to catch image paste data from the clipboard.
  3. Detect image files in the clipboard data and convert them to a displayable URL.
  4. Insert the image into the grid cell (e.g., using grid.setCellData or a cell template).

Getting Started:

Disable the grid’s built-in clipboard behavior so we can intercept paste events

By default, pressing Ctrl+V pastes plain text into the grid. We turn this off (autoClipboard = false) so we can handle pasting manually. Then we attach a standard DOM paste event on the grid host.

<!-- app.component.html -->
<wj-flex-grid
  #grid
  [itemsSource]="data"
  [autoClipboard]="false"
  style="height: 400px; width: 100%;">
</wj-flex-grid>

<p *ngIf="pasteMessage">{{ pasteMessage }}</p>
// app.component.ts
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { FlexGrid } from '@mescius/wijmo.angular2.grid';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements AfterViewInit {
  @ViewChild('grid', { static: true }) grid: FlexGrid;
  data = this.getData();
  pasteMessage: string | null = null;

  ngAfterViewInit() {
    // Listen for native paste events
    this.grid.hostElement.addEventListener('paste', this.onPaste.bind(this));
  }

  getData() {
    return [
      { id: 1, name: 'Item 1', image: '' },
      { id: 2, name: 'Item 2', image: '' }
    ];
  }
}

 

Attach a paste DOM event handler to catch image paste data from the clipboard

The browser clipboard API exposes e.clipboardData.items, which can contain files or text. If an image file is present (item.kind === 'file' && item.type.startsWith('image/')), we convert it to a Base64 URL and update the grid cell. Otherwise we let text fall through.

// app.component.ts (continued)
onPaste(e: ClipboardEvent) {
  if (!e.clipboardData) {
    return;
  }

  const items = Array.from(e.clipboardData.items);
  const imageItem = items.find(i => i.kind === 'file' && i.type.startsWith('image/'));

  if (imageItem) {
    e.preventDefault();

    const blob = (imageItem as any).getAsFile();
    const reader = new FileReader();

    reader.onload = () => {
      const url = reader.result as string;
      this.insertImageIntoCell(url);
      this.pasteMessage = 'Image pasted successfully.';
    };

    reader.readAsDataURL(blob);
  }
}

 

Detect image files in the clipboard data and convert them to a displayable URL

Once we get a base64 image URL, we write it into the grid’s data item. The simplest approach is to store the URL in a field (e.g., image) that’s bound to a custom cell template. Then the image appears in the cell.

// app.component.ts (continued)
insertImageIntoCell(imgUrl: string) {
  const grid = this.grid;
  const sel = grid.selection;

  if (sel.row > -1 && sel.col > -1) {
    // Assume the 'image' field exists on the data item
    grid.setCellData(sel.row, 'image', imgUrl, true);
  }
}

 

Insert the image into the grid cell (e.g., using grid.setCellData or a cell template)

A basic string URL doesn’t show a picture on its own; we use a cellTemplate to render an <img> tag. Binding names like 'image' refer to that cell’s data field:

<wj-flex-grid
  #grid
  [itemsSource]="data"
  [autoClipboard]="false"
  style="height: 400px; width: 100%;">
  <wj-flex-grid-column
    header="Photo"
    binding="image"
    [cellTemplate]="imageTemplate"
    width="120">
  </wj-flex-grid-column>
</wj-flex-grid>

<ng-template #imageTemplate let-item let-col="col">
  <img *ngIf="item[col.binding]" [src]="item[col.binding]" style="max-width: 100px;" />
</ng-template>

 

With this Angular setup:

  • Users can press Ctrl+V or invoke a paste action while a grid cell is selected.
  • If the clipboard contains an image, it’s inserted into the selected cell’s image field.
  • The bound cell template renders the pasted image.
  • You can extend this system to accept multiple images, validate file size/type, or prompt the user before insertion.

Happy coding!

Andrew Peterson

Technical Engagement Engineer