Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge cells in a single column?

Given the sample code using ag-grid with Vue 3

<script setup lang="ts">
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";
import { AgGridVue } from "ag-grid-vue3";
import { ref } from "vue";

const columnDefs = ref([
  {
    field: "person",
  },
  {
    field: "car",
  },
]);

const rowData = ref([
  {
    person: "person-1",
    car: "car-1",
  },
  {
    person: "person-1",
    car: "car-2",
  },
  {
    person: "person-1",
    car: "car-3",
  },
  {
    person: "person-2",
    car: "car-4",
  },
  {
    person: "person-3",
    car: "car-5",
  },
  {
    person: "person-3",
    car: "car-6",
  },
]);
</script>

<template>
  <ag-grid-vue
    style="width: 500px; height: 500px"
    class="ag-theme-alpine"
    :columnDefs="columnDefs"
    :rowData="rowData"
  >
  </ag-grid-vue>
</template>

You will get the following output

enter image description here

I could group the table based on person but is there a way to merge cells in a single column?

enter image description here

I think I can't use row-spanning for a single column definition because inside the rowSpan function it is not possible to tell ag-grid to combine multiple cells of a single column.

Any ideas?


1 Answers

After spending a few hours on this requirement, I came up with the solution.

Here are the steps which I performed :

  • To implement rowSpan, You have to manipulate the rowData so that it will contain the person property only in the first occurance object. As a result, When we will apply the rowSpan based on the length it will not take that length for each same person name. This is how I manipulated the rowData :

        const uniq = {};
        const rowData = [{
          person: "person-1",
          car: "car-1",
        }, {
          person: "person-1",
          car: "car-2",
        }, {
          person: "person-1",
          car: "car-3",
        }, {
          person: "person-2",
          car: "car-4",
        }, {
          person: "person-3",
          car: "car-5",
        }, {
          person: "person-3",
          car: "car-6",
    }];
    
    rowData.forEach(obj => {
        !uniq[obj.person] ? uniq[obj.person] = true : delete obj.person;
    });
    
    console.log(rowData);
  • Now, Created a rowSpan function which is basically used to return the length of the objects contains occurrence of same person names.

    function rowSpan(params) {
      const person = params.data.person;
      const gridData = getData(); // getData() with return the original rowData array.
      return gridData.filter((e) => e.person === person).length;
    }
    
  • At the end, for styling the rowSpan columns. I used these styles (refer from here)

    .show-cell {
      background: white;
      border-left: 1px solid lightgrey !important;
      border-right: 1px solid lightgrey !important;
      border-bottom: 1px solid lightgrey !important;
    }
    

    This is how the columnDefs for person object looks like :

    {
      field: "person",
      rowSpan: rowSpan,
      cellClassRules: { 'show-cell': 'value !== undefined' }
    }
    

Live Demo : Row Spanning Demo

like image 136
Creative Learner Avatar answered Oct 19 '25 10:10

Creative Learner