I need to display data as chips in react grid

Hi,


I really need to be able to display data as chips in one particular column of react data grid

Any help to achieve this would be really appreciated


Thank you

Eric


22 Replies

TS Thiyagu Subramani Syncfusion Team August 16, 2021 12:37 PM UTC

Hi Eric 

Greeting from Syncfusion support. 

We have achieved your requirement “Display data as chips in react grid” by using column.template feature in the Grid. Using this column template we have rendered the chips in Grid’s required column. Please refer the below code example and sample for more information. 

export class Default extends SampleBase { 
   . . . 
  chipTemplate (args) { 
    var shipCountry = args.ShipCountry.split(','); 
    if (args.ShipCountry) { 
            return (<ChipListComponent id="chip-avatar"> 
            <ChipsDirective> 
                {shipCountry.map((value, index) => { 
        return <ChipDirective key={index} cssClass={[this.countryData.find((e, index)=>{return e.Country === value}).Color.toLowerCase() + " " + "e-chips"]} text={value}></ChipDirective> 
      })} 
            </ChipsDirective> 
        </ChipListComponent>); 
  } 
  else { 
    return ''; 
  } 
  } 
  render() { 
    return ( 
      <div className="control-pane"> 
        <div className="control-section"> 
          <GridComponent 
           . .  
              <ColumnDirective 
                field="ShipCountry" 
                headerText="Ship Country" 
                edit={this.editparams} 
                template={this.chipTemplate.bind(this)} 
                width="150" 
              /> 
            </ColumnsDirective> 
            <Inject services={[EditToolbar]} /> 
          </GridComponent> 
        </div> 
      </div> 
    ); 
  } 
} 


 

Please let us know if you need further assistance. 

Regards, 
Thiyagu S


EO Eric Ouellette August 16, 2021 01:32 PM UTC

Hi Thiyagu,

Thank you for your reply, it almost answer my requirement except that I'm not using a multiSelect, I have an array coming from the dataSource for that column and I want to display all the items from the array of each row.

I hope you understand what I mean

Thank you 


Eric 



TS Thiyagu Subramani Syncfusion Team August 18, 2021 01:59 AM UTC

Hi Eric, 

Thanks for your update. 

Based on your shared information we have rendered chips control based on array values for each row without using multiselect. Using actionBegin event we have defined required array values to the shipCountry column based on updated value when args.requestType as save. Please refer to the below code and sample link for more reference. 

  chipTemplate(args) { 
    var shipCountry = args.ShipCountry; 
    if (args.ShipCountry) { 
      return ( 
        <ChipListComponent id="chip-avatar"> 
          <ChipsDirective> 
            {shipCountry.map((value, index) => { 
              return <ChipDirective key={index} text={value} />; 
            })} 
          </ChipsDirective> 
        </ChipListComponent> 
      ); 
    } else { 
      return ''; 
    } 
  } 
  actionBegin(args) { 
    if (args.requestType === 'save') { // we have defined required array value based on that modified shipCountry value 
      args.data.ShipCountry = args.data.ShipCountry.split(','); 
    } 
  } 



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

Regards, 
Thiyagu S 



EO Eric Ouellette August 19, 2021 01:08 PM UTC

Hi Thiyagu,

This solution solved my issue, thanks

but if I wanted to only display the 2 first items from the array and add a little tag displaying the amount of items not displaying, for example, if I have 5 items in the array, I want to display the 2 first items since the remaining of 5 minus 2 is 3, I want to display a little tag with a 3 on it.

I hope it makes sens the way I'm explaining it


Thank you


Eric



MS Manivel Sellamuthu Syncfusion Team August 20, 2021 10:38 AM UTC

Hi Eric, 
 
Thanks for your update. 
 
We are glad that the provided solution resolved your requirement. 
 
Query: I wanted to only display the 2 first items from the array and add a little tag displaying the amount of items not displaying, 
 
Based on your query you want to display the first 2 items from the array in ChipList and remaining number of items in a tag. We have modified the previous code example based on your requirement. Please refer the below code example and sample for more information. 
 
export class Default extends SampleBase { 
  data = [ 
    { 
      OrderID10248, 
      CustomerID'VINET', 
      ShipCountry: ['France''Germany'] 
    }, 
    { 
      OrderID10249, 
      CustomerID'TOMSP', 
      ShipCountry: ['Germany''Brazil''France'] 
    }, 
    { 
      OrderID10250, 
      CustomerID'HANAR', 
      ShipCountry: ['Brazil''Belgium'] 
    }, 
    { 
      OrderID10251, 
      CustomerID'VICTE', 
      ShipCountry: ['France''Switzerland'] 
    } 
  ]; 
  editOptions = { allowEditing: true, allowAdding: true, allowDeleting: true }; 
  toolbarOptions = ['Add''Edit''Delete''Update''Cancel']; 
  chipTemplate(args) { 
// here we have sliced the first two  items and stored in a variable 
    var shipCountry = args.ShipCountry.slice(0,2); 
    if (args.ShipCountry) { 
      return ( 
        <div> 
        <ChipListComponent id="chip-avatar"> 
          <ChipsDirective> 
            {shipCountry.map((value, index) => { 
              return <ChipDirective key={index} text={value} />; 
            })} 
          </ChipsDirective> 
        </ChipListComponent> 
//showing the count of remaining items in a button 
        <ButtonComponent cssClass='e-primary'>{args.ShipCountry.length>2 ? args.ShipCountry.length-20}</ButtonComponent> 
        </div> 
      ); 
    } else { 
      return ''; 
    } 
  } 
  actionBegin(args) { 
    if (args.requestType === 'save') { 
      args.data.ShipCountry = args.data.ShipCountry.split(','); 
    } 
  } 
  render() { 
    return ( 
      <div className="control-pane"> 
        <div className="control-section"> 
          <GridComponent 
            dataSource={this.data} 
            editSettings={this.editOptions} 
            toolbar={this.toolbarOptions} 
            actionBegin={this.actionBegin.bind(this)} 
           . . . 
              <ColumnDirective 
                field="ShipCountry" 
                headerText="Ship Country" 
                template={this.chipTemplate.bind(this)} 
                width="150" 
              /> 
            </ColumnsDirective> 
            <Inject services={[EditToolbar]} /> 
          </GridComponent> 
        </div> 
      </div> 
    ); 
  } 
} 
 
 
 
Please let us know if you need further assistance. 
 
Regards, 
Manivel 



EO Eric Ouellette August 20, 2021 05:23 PM UTC

Hi Manivel,


That is almost exactly what I wanted to achieve, except that I would like the tag with the number on the same line that the 2 chips not under.


Thank you 


Eric



EO Eric Ouellette August 20, 2021 07:42 PM UTC

Hi, 

I also have another issue, I'm using column commands to display a delete button in one of the columns and I didn't find a way to customize the delete confirmation message, any help would be appreciated.

Thank you


Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 23, 2021 11:17 AM UTC

Hi Eric, 

  Thanks  for your update. 

   Query 1: I would like the tag with the number on the same line that the 2 chips not under. 

       Based on your requirement you want to limit the number of chips in your column and add one more chip showing the remaining number of items on the list. You also want to display all the chips in the same line. 

      Your requirements can be achieved by slicing the array of data and add the number of remaining items in the list to the array of data. 

Please refer the below code example. 


    chipTemplate(args) { 
        // here we have sliced the first two  items and stored in a variable 
        var shipCountry = args.ShipCountry.slice(0, 2); 
        // if the length is more than 2 then we have added one more item to show how many items are more. 
        shipCountry = 
            args.ShipCountry.length > 2 
                ? shipCountry.concat((args.ShipCountry.length - 2).toString()) 
                : shipCountry; 
        if (args.ShipCountry) { 
            return ( 
                <div> 
                    <ChipListComponent id="chip-avatar" width="150px"> 
                        <ChipsDirective> 
                            {shipCountry.map((value, index) => { 
                                return <ChipDirective key={index} text={value} />; 
                            })} 
                        </ChipsDirective> 
                    </ChipListComponent> 
                </div> 
            ); 
        } else { 
            return ''; 
        } 
    } 




Query 2: I'm using column commands to display a delete button in one of the columns and I didn't find a way to customize the delete confirmation message. 

     Based on your requirement you are using a command column with a delete button, you want to customize the display text of the display confirmation dialog box. You can achieve your requirement using the `Globalization` feature in EJ2 Grid. 

    Please refer the below code example. 


L10n.load({ 
        'en-US': { 
            grid: { 
                ConfirmDelete: 'Click Ok to delete the record' 
            } 
        } 
    }); 


 

Please find the attached sample and revert for more queries regarding this. 

Regards, 
Joseph I. 



EO Eric Ouellette August 23, 2021 02:07 PM UTC

Hi Joseph,


Thank you for your reply it solved my first issue and part of my second issue as well but for the confirmation message, I would like to display the value of the first column (name) in the confirmation message for the row I'm deleting, for example if I want to delete the the first row and the name in the first column for that row is John Doe, I want to display a confirmation message as follow, "You're about to delete access for user: John Doe but if I want to delete another row with name Jane Austin, the confirmation message should display as follow, "You're about to delete access for user: Jane Austin


Thank you


Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 24, 2021 01:16 PM UTC

Hi Eric, 

   Thanks for your update. 

   Based on your requirement you are using a command column with a delete button, you want to customize the display text of the delete confirmation dialog box by adding the data on the row which is about to be deleted. 

   Your requirement can be achieved using the `commandClick` event of the EJ2 Grid and customize the `ConfirmDelete` option of the `defaultLocale` property of the EJ2 Grid. If you are using a delete button in the toolbar of the grid, we suggest you to do the same in the ` toolbarClick` event of the EJ2 Grid so that the confirmation message will be updated based on the selected row. 

Please refer the below code example. 


toolbarClick(args) { 
        if ( 
            args.item.text == 'Delete' && 
            args.item.id == this.grid.element.id + '_delete' 
        ) { 
            var selectedRecords = this.grid.getSelectedRecords(); 
            if (selectedRecords.length > 0) { 
                var customerId = selectedRecords[0].CustomerID; 
                this.grid.defaultLocale.ConfirmDelete = 
                    "You're about to delete access for user: " + customerId; 
            } 
        } 
    } 
 
    commandClick(args) { 
        this.grid.defaultLocale.ConfirmDelete = 
            "You're about to delete access for user: " + args.rowData.CustomerID; 
    } 



Please find the attached sample and revert for more queries regarding this. 

Regards, 
Joseph I. 



EO Eric Ouellette August 24, 2021 01:47 PM UTC

Hi Joseph,

Thank you very much, this is exactly what I needed, it completely solved my issue.

I have another issue maybe you can help me with, when I add a new row I want the trash button to automatically be added to it, I don't know if it's possible or not.


Thank you


Eric



EO Eric Ouellette August 24, 2021 02:38 PM UTC

Hi Joseph,

The issue with the trash button is resolved but I have another issue, I need the first column of the new row, which is the username column, to act as a search field, what I mean is for example, I add a new row and type the username of the user I want to add in the first column and if the user is in the database, it automatically fill the remaining columns or the row with the data.

I hope it makes sense the way I explained it

THank you

Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 25, 2021 10:32 AM UTC

Hi Eric, 

   Thanks for the update. 

   Based on your requirement when you add a new row to the EJ2 Grid, you want the first column to act as a search field. For example if you want to a row having a column user name as the first column, if you type the name of the user in the column you want to display the entire data of the user in the respective columns if the user name is already present in the dataSource. 

   Before proceeding to the solution we would like to ensure the following details so that we can provide a perfect solution ASAP. 

  • Do you want to display the details of other columns by checking the condition in your database while the grid is in edit mode?
  • Otherwise do you want to display the details of other columns while you save the row, i.e. do you want to display the details of other columns when you type the user name data only and click on the save button?
  • And finally we would like to bring this to your knowledge that by default there is a concept of  primary key based on which the CRUD actions are performed. The primary key should be a unique value for the CURD actions to be performed properly. In your case, is the userName column is set as primary key or do you have any other column in the grid set as primary key? Kindly confirm this.  

Please provide the above details and if you have any other queries please get back to us. 

Regards, 
Joseph I. 



EO Eric Ouellette August 25, 2021 01:48 PM UTC

Hi Joseph,

Thanks for your reply, to answer your questions, I want to display the details of other columns when I type the user name data only and press the enter key and I don't have any other columns set as Primary Key.


Thank you 


Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 26, 2021 06:00 PM UTC

Hi Eric, 

Thanks for the update. 

  By default in EJ2 Grid we perform all the CRUD actions based on the Primary Key column. It is important to define one of the column in your grid as a primary key column to perform the CRUD actions in the grid. So we suggest you to define any of the column in your sample as a primary key column. The primary key column should contain unique values and it must not have duplicate values. 

Please revert for more queries regarding this. 

Regards, 
Joseph I.  



EO Eric Ouellette August 26, 2021 06:41 PM UTC

Hi Joseph,

Thank you for your answer but it doesn't answer question as a remainder here what I need.

I need the first column of the new row, which is the username column, to act as a search field, what I mean is for example, I add a new row and type the username of the user I want to add in the first column and if the user is in the database, it automatically fill the remaining columns or the row with the data.

Is it possible to do it with Syncfusion EJ2 react Grid ??


Thank you 


Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 27, 2021 12:57 PM UTC

Hi Eric, 

  Thanks for your update. 

  In our previous update we have requested you to define any of the columns in the grid as primary key column, because we can perform CRUD actions in the grid only if there is a primary key column in the grid. 

  Based on your query, we can understand you want to add a new row in which when you type the username which is already present in the datasource and save it, you wanted to automatically fill other columns with the values of the user name already present in the dataSource. We need you to ensure is there a chance of the username field in your database contain duplicate values? If yes, then what value of the two records having the same usernames are you expect to be assigned to the newly added row? 

Please revert for more queries regarding this. 

Regards, 
Joseph I. 



EO Eric Ouellette August 27, 2021 01:00 PM UTC

Hi Joseph,


No there wont be any duplicate value for the username field.


Thank you 


Eric



JC Joseph Christ Nithin Issack Syncfusion Team August 30, 2021 11:42 AM UTC

Hi Eric, 

  Thanks for your update. 

  Based on your requirement when you add a new row to the EJ2 Grid, you want the first column to act as a search field. For example if you want to a row having a column user name as the first column, if you type the name of the user in the column you want to display the entire data of the user in the respective columns if the user name is already present in the dataSource.  

   We have considered your requirement as a custom sample. We will update further details on 1st September 2021. We appreciate your patience until then. 

Regards, 
Joseph I. 



JC Joseph Christ Nithin Issack Syncfusion Team September 1, 2021 06:40 PM UTC

Hi Eric, 

Thanks for your patience. 

  Based on your requirement when you add a new row to the EJ2 Grid, you want the first column to act as a search field. For example if you want to a row having a column user name as the first column, if you type the name of the user in the column you want to display the entire data of the user in the respective columns if the user name is already present in the dataSource. 

  Your requirement can be achieved by passing an AJAX request to the server in the `actionBegin` event of the EJ2 Grid. In the actionBegin event we have canceled the normal insert process and get the details of the row with the userName entered while adding the row and then add the result data by calling the `addRecord` method of the EJ2 Grid.  

Please refer the below code example. 


public onActionBegin(args) { 
        if (args.requestType === 'save') { 
            if (args.data.OrderID === undefined || args.data.OrderID === null) { 
                args.cancel = true; 
                var tempData = args.data; 
                (this as any).grid.showSpinner(); 
                var ajax = new Ajax(); 
                ajax.type = "POST" 
                ajax.url = "/Home/GetCustomerData" 
                var customerId = { CustomerID: args.data.CustomerID }; 
                ajax.data = JSON.stringify(customerId); 
                ajax.send(); 
                ajax.onSuccess = (result) => { 
                    var resultData = JSON.parse(result); 
                    if (resultData.IsSuccess) { 
                        tempData.OrderID = 10000 + resultData.Count + 1; 
                        tempData.EmployeeID = resultData.OrderList.EmployeeID; 
                        tempData.Freight = resultData.OrderList.Freight; 
                        tempData.OrderDate = resultData.OrderList.OrderDate; 
                        tempData.ShipCity = resultData.OrderList.ShipCity; 
                        (this as any).grid.addRecord(tempData); 
                    } 
 
                    (this as any).grid.hideSpinner(); 
                } 
            } 
        } 
    } 






Please find the attached sample and revert for more details. 

Regards, 
Joseph I. 



EO Eric Ouellette September 1, 2021 10:56 PM UTC

HI Joseph,

Thank you for your reply but there is only a tiny problem with your provided answer it is that I'm in React not in ASP.NET, can you translate it to React please ?


Thank you



JC Joseph Christ Nithin Issack Syncfusion Team September 2, 2021 04:44 PM UTC

Hi Eric, 

Thanks for your update. 

  Based on your requirement you want the solution provided previously completely in react and not in ASP .Net. In the previous update we have provided the logic for getting the row values when you enter the `CustomerID` column and press enter while adding a new row from the server side. You can use this logic in any of the services you are using. 

   In this case, in the `actionBegin` event of the grid we have checked for the `action` and `requestType` are `save` and `add` respectively and then we have canceled the default process for adding a new row by using `args.cancel`. Then we have activated the spinner for the grid using the `grid.showSpinner` method. After which we have send the request to the server side using AJAX request (here you can use any of the services you are using in your application). In the success event of the request you can get the data of the row and pass that as a parameter for the `addRecord` method and this will add a new row with the data passed to the grid. 

Please refer the code example below. 



    public onActionBegin(args) { 
        if (args.requestType === 'save' && args.action === 'add') { 
            if (args.data.OrderID === undefined || args.data.OrderID === null) { 
                args.cancel = true; // cancel the normal save process. 
                var tempData = args.data; // assign the data of the new row to a temp variable. 
                (this as any).grid.showSpinner(); // show the spinner to the grid. 
                var ajax = new Ajax(); 
                ajax.type = "POST" 
                ajax.url = "/Home/GetCustomerData" 
                var customerId = { CustomerID: args.data.CustomerID }; 
                ajax.data = JSON.stringify(customerId); 
                ajax.send(); // send a HTTP request to the server side. 
                ajax.onSuccess = (result) => { // in the success event of the request assign the values got from the server side to the tempdata. 
                    var resultData = JSON.parse(result); 
                    if (resultData.IsSuccess) { 
                        tempData.OrderID = 10000 + resultData.Count + 1; 
                        tempData.EmployeeID = resultData.OrderList.EmployeeID; 
                        tempData.Freight = resultData.OrderList.Freight; 
                        tempData.OrderDate = resultData.OrderList.OrderDate; 
                        tempData.ShipCity = resultData.OrderList.ShipCity; 
                        (this as any).grid.addRecord(tempData); // call the add record method and pass the tempdata to create a new row. 
                    } 
 
                    (this as any).grid.hideSpinner(); // hide the spinner from the grid. 
                } 
            } 
        } 
    } 




Please get back to us for further assistance on this. 

Regards, 
Joseph I. 


Loader.
Up arrow icon