Please provide full Vue 3 sample for DataGrid custom binding

Hello,

I have great difficulty having the datagrid work with custom binding.

For each add/edit/delete action in the grid, I have a crud-like api call which was tested against Postman.

Data comes back using result/count.  

I am using the DataSourceChanged event like this :

    let state = { skip: 0, take: 10 }
/////
    dataStateChange(state) {
      //load data from backend
      this.dataviewservice.getPagedData('cars', state).then((data) => {
        this.gridData = data
      })
    },
    onDataSourceChanged(state) {
      console.log(state)
      if (state.action==='add') {
        this.dataviewservice.addData('cars', state)
          .then(() => {
            console.log('Car added successfully')
            state.endEdit()
          })
      } else if (state.action==='edit') {
        this.dataviewservice.updateData('cars', state)
          .then(() => {
            console.log('Car updated successfully')
            state.endEdit()
          })
      } else if (state.requestType==='delete') {
        this.dataviewservice.deleteData('cars', state)
          .then(() => {
            console.log('Car deleted successfully')
            state.endEdit()
          })
      }
    },

All three actions are performed correctly on the server side.

The Edit returns instantly but Add and Delete have the spinner hanging.

Please provide a full sample for Vue 3 DataGrid custom binding.

Thank you 


4 Replies

RR Rajapandi Ravi Syncfusion Team September 15, 2021 01:19 PM UTC

Hi Julien, 

Greetings from syncfusion support 

Before start providing solution on your query, we would like to share our Custom Binding feature behavior.  

For using custom binding, you need to bind the response data(Grid data) returned from your API as an object of result(JSON data source) and count(Total data count) properties and set it to the Grid’s dataSource property. On setting the data source in this format, the ‘dataStateChange’ event will be triggered with corresponding query for every Grid action performed like Paging, Sorting and Filtering..,etc.  
  
The dataSourceChanged event will be triggered for updating the grid data. You can perform the save operation based on the event arguments and you need to call the endEdit method to indicate the completion of save operation and call the cancelEdit method if the server operation fails.  
 
So please ensure to define this event in the Grid and we have also explained this event’s action below for your understanding,  
  
On performing CRUD action in the Grid, the action details will be returned in the dataSourceChanged event as shown in the below image, 
 
 
 
So, in this event you can update the details in your server and on success of this action you need to call the state’s(The dataSourceChanged event argument) endEdit method in order to update the changes in the Grid(This will trigger the dataStateChange event which will fetch the updated data from the server).  
  
This is demonstrated in the below code snippet,  
  
// Grid’s dataStateChange event handler  
dataSourceChanged: function (state) {  
    if (state.action === 'add') {  
        addOrder(state.data).then(() => state.endEdit());  
    } else if (state.action === 'edit') {  
        updateOrder(state.data).then(() => { state.endEdit() });  
    } else if (state.requestType === 'delete') {  
        deleteOrder(state.data[0].OrderID).then(() => state.endEdit());  
    }  
}  
  
We have prepared a sample based on this with local server(to fetch data) for your reference. Please find it below,  
  
 
More details on custom binding can be checked in the below help documentation link,  
  
 
                                                            https://ej2.syncfusion.com/vue/documentation/grid/data-binding/#perform-crud-operations 
  
  
 


Regards, 
Rajapandi R 



JH Julien Hoffmann September 16, 2021 08:38 AM UTC

Hello,

Thank you for this long explanation. I eventually managed to get this working.

Based on the same sample, how should I do to have one my columns as a foreign key ?

I would like to have the foreign values be fetched through an API. I have played around with column datasource, edit property, refreshColumns, etc... In all situations, I have the foreign value displayed correctly, but the dropdownlist in edit mode is never populated.


image_4.png

I have also filed the same issue today on a sample you had provided for a similar React issue.

Thanks,

Julien



JH Julien Hoffmann September 17, 2021 08:18 AM UTC

Hi,

Thanks to your reply to a similar question in React forum, this is solved by using the following code:


this.$refs.theGrid.getColumnByField('constituentId').dataSource = ds
this.$refs.theGrid.getColumnByField('constituentId').edit.params.dataSource = ds
this.$refs.theGrid.refreshColumns()


Julien



RR Rajapandi Ravi Syncfusion Team September 17, 2021 12:34 PM UTC

Hi Julien, 

Thanks for the update 

Since you were using custom binding for the grid dataSource, so we suggest you use the same thing for the ForeignKey dataSource.  

We have prepared a simple sample with the grid having custom binding for both the grid and foreignKey column. By default, foreign key column maps the foreignKeyField value based on the column field value and returns the appropriate foreignKeyValue to the grid. So, mapping requires whole data of the foreignKey dataSource. 

Follow the below steps to achieve custom binding in foreignKey column. 

  1. Bind the events dataStateChange and columnDataStateChange to the grid.
  2. The dataStateChange event is used to bind the custom data to the grid. here you can execute your own service and return the data with result and count pair.
  3. The columnDataStateChange event is used to bind the custom data to the grid’s foreignKey column datasource. here you can execute your own service and return the data with result and count pair. Since the foreignkey mapping requires whole data so return all the data (instead of current page) to the grid.

Code Example: 


<template> 
    <div id="grid_parent"> 
        <ejs-grid 
        ref="grid" 
        id="transaction_grid" 
        :dataSource="data" 
        allowPaging='true' 
        :dataSourceChanged="dataSourceChanged" 
        :dataStateChange="dataStateChange" 
        :columnDataStateChange='columnStateChange' 
        :editSettings="editSettings" 
        :toolbar='toolbar' 
      > 
        <e-columns> 
          .  .  .  .  .  .  .  .  . 
          .  .  .  .  .  .  .  .  . 
          <e-column field= "EmployeeID" headerText="Employee ID" foreignKeyValue="FirstName" :dataSource="colData" width="150"></e-column> 
          .  .  .  .  .  .  .  .  . 
         .  .  .  .  .  .  .  .  . 
        </e-columns> 
      </ejs-grid> 
    </div> 
</template> 
<style> 

</style> 
<script> 
import Vue from "vue"; 
import { GridPlugin, Page, Toolbar, Edit, ForeignKey } from "@syncfusion/ej2-vue-grids"; 
import { getOrders, addOrder, updateOrder, deleteOrder } from "./orderService"; 
import { EmployeeService } from "./EmployeeService"; 

Vue.use(GridPlugin); 

export default { 
  name: 'app', 
  data() { 
    return { 
      data: {}, 
      colData: {}, 
      editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true }, 
      toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
      employeeService: new EmployeeService(), 
    }; 
  }, 
  mounted() { 
    let state = { skip: 0, take: 12 }; 
    this.dataStateChange(state); 
    this.columnStateChange({setColumnData:this.$refs.grid.ej2Instances.setForeignKeyData.bind(this.$refs.grid.ej2Instances)}) 
  }, 
 methods: { 
    dataStateChange: function (state) { 
      getOrders().then(gridData => { 
        this.data = gridData; 
        } 
      ); 
    }, 
    columnStateChange: function (state) { 
        this.employeeService.execute(state).then(( gridData ) => { 
          console.log(gridData); 
          //instance.ref.grid.columns[1].dataSource = gridData; 
          this.colData = gridData; 
          state.setColumnData(); 
         } ); 
    }, 
    dataSourceChanged: function (state) { 
      if (state.action === 'add') { 
        addOrder(state.data).then(() => state.endEdit()); 
      } else if (state.action === 'edit') { 
        updateOrder(state.data).then(() => { state.endEdit()}); 
      } else if (state.requestType === 'delete') { 
        deleteOrder(state.data[0].OrderID).then(() => state.endEdit()); 
      } 
    } 
  }, 
  provide: { 
    grid: [Page, Toolbar, Edit, ForeignKey], 
  }, 
</script> 


Refer the below sample for more information. 




Screenshot: 

 

Please get back to us if you need further assistance on this. 

Regards, 
Rajapandi R 


Loader.
Up arrow icon