How to select elements on multiple pages of grid using server-side paging?

Hi there,

I have a grid that uses server-side paging to handle long data sets. My requirement is to allow selecting of multiple elements spread across several pages. I've implemented this by maintaining an array of selected element ids (managed from the rowSelected/rowDeselected events). I then watch for rowDataBound events where I check if the row element is one of the selected ones. If so, I record it's index in another array. Then in the dataBound event handler, I iterate through this index array and select the appropriate rows. This works great except when I change pages in the grid rowDeselect events are being fired for each selected row. This results in elements selected on other pages being lost.

My question is if there's a way to disable the rowDeselected events on data source updating? I tried setting a flag in the dataSourceChanged event (cleared in dataBound event) that the rowDeselected handler checks before doing anything but the rowDeselected event is still occasionally being fired (not for all selected fields).

Or maybe there's a better approach for this?

Here's my current code with the flag for rowDeselected processing.

<template>
  <ejs-grid ref="regionGrid" :dataSource="regionDataSource" 
    :allowPaging="true" :allowSorting="true" :allowSearch="true" :pageSettings="gridSettings.pageSettings" :toolbar="gridSettings.toolbar"
    :rowSelected="onRegionSelect" :rowDeselected="onRegionDeselect" :dataBound="onRegionDatabound" :rowDataBound="onRegionRowDatabound" :dataSourceChanged="onRegionDatasourceChanged">
    <e-columns>
      <e-column type='checkbox' width='50'></e-column>
      <e-column field="name" headerText="Region Name"></e-column>
    </e-columns>
  </ejs-grid>
</template>

<script>
import { Page, Sort, Toolbar } from '@syncfusion/ej2-vue-grids';
import DataManager from '@/util/dataManager';

export default {
  provide: {
    grid: [Page, Sort, Toolbar]
  },
  data: function() {
    return {
      gridSettings: {
        toolbar: ['Search'],
        pageSettings: { pageSize: 8 }
      },

      tempSelectedRegions: [],
      tempSelectedRegionIndexes: [],
      initializingRegions: false,
    }
  },
  computed: {
    regionDataSource() {
      return DataManager.create('regions/indexdatatable');
    }

  },
  methods: {
    // Region grid events
    onRegionSelect(args) {
      if (this.tempSelectedRegions.indexOf(args.data.id) === -1)
        this.tempSelectedRegions.push(args.data.id);
    },
    onRegionDatasourceChanged() {
      this.initializingRegions = true;
    },
    onRegionDeselect(args) {
      if (this.initializingRegions)
        return;

      // Get the index of the item in the array
      const index = this.tempSelectedRegions.indexOf(args.data.id);
      if (index !== -1)
        this.tempSelectedRegions.splice(index, 1);
    },
    onRegionRowDatabound(args) {
      if (this.tempSelectedRegions.find(i => i === args.data.id)) {
        this.tempSelectedRegionIndexes.push(parseInt(args.row.getAttribute('aria-rowindex')));
      }
    },
    onRegionDatabound() {
      if (this.tempSelectedRegionIndexes.length) {
        this.tempSelectedRegionIndexes.forEach(i => {
          this.$refs.regionGrid.selectRow(i);
        });
      }
      
      // Clear the index
      this.tempSelectedRegionIndexes = [];
      this.initializingRegions = false;
    }
  }
}
</script>

3 Replies 1 reply marked as answer

RS Rajapandiyan Settu Syncfusion Team November 19, 2020 11:41 AM UTC

Hi Jason, 
 
Based on your requirement, you need to maintain selection in your Grid while performing paging action. 
 
By default, the EJ2 Grid having persistSelection feature support. In which, the row Selections are maintained when navigating the pages. You can achieve your requirement by enabling persistSelection as true in the Grid’s selectionSettings
 
If ‘persistSelection’ set to true, then the Grid selection is persisted on all operations. For persisting selection in the Grid, any one of the column should be enabled as a primaryKey and the Grid must have checkbox type column. Refer to the below code example and sample for your reference. 
 
 
 
<template> 
  <div class="col-lg-12 control-section"> 
    <div> 
      <ejs-grid 
        ref="grid" 
        id="transaction_grid" 
        :dataSource="data" 
        height="300" 
        :allowPaging="true" 
        :selectionSettings="selectionOptions" 
        :dataStateChange="dataStateChange" 
      > 
        <e-columns> 
          <e-column field="checkBox" type="checkbox" width="130"></e-column> 
          <e-column 
            field="OrderID" 
            headerText="Order ID" 
            width="130" 
            :isPrimaryKey="true" 
            textAlign="Right" 
          ></e-column> 
          -------- 
        </e-columns> 
      </ejs-grid> 
    </div> 
  </div> 
</template> 
<script> 
------- 
export default Vue.extend({ 
  data() { 
    return { 
      data: {}, 
      selectionOptions: { persistSelection: true }, 
      orderService: new OrderService(), 
    }; 
  }, 
  mounted() { 
    // Used vue mounted hook to provide dataSource to Grid and handled the initial paging 
    let state = { skip: 0, take: 12 }; 
    this.dataStateChange(state); 
  }, 
  methods: { 
dataStateChange: function (state) { 
      // Handled the other Grid actions like paging, sorting etc.. by using dataState change event 
      this.orderService.execute(state).then((gridData) => { 
        this.data = gridData; 
      }); 
    }, 
  }, 
------ 
}); 
</script> 
 
 
 
Please get back to us if you need further assistance with this.   
 
Regards, 
Rajapandiyan S 


Marked as answer

JA Jason November 19, 2020 04:58 PM UTC

Wow, thanks, that's exactly what I needed! I somehow missed any mention of that setting in the docs.

Jason


RS Rajapandiyan Settu Syncfusion Team November 20, 2020 11:47 AM UTC

Hi Jason, 
 
We are glad that you have achieved your requirement by using the given solution. 
 
Regards, 
Rajapandiyan S 


Loader.
Up arrow icon