4

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?

2 Answers2

4

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

Debug Diva
  • 26,058
  • 13
  • 70
  • 123
  • 1
    thanks for your answer @Rohit Jindai :) Unfortunately the row manipulation looks pretty hacky. I'm hoping for a "native" solution ... ( wasn't able to find one in the docs tough ... ) –  Jul 04 '22 at 06:05
  • @baitendbidz I created this working demo by taking the reference from docs only and there is no harm to use this solution. In docs those are straight forward solutions but our case is different. That's the reason i came up with customized one. – Debug Diva Jul 04 '22 at 06:31
0

Are you sure row-spanning will not work? Can you try to implement this?

function rowSpan(params) {
  const person = params.data.person;
  return rowData.value.filter((e) => e.person === person).length;
}

const columnDefs = ref([
  {
    field: "person",
    rowSpan: rowSpan,
  },
  {
    field: "car",
  },
]);
TymoteuszLao
  • 844
  • 1
  • 5
  • 16
  • 1
    I implemented `rowSpan: params => rowData.value.filter((e) => e.person === params.data.person).length` and nothing changed. Although when logging the length: 3 times 3, 1 time 1 and 2 times 2 ( as expected ) –  Jun 29 '22 at 11:45
  • @baitendbidz Do you have suppressRowTransform set to "true" in gridOptions? – TymoteuszLao Jun 29 '22 at 11:59
  • yes, I added `:suppress-row-transform="true"` to the grid component but that didn't help –  Jun 29 '22 at 12:06