We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Dynamically Create New Grid Based on Current Result

Hi,

I like to create a new grid dynamically based on current result in another grid, for instance as a result of filtering.

So step by step:
  1. I have a data grid filled with data.
  2. This data is filtered (using filter menu for instance).
  3. User clicks on a button (i.e. "Copy result to new grid") to create new grid.
  4. New grid is dynamically added to page (for instance into a new tab).
So the main question I have here is how to create a data grid dynamically without having to setup/configure the grid in HTML first.

Thanks,
Marius


13 Replies

MS Manivel Sellamuthu Syncfusion Team August 20, 2019 09:25 AM UTC

Hi Marius, 

Thanks for contacting us. 

From your query we can understand that you want to create a grid dynamically. We have prepared a sample based on your requirement in that sample, on a button click we have created a grid dynamically which consists of the filtered data of the previous grid. 

Please find the below code example and sample for more information. 


App.vue 

<template> 
  <div id="app"> 
    <button v-on:click="Click">Result</button> 
    <ejs-grid 
      ref="grid" 
      :dataSource="data" 
      :pageSettings="pageOption" 
      :allowFiltering="true" 
      :filterSettings="filterOptions" 
      allowPaging="true" 
    > 
      <e-columns> 
        <e-column field="OrderID" headerText="Order ID" textAlign="Right" width="100"></e-column> 
        <e-column field="CustomerID" headerText="Customer ID" width="120"></e-column> 
        <e-column field="ShipCity" headerText="Ship City" width="100"></e-column> 
        <e-column field="ShipName" headerText="Ship Name" width="100"></e-column> 
      </e-columns> 
    </ejs-grid> 
    <div id="head">Fitlered Data 
      <div id="Grid"></div>    // add the selector in template 
    </div> 
  </div> 
</template> 
<script> 
import Vue from "vue"; 
import { GridPlugin, Grid, Filter, Page } from "@syncfusion/ej2-vue-grids"; 
import { data } from "./datasource.js"; 
import { DataManager } from "@syncfusion/ej2-data"; 
Vue.use(GridPlugin); 

export default { 
  data() { 
    return { 
      data: data, 
      grid: "", 
      flag: true, 
      pageOption: { 
        pageSize: 3 
      }, 
      filterOptions: { 
        type: "Menu" 
      } 
    }; 
  }, 
  methods: { 
    Click: function(e) { 
      if (this.flag) { 
        Grid.Inject(Page); 
// creating a grid model 
        this.grid = new Grid({ 
          allowPaging: true, 
          pageSettings: { pageSize: 3 }, 
          columns: [ 
            { 
              field: "OrderID", 
              headerText: "Order ID", 
              textAlign: "Right", 
              width: 120, 
              type: "number" 
            }, 
            { 
              field: "CustomerID", 
              width: 140, 
              headerText: "Customer ID", 
              type: "string" 
            }, 
            { 
              field: "ShipCity", 
              headerText: "Ship City", 
              textAlign: "Right", 
              width: 120 
            }, 
            { field: "ShipName", headerText: "Ship Name", width: 140 } 
          ] 
        }); 

        this.grid.appendTo("#Grid");   //appending to the selector 
        this.flag = false; 
      } 
      let query = this.$refs.grid.ej2Instances.renderModule.data.generateQuery( 
        true 
      ); // get grid corresponding query by skipping page query 
      new DataManager({ json: data }) 
        .executeQuery(query) 
        .then(e => { 
          this.grid.dataSource = e.result; //apply the filtered data of the previous grid to the dynamically created grid 
        }) 
        .catch(e => true); 
    } 
  }, 
  provide: { 
    grid: [Filter, Page] 
  } 
}; 
</script> 

<style> 
</style> 


Please get back to us, if you need further assistance. 

Regards, 
Manivel 



ML Marius Lian August 21, 2019 10:56 AM UTC

Hi Manivel,

Thank you for this very detailed and good answer!

I tried it and it worked perfectly.

I just have one follow-up question:
Where can I find more documentation about how *.generateQuery works?

Thanks,
Marius


MS Manivel Sellamuthu Syncfusion Team August 22, 2019 01:02 PM UTC

Hi Marius, 

Thanks for your update. 

we are happy to hear that your requirement has been achieved. Since generateQuery method is used for internal purposes only, So that we have not included documentation for that. We have used it to provide a workaround solution only. 

The generateQuery method is used to generate Query for Grid actions such as Paging, Grouping, filtering and  it accepts an optional Boolean value as a parameter, when it is set to true, it will generate the query without paging query. By default it will be false. 

Please get back to us, if you need further assistance. 

Regards, 
Manivel 



ML Marius Lian August 23, 2019 03:58 AM UTC

Hi Manivel,

Ok, thanks. 

The reason I wanted to look at the generateQuery was because I wanted to also check if I could only get the current selected columns.

I can explain:
  • Below you solved how to get the current filtered rows into a new grid.
  • But I also want to only transfer the current selected collumns to the new grid.
  • So for instance in the sample below, I might have only CustomerID visible using ColumnChooser.
  • Then when I create the new grid I only want to create the visible columns.
I guess in the "// creating a grid model" I only need to create the visible columns. 

So the question is: is there a way to know which columns are currently visible and then dynamically only create those columsn in the new grid?

Thanks,
Marius


MS Manivel Sellamuthu Syncfusion Team August 23, 2019 11:49 AM UTC

Hi Marius, 

Thanks for your update. 

we have validated your requirement. You can use getVisibleColumns method of the Grid to achieve your requirement. This method will return only the visible columns. Also we have modified the sample as per your requirement. 

Please find the below code example and sample for more information. 

App.vue 
export default { 
  data() { 
    return { 
      data: data, 
      grid: "", 
      toolbar: ["ColumnChooser"], 
      flag: true, 
      pageOption: { 
        pageSize: 3 
      }, 
      filterOptions: { 
        type: "Menu" 
      } 
    }; 
  }, 
  methods: { 
    Click: function(e) { 
      if (this.flag) { 
        Grid.Inject(Page); 
        this.grid = new Grid({ 
          allowPaging: true, 
          pageSettings: { pageSize: 3 } 
        }); 
 
        this.grid.appendTo("#Grid"); 
        this.flag = false; 
      } 
      let query = this.$refs.grid.ej2Instances.renderModule.data.generateQuery( 
        true 
      ); // get grid corresponding query by skipping page query 
      new DataManager({ json: data }) 
       .executeQuery(query) 
        .then(e => { 
          this.grid.dataSource = e.result; 
        }) 
        .catch(e => true); 
 
//creating grid dynamically with visible columns 
 
      this.grid.columns = this.$refs.grid.ej2Instances.getVisibleColumns(); 
    } 
  }, 
  provide: { 
    grid: [Filter, ColumnChooser, Toolbar, Page] 
  } 
}; 
</script> 




Please get back to us, if you need further assistance. 

Regards, 
Manivel 



ML Marius Lian August 27, 2019 11:54 AM UTC

Hi Manivel,

Thanks! How could I miss that method... 

Have a great day,
Marius


MS Manivel Sellamuthu Syncfusion Team August 27, 2019 01:53 PM UTC

Hi Marius, 

Thanks for your update. 

We hope that your requirement has been achieved. 

Please get back to us, if you need further assistance. 

Regards, 
Manivel 



ML Marius Lian August 31, 2019 01:28 AM UTC

Hi Again,

One thing only:
I don't understand this part:

Grid.Inject(Page); 

Why would you need to do that?

Thanks,
Marius


PS Pavithra Subramaniyam Syncfusion Team September 2, 2019 07:45 AM UTC

Hi Marius, 
 
In Essential JavaScript 2 Grid, we need to inject the feature modules before using a feature. For Vue DataGrid the modules can be injected through  “provide”.  As we rendered dynamic JavaScript Grid inside the button click event we need to inject the modules through “Inject” method. Please refer to the below documentation link for more information. 
 
 
Please get back to us if you need any further assistance on this. 
 
Regards, 
Pavithra S. 



ML Marius Lian September 2, 2019 05:39 PM UTC

Hi Pavithra,

Thanks for your response.

What is confusing is that in the code below "Page" is both injected through the "Provide" part and additinally through "Inject" method. 

I was assuming that "Page" would only need to be injected 1 time.

Does this mean that everytime a Syncfusion component is dynamically created in any method/event all dependent feature modules must be injected? So if I want to dynamically create a grid with paging, filtering, column chooser and a toolbar then I have to run this in the metod/event before creating the grid:
Grid.Inject(Page);
Grid.Inject(Filter);
Grid.Inject(ColumnChooser);
Grid.Inject(Toolbar);

Is that correct?

Thanks,
Marius


MS Manivel Sellamuthu Syncfusion Team September 3, 2019 12:55 PM UTC

Hi Marius, 

Thanks for your update. 

Yes. Since we are injecting modules for Vue framework using `Provide` option and JavaScript framework using `Inject` method, So when we creating grid dynamically(with JavaScript framework), we need to use Inject method too. 

Please get back to us, if you need further assistance. 

Regards, 
Manivel 



ML Marius Lian September 4, 2019 06:12 AM UTC

Hi Manivel,

Ahh, then I understand where this confusion comes from.

Actually when I asked about how to "Dynamically Create New Grid" I did not mean how to do this in "JavaScript framework". I meant how to do this in "Vue framework". 

So I see now that the solution in this thread probably isn't what I was after. I wonder how to dynamically create new grid in "Vue framework".

I guess this discussion is somewhat relevant:

Would it be possible for you to re-create the code-sample below but with the "Vue framework"?

Thanks,
Marius

Thanks,
Marius


PS Pavithra Subramaniyam Syncfusion Team September 9, 2019 03:51 AM UTC

Hi Marius, 

We suggest to use Vue Global Event Bus concept to achieve this requirement. By default this EventBus allows us to emit an event from one component and listen for that event in another component. So we can easily communicate with two Vue components by using this EventBus concept. In the below code we have showed how to use this concept to achieve your requirement 
 
[Vue] 
<template> 
  <div id="app"> 
    <button v-on:click="Click">Result</button> 
    <ejs-grid ref="grid"  :dataSource="data" :pageSettings="pageOption" :allowFiltering="true" allowPaging="true" > 
      <e-columns> 
       .   .  
      </e-columns> 
    </ejs-grid> 
    <h1>Dynamic Grid Binding</h1> 
    <GridChild1 
      msg="Child Grid1(child Vue Component) component rendering on App Component(Parent Vue component)" 
    /> 
  </div> 
</template> 
<script> 
.  .  .  
  methods: { 
    Click: function(e) { 
      let query = this.$refs.grid.ej2Instances.renderModule.data.generateQuery( 
        true 
      ); // get grid corresponding query by skipping page query 
      new DataManager({ json: data }) 
        .executeQuery(query) 
        .then(e => { 
          this.$eventHub.$emit("data", e.result); // emitted the event from child component 
        }) 
        .catch(e => true); 
   
 
}; 
</script> 


[Child] 
<template> 
  <div v-if="flag" id="gridchild1"> 
    <div>{{msg}}</div> 
    <ejs-grid ref="grid" :created="created" allowPaging="true" :pageSettings="pageOption"> 
      <e-columns> 
        .   .   .  
      </e-columns> 
    </ejs-grid> 
  </div> 
</template> 

<script> 
import Vue from "vue"; 
import { GridPlugin, Page } from "@syncfusion/ej2-vue-grids"; 

Vue.use(GridPlugin); 
export default { 
   
  data() { 
    this.$eventHub.$on("data", this.getTemplateValue); 
.   .  
  }, 
  methods: { 
    getTemplateValue: function(e) { 
      this.flag= "true"; 
      this.filterData = e; 
      if(this.$refs.grid){ 
        this.$refs.grid.ej2Instances.dataSource = this.filterData 
     
    }, 
    created:function(e){ 
this.$refs.grid.ej2Instances.dataSource = this.filterData 
   
 
}; 
</script> 



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

Regards, 
Pavithra S. 


Loader.
Live Chat Icon For mobile
Up arrow icon