Trying to generate IEditCells dynamically for Columns indside map() inside render()

Hi,

I want to generate different IEditCells in BatchEdit dynamically for each column inside a map(). The object contains the data for columns and the columns associated IEditCell data. 

Something like this:

<ColumnsDirective>
                                {columnsAndIEditCellsData.column.map((o=> {

                                    const editParamsIEditCell = {
                                        params: {
                                            actionComplete: () => false,
                                            allowFiltering: true,
                                            dataSource: new DataManager(
                                                // maps cell data
                                                this.getCellEditorParams(o)
                                            ),
                                           // fields: { text: "type", value: "id" },
                                            query: new Query()
                                        }
                                    };

                                    return (
                                        <ColumnDirective
                                            field={o.headerName}
                                            customAttributes={this.customAttributes}
                                            headerText={o.headerName}
                                            editType='dropdownedit'
                                            edit={editParams}
                                        />
                                    )
                                })}
                            </ColumnsDirective>


It only works if I generate the IEditCell in the class body first but not dynamically like in this case. Is there a solution to handle this issue in this way? 


5 Replies

PG Praveenkumar Gajendiran Syncfusion Team July 23, 2021 10:18 AM UTC

Hi Andreas,

Greetings from Syncfusion support,

We checked your query and provided information, based on that we could see that you want to change the dataSource and customize the editor dropdown component. For this, we suggest you to achieve your requirement by using “CellEditTemplate” feature of Grid using which you can customize your entire editor component. 
We have already discussed about the CellEditTemplate feature of Grid in our documentation section.  
Please refer the below documentation link for more information. 

Documentation: https://ej2.syncfusion.com/react/documentation/grid/edit/#cell-edit-template

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

regards,
Praveenkumar G 



AW Andreas Weber August 18, 2021 10:40 AM UTC

Hi,

thank you for your reply. It works fine for this issue!

Now I want to use the same case as the edit dialog. If I want to use these settings for this, I get this view(see screenshot). If there is only one cell with Dropdown in the grid it will be displayed correctly. It is clear to me that this function only generates a dropdown dynamically when row is clicked. Is there a way to correctly display several dynamic dropdowns in the dialog under these basic setting?

In this case three Dropdowns for "Column"-, "Row"- and "Target"-Columns should be shown correctly. 

The code below is used to generate the dynamic dropdowns.


    // batchEdit

    elemHTMLElement;
    batchEditObjectDropDownList;
    batchEditCellIEditCell = {
        create: () => {
            this.elem = document.createElement('input');
            return this.elem;
        },
        destroy: () => {
            this.batchEditObject.destroy();
        },
        read: () => {
            return this.batchEditObject.value;
        },
        write: (args: { rowDataobjectcolumnColumn }) => {
            const { gridRender_data } = this.state

            let dropDownData = null
            if (gridRender_data.options !== undefined) {
                gridRender_data.options.columnDefs.forEach(element => {
                    if (element.field === args.column.field && element.type === 'list') {
                        dropDownData = element.cellEditorParams.values
                    }
                });
            }
            this.batchEditObject = new DropDownList({
                floatLabelType: 'Never',
                dataSource: dropDownData
            });
            this.batchEditObject.appendTo(this.elem);
        }
    };

Attachment: DialogEdit_63e672f9.zip


MF Mohammed Farook J Syncfusion Team August 19, 2021 04:29 PM UTC

 Hi Andreas, 
 
We have validated your requirement and we found root cause of issue when append the template in same target element. So, the issue will be occurred.  
 
We have suggested the following way to render the same ‘cellEdit-template’ in different column. Please find the code example for your reference. 
 
export class BatchEdit extends SampleBase { 
. . . 
    this.toolbarOptions = ['Add''Delete''Update''Cancel']; 
    this.editSettings = { 
      allowEditing: true, 
      allowAdding: true, 
      allowDeleting: true, 
      mode: 'Dialog' 
    }; 
. . . 
  } 
  dropdownTempObj; 
  dropdownTemp = { 
    create: args => { 
      this.elem = document.createElement('input'); 
      this.elem.id = 'dropedit' + args.column.field; // generate unique id 
      return this.elem; 
    }, 
    destroy: () => { 
      this.dropdownTempObj.destroy(); 
    }, 
    read: () => { 
      return this.dropdownTempObj.value; 
    }, 
    write: args => { 
      this.dropdownTempObj = new DropDownList({ 
        dataSource: data, 
        fields: { text: args.column.fieldvalue: args.column.field }, // assign the value by using column.field 
 
        value: args.rowData[args.column.field] 
      }); 
 
      this.dropdownTempObj.appendTo(args.element); // we need to append unique element , so you can use args.element 
    } 
  }; 
  render() { 
    return ( 
. . . 
            <GridComponent 
              dataSource={data}   
              editSettings={this.editSettings} 
            > 
                <ColumnDirective 
                  field="CustomerName" 
                  headerText="Customer Name" 
                  width="150" 
                  validationRules={this.validationRule} 
                  edit={this.dropdownTemp} 
                /> 
 
                <ColumnDirective 
                  field="ShipCountry" 
                  headerText="Ship Country" 
                  width="150" 
                  edit={this.dropdownTemp} 
                /> 
              </ColumnsDirective> 
              <Inject services={[PageToolbarEdit]} /> 
            </GridComponent> 
. . . 
 
In the above code example, we have generated unique element by using ‘id’ attribute in ‘edit.create’ function and render the DropDownList by using ‘args.element’ in `edit.write` function. Please find the sample for your reference 
 
 
Please get back to us if you need further assistance. 
 
Regards, 
Praveen 
 
 
 



AW Andreas Weber August 20, 2021 11:38 AM UTC

Hi  Mohammed,

thank you for your detailed reply. In your Sample the "read"-function does not work correctly. If I change the values in more than one DropdownList it takes the latest changed value vor all columns. Can you give me further assistance for this issue please.

Thank you,

Regards



RS Rajapandiyan Settu Syncfusion Team August 23, 2021 09:53 AM UTC

Hi Andreas, 
 
We regret the inconvenience caused. 
 
Query: In your Sample the "read"-function does not work correctly. If I change the values in more than one DropdownList it takes the latest changed value vor all columns. 
 
You can resolve the reported problem by using following code example. 
 
 
[index.js] 
 
 
export class BatchEdit extends SampleBase { 
  ---- 
  editTempObj = []; 
  dropdownTemp = { 
    create: args => { 
      var elem = document.createElement('input'); 
      elem.id = 'dropedit' + args.column.field; 
      return elem; 
    }, 
    destroy: args => { 
      // destroy the custom input elements 
      this.editTempObj[0].ej2_instances[0].destroy(); 
      this.editTempObj.shift(); 
    }, 
    read: args => { 
      var value = args.ej2_instances[0].value; 
      this.editTempObj.push(args);  // store the custom input element in an array 
      return value;  // return the dropdown value from its args  
    }, 
    write: args => { 
      var dropdownTempObj = new DropDownList({ 
        dataSource: data, 
        fields: { text: args.column.fieldvalue: args.column.field }, 
        value: args.rowData[args.column.field] 
      }); 
 
      dropdownTempObj.appendTo(args.element); 
    } 
  }; 
  render() { 
    return ( 
      <div className="control-pane"> 
        <div className="control-section"> 
          <div className="col-md-9"> 
            <GridComponent 
              dataSource={data} 
              pageSettings={this.pageSettings} 
              toolbar={this.toolbarOptions} 
              allowPaging={true} 
              editSettings={this.editSettings} 
            > 
              <ColumnsDirective> 
               ---- 
                <ColumnDirective 
                  field="CustomerName" 
                  headerText="Customer Name" 
                  width="150" 
                  validationRules={this.validationRule} 
                  edit={this.dropdownTemp} 
                /> 
                <ColumnDirective 
                  field="ShipCountry" 
                  headerText="Ship Country" 
                  width="150" 
                  edit={this.dropdownTemp} 
                /> 
              </ColumnsDirective> 
              <Inject services={[PageToolbarEdit]} /> 
            </GridComponent> 
          </div> 
        </div> 
      </div> 
    ); 
  } 
} 
 
 
 
 
Please get back to us if you need further assistance with this. 
 
Regards, 
Rajapandiyan S 


Loader.
Up arrow icon