skip to Main Content

I’m looking for advice on creating a blur overlay div to cover a specific column in a table. I want the overlay to show the header while hiding the cells in that column. It’s important that the overlay moves along with resizable columns and persists across pagination changes. How can I ensure the overlay remains in place and resizes properly with the columns? I want to write a text over the blur (so i need an overlayed div element). Think of it like a cover that hides the column underneath. Thank you for your help! I managed to put the overlay div on top of the columns and used

table.on("columnResized", positionOverlay);

yet, with this event, the resize is updated after the mouse movement has ended. It does not simultaneously move with the columns.

And here is my positionOverlay function. Thank you for your help.

    function positionOverlay() {
        const overlay = document.getElementById("overlay");
        const tableElement = document.querySelector(".tabulator-tableholder");
        const column = table.getColumn("someColumn");
        const cellElement = column.getCells()[0]?.getElement();
  
            const rect = cellElement.getBoundingClientRect();
            const tableRect = tableElement.getBoundingClientRect();

            overlay.style.width = rect.width + "px";
            overlay.style.height = tableRect.height + "px";
            overlay.style.left = rect.left + "px";
            overlay.style.top = 34 + "px"; 
            overlay.style.display = "flex";
    }

2

Answers


  1. You might don’t need JavaScript, checkout the new CSS function anchor():

    But be aware of its coverage, it could be a valid option in the future, using it on production is NOT advised at this moment.

    body {
      background-color: #ccc;
    }
    
    .table {
      overflow: hidden;
      background-color: white;
      border: solid 1px rgba(0, 0, 0, 0.1);
      resize: both;
      anchor-name: --anchor-table;
      
      th, td {
        vertical-align: middle;
        padding: 4px 10px;
      }
    }
    
    .blur-column {
      anchor-name: --anchor-blur-column;
    }
    
    .blur {
      position: absolute;
      z-index: 1;
      top: anchor(--anchor-blur-column bottom);
      left: anchor(--anchor-blur-column left);
      right: anchor(--anchor-blur-column right);
      bottom: anchor(--anchor-table bottom);
      background-color: rgba(0, 0, 0, 0.1);
      backdrop-filter: blur(5px);
    }
    <div class="blur"></div>
    <table class="table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Email</th>
          <th class="blur-column">API Key</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>Alice</td>
          <td>[email protected]</td>
          <td>9A10F92C11E4B</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>2</td>
          <td>Bob</td>
          <td>[email protected]</td>
          <td>8B29C93D13E5A</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>3</td>
          <td>Charlie</td>
          <td>[email protected]</td>
          <td>7C38D04E14F6C</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>4</td>
          <td>David</td>
          <td>[email protected]</td>
          <td>6D47E15F15G7B</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>5</td>
          <td>Eve</td>
          <td>[email protected]</td>
          <td>5E56F26G16H8A</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>6</td>
          <td>Frank</td>
          <td>[email protected]</td>
          <td>4F67G37H17I9C</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>7</td>
          <td>Grace</td>
          <td>[email protected]</td>
          <td>3G78H48I18J1B</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>8</td>
          <td>Hank</td>
          <td>[email protected]</td>
          <td>2H89I59J19K2A</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>9</td>
          <td>Ivy</td>
          <td>[email protected]</td>
          <td>1I90J60K20L3C</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Delete</a>
          </td>
        </tr>
        <tr>
          <td>10</td>
          <td>Jack</td>
          <td>[email protected]</td>
          <td>0J01K71L21M4B</td>
          <td>
            <a href="#">View</a>
            <a href="#">Edit</a>
            <a href="#">Resize ↘</a>
          </td>
        </tr>
      </tbody>
    </table>
    Login or Signup to reply.
  2. One approach could be to use the column formatter to apply a blur effect to each cell using filter css property. This won’t work with IE but otherwise widely implemented. Couple ways to this:

    1. Add an overlay div, as you suggested, to each cell element (Gender column below)
    2. Directly add the blur to cell element (Color column below)

    Please note this is a visual effect only. Users can still get the blurred data if they really wanted, using Dev Tools for example.

    const data = [
      { id: 1, name: 'Billy Bob', age: '12', gender: 'male', height: 1, col: 'red', dob: '', cheese: 1 },
      { id: 2, name: 'Mary May', age: '1', gender: 'female', height: 2, col: 'blue', dob: '14/05/1982', cheese: true },
      { id: 10, name: 'Margret Marmajuke', age: '16', gender: 'female', height: 5, col: 'yellow', dob: '31/01/1999' }
    ]
    
    const table = new Tabulator('#table', {
      data: data,
      columns: [
        { title: 'Name', field: 'name' },
        { title: 'Age', field: 'age' },
        { title: 'Gender',
          field: 'gender',
          formatter: (cell, formatterParams, onRendered) => {
            onRendered(() => {
              const overlay = document.createElement('div')
              overlay.classList.add('overlay')
              
              cell.getElement().appendChild(overlay)
            });
            
            return cell.getValue()
          }
        },
        { title: 'Height', field: 'height' },
        { 
          title: 'Color',
          field: 'col',
          formatter: (cell, formatterParams, onRendered) => {
            cell.getElement().style.filter = 'blur(4px)'
            
            return cell.getValue()
          }
        }
      ]
    })
    .overlay {
      position: absolute;
      top: 0;
      right:0;
      bottom: 0;
      left:0;
      background-color: rgba(255, 255, 255, 0.1);
      backdrop-filter: blur(4px);
      z-index: 1000;
      user-select: none;
    }
    <link href="https://unpkg.com/[email protected]/dist/css/tabulator.min.css" rel="stylesheet" />
    <script type="text/javascript" src="https://unpkg.com/[email protected]/dist/js/tabulator.min.js"></script>
    
    <div id="table"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search