syncfusion / flutter-widgets

Syncfusion Flutter widgets libraries include high quality UI widgets and file-format packages to help you create rich, high-quality applications for iOS, Android, and web from a single code base.
1.46k stars 680 forks source link

Flutter syncfusion DataGridview Force Cell on canSubmitCell #1144

Closed abdulrehmananwar closed 3 months ago

abdulrehmananwar commented 1 year ago

if user input value force to select valid value untill dont go to other cell. if he clear cell then he can go to next cell. please help how to achive this. image import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:collection/collection.dart'; import 'package:tag/widgets/search_grid.dart';

class MainGridPage extends StatefulWidget { const MainGridPage({Key? key}) : super(key: key); @override State createState() => _MainPageState(); }

class _MainPageState extends State { List firstgridflieds = []; List<Map<String,dynamic>> datalist1 = []; List<Map<String,dynamic>> datalist2 = []; @override void initState() { firstgridflieds = [ GridFields(FieldName: 'Name', InputType: 'search', ReadOnly: false), GridFields(FieldName: 'Quantity', InputType: 'number', ReadOnly: false), GridFields(FieldName: 'Price', InputType: 'decimal', ReadOnly: false), GridFields(FieldName: 'Amount', InputType: 'number', ReadOnly: true), ];

datalist1.add({"Name":'Name 1',"Quantity":10,"Price":5,"Amount":50});

// TODO: implement initState
super.initState();

}

@override Widget build(BuildContext context) { return Scaffold(body: SingleChildScrollView(child: DataGridView(gridfields:firstgridflieds,datalist: datalist1,),)

); } }

class DataGridView extends StatefulWidget { final List gridfields; final List<Map<String,dynamic>> datalist; const DataGridView({Key? key,required this.gridfields,required this.datalist}) : super(key: key);

@override State createState() => _DataGridViewState(); }

class _DataGridViewState extends State {

@override void dispose() { dataGridController.dispose(); // TODO: implement dispose super.dispose(); }

DataGridController dataGridController = new DataGridController(); late EmployeeDataSource _employeeDataSource; late CustomSelectionManager _customSelectionManager;

@override void initState() { super.initState();

_customSelectionManager = CustomSelectionManager(dataGridController);
_employeeDataSource = EmployeeDataSource(widget.datalist, widget.gridfields,context);
_employeeDataSource.addrow();

}

@override Widget build(BuildContext context) { return SfDataGrid( selectionMode: SelectionMode.single, navigationMode: GridNavigationMode.cell, editingGestureType: EditingGestureType.tap, selectionManager: _customSelectionManager, allowEditing: true, source: _employeeDataSource, controller: dataGridController, headerGridLinesVisibility: GridLinesVisibility.both, gridLinesVisibility: GridLinesVisibility.both, columns: List.generate( widget.gridfields.length, (i) => GridColumn( columnName: widget.gridfields[i].FieldName, label: Container( alignment: Alignment.centerLeft, child: Text(widget.gridfields[i].FieldName)))), ); } }

class EmployeeDataSource extends DataGridSource { EmployeeDataSource(this.EmpList, this.GridColumnList,this._context) { updateDataGridRows(); }

updateDataGridRows() async { dataGridRows = EmpList.map((e) => DataGridRow( cells: List.generate( GridColumnList.length, (i) => DataGridCell( columnName: GridColumnList[i].FieldName, value: e[GridColumnList[i].FieldName])))).toList(); }

BuildContext _context; List<Map<String, dynamic>> EmpList = []; List GridColumnList = []; List dataGridRows = [];

/// Helps to hold the new value of all editable widget. /// Based on the new value we will commit the new value into the corresponding /// [DataGridCell] on [onSubmitCell] method. dynamic newCellValue = null;

/// Help to control the editable text in [TextField] widget. TextEditingController editingController = TextEditingController();

@override List get rows => dataGridRows;

void addrow() { Map<String, dynamic> value = {}; EmpList.insert(EmpList.length, value);

updateDataGridRows();
notifyListeners();

}

@override Future onCellSubmit(DataGridRow dataGridRow, RowColumnIndex rowColumnIndex, GridColumn column) async{ final dynamic oldValue = dataGridRow .getCells() .firstWhereOrNull((DataGridCell dataGridCell) => dataGridCell.columnName == column.columnName) ?.value ?? '';

final int dataRowIndex = dataGridRows.indexOf(dataGridRow);

if (newCellValue == null || oldValue == newCellValue) {
  return;
} else {
  // if new value found

  // set new value to Map List Row
  EmpList[dataRowIndex][column.columnName] = newCellValue;

  // get current row value
  Map<String, dynamic> currentrowvalues = EmpList[dataRowIndex];

  // do calculation for other columns
  int quantity = 0;
  int price = 0;
  int amount = 0;
  quantity = int.tryParse(currentrowvalues.containsKey('Quantity')
      ? currentrowvalues['Quantity'].toString()
      : "0") ??
      0;
  price = int.tryParse(currentrowvalues.containsKey('Price')
      ? currentrowvalues['Price'].toString()
      : "0") ??
      0;
  amount = quantity * price;

  // set value to Amount Cell
  EmpList[dataRowIndex]["Amount"] = amount;
  // reset current row values after adding new cells
  currentrowvalues = EmpList[dataRowIndex];

  // now assign new row values to GridRow through loop over each field
  GridColumnList.asMap().forEach((index, value) {
    // set new value to grid row
    dataGridRows[dataRowIndex].getCells()[index] = DataGridCell<dynamic>(
        columnName: value.FieldName,
        value: currentrowvalues.containsKey(value.FieldName)
            ? currentrowvalues[value.FieldName]
            : null);

    //notify listner to refresh cells
    notifyDataSourceListeners(
        rowColumnIndex: RowColumnIndex(rowColumnIndex.rowIndex, index));
  });

  // if current row is last row then add new row
  if (rowColumnIndex.rowIndex + 1 == rows.length) {
    addrow();
  }
}

}

@override Future canSubmitCell(DataGridRow dataGridRow, RowColumnIndex rowColumnIndex, GridColumn column) async{ // TODO: implement canSubmitCell GridFields fieldmodel = GridColumnList.where( (element) => element.FieldName == column.columnName).single;

if(fieldmodel.InputType == "search" && newCellValue!=null)
  {
    // find value in base of input value from search dialog
    await dialogbox(rowColumnIndex);

  }

return super.canSubmitCell(dataGridRow, rowColumnIndex, column);

}

Future dialogbox(RowColumnIndex rowColumnIndex) async{

List<String> fruitlist = ["Apple","Orange","blueberry","banana"];
if(newCellValue.length>0)
  {
    fruitlist = fruitlist.where((food) => food.toLowerCase().contains(newCellValue)).toList();
    if (fruitlist.length==1)
      {
        newCellValue = fruitlist[0];
        return;
      }
  }

if (fruitlist.length>0) { showDialog( context: _context, builder: (context) { return AlertDialog( scrollable: true, shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.zero)), title: Container(width: 300, height: 300, child:

          ListView.builder(
            itemCount: fruitlist.length,
            itemBuilder: (context, i) {
              return
                ListTile(
                  title: Text(fruitlist[i].toString()),
                  onTap: (){
                    String value = fruitlist[i];
                    newCellValue = value;
                    Navigator.pop(context);
                  },
                );

            },
          )

          ));
    });

}

}

@override Widget? buildEditWidget(DataGridRow dataGridRow, RowColumnIndex rowColumnIndex, GridColumn column, CellSubmit submitCell) { // The new cell value must be reset. // To avoid committing the [DataGridCell] value that was previously edited // into the current non-modified [DataGridCell]. newCellValue = null;

// get current row values Map<String, dynamic> rowvalue = EmpList[rowColumnIndex.rowIndex]; // get current field model GridFields fieldmodel = GridColumnList.where( (element) => element.FieldName == column.columnName).single;

// extract cell value from current row and set to text field editingController.text = rowvalue.containsKey(column.columnName) ? rowvalue[column.columnName].toString() : ""; return TextField( autofocus: true, maxLines: 1, readOnly: fieldmodel.ReadOnly, controller: editingController, onChanged: (dynamic value) { if (value.isNotEmpty) { newCellValue = value; } }, decoration: InputDecoration( border: InputBorder.none, isDense: true, suffix: fieldmodel.InputType == "search"? ExcludeFocus( child:InkWell( child:Icon(Icons.search), onTap:()=>dialogbox(rowColumnIndex))):null)); }

@override DataGridRowAdapter buildRow(DataGridRow row) { return DataGridRowAdapter( cells: row.getCells().map((e) { return Text( e.value != null ? e.value.toString() : "", // style:Theme.of(_context).textTheme.bodyText1, ); }).toList()); } }

// create grid fields dynamically class GridFields { final String FieldName; final String InputType; final bool ReadOnly; GridFields( {required this.FieldName, required this.InputType, required this.ReadOnly});

factory GridFields.fromJson(Map<String, dynamic> json) { return GridFields( FieldName: json['FieldName'], InputType: json['InputType'], ReadOnly: json['InputType']); } }

class CustomSelectionManager extends RowSelectionManager { CustomSelectionManager(this.dataGridController); DataGridController dataGridController; bool istabPressed = false; @override Future handleKeyEvent(RawKeyEvent keyEvent) async{ istabPressed = true; if (keyEvent.logicalKey == LogicalKeyboardKey.tab) { super.handleKeyEvent(keyEvent); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { dataGridController.beginEdit(dataGridController.currentCell); });

  return;
}
super.handleKeyEvent(keyEvent);

} }

abdulrehmananwar commented 1 year ago

TextField on change event i set variable "cansubmit" value to true butt on canSubmitCell variable value changed. please resolve this issue grid_sample.zip

Tamilarasan-Paranthaman commented 1 year ago

Hi @abdulrehmananwar,

Thank you for sharing the sample. However, we are still unclear about the specific behavior you are looking for. Based on our analysis of the shared sample, the canSubmitCell method calls a dialog after a value is entered in the name column cell and another cell is selected. If the entered text value contains an item name in the 'fruitlist', the list of values is displayed, and the cell is committed with the selected value. Also, the cell is submitted with the entered value without opening a dialog when only one value is matched. If the value is not contained in the 'fruitlist', the list is empty, and the cell is committed with the typed value.

Could you please clarify if you would like to prevent cell submission when the value is not contained in the 'fruitlist'? Additionally, please confirm if the cell should only be submitted when the user types a correct value or cell is empty.

Regards, Tamilarasan

abdulrehmananwar commented 1 year ago

Requirement 1-is textfield is empty noting to happen 2- if textfield is not empty i want to search that value in list 3- filter list against text value 4- if filter list contains only one item copy that item to gridview row without open dialog 5- if filter list item not equal to one then open dialog with filter list which could be empty 6- user will choose value and that value will copy to gridview row 7- if textfield is not empty and cell value not equals to list value untill that user cannot move to any other column

Tamilarasan-Paranthaman commented 1 year ago

Hi @abdulrehmananwar,

Based on your requirement and the details you have provided, we have made the necessary modifications to your sample to meet your requirements and have attached it. In this modified sample, the cell is committed automatically without opening the dialog if only one value is available, while if multiple values are matched, the cell will be committed after the user chooses the desired value from the dialog. In the scenario where no values are matched, the cell will not be committed until the user types the correct value or leaves the cell empty. In canSubmitCell method, open the dialog when it’s not already opened. To allow focus on the dialog when it opens, the canSubmitCell method is called to check if the cell can be submitted. In the canSubmitCell method, the dialog is opened if it is not already open. Please refer to the attached sample and code snippet for a better understanding.

// A boolean variable that indicates whether a dialog is currently open or not.
  bool isDialogOpen = false;

  // A list of strings containing the names of different fruits.
  List<String> fruitlist = ["Apple", "Orange", "blueberry", "banana"];

  // List of search fruits that can be used to store and manipulate a collection of strings related to fruits.
  // This list can be modified at runtime as required.
  List<String> fruits = [];

  @override
  Future<bool> canSubmitCell(DataGridRow dataGridRow,
      RowColumnIndex rowColumnIndex, GridColumn column) async {
    GridFields fieldmodel = GridColumnList.where(
        (element) => element.FieldName == column.columnName).single;
    if (fieldmodel.InputType == "search" &&
        newCellValue != null &&
        newCellValue != '') {
      fruits = fruitlist
          .where((food) => food.toLowerCase().contains(newCellValue))
          .toList();

      // Check if a dialog is not already open and fruits list is not empty
      if (!isDialogOpen && fruits.isNotEmpty) {
        // Set isDialogOpen to true to indicate a dialog is being opened
        isDialogOpen = true;
        // Open the dialog box and wait for it to be dismissed
        await dialogbox(rowColumnIndex);
        // Set isDialogOpen to false to indicate the dialog has been closed
        isDialogOpen = false;
      } else if (isDialogOpen) {
        // To allow the focus to the Dialog box.
        return true;
      } else {
        // To avoid the cell submission when the typed value is not available in the list.
        return false;
      }
    }
    // return true to allow the cell submission for other column.
    return true;
  }

  Future<void> dialogbox(RowColumnIndex rowColumnIndex) async {
    if (newCellValue.length > 0) {
      if (fruits.length == 1) {
        newCellValue = fruits[0];
        return;
      }
    }

    // ignore: prefer_is_empty
    if (fruits.length > 0) {
      await showDialog(
          context: _context,
          builder: (context) {
            return AlertDialog(
                scrollable: true,
                shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.zero)),
                title: SizedBox(
                    width: 300,
                    height: 300,
                    child: ListView.builder(
                      itemCount: fruits.length,
                      itemBuilder: (context, i) {
                        return ListTile(
                          title: Text(fruits[i].toString()),
                          onTap: () async {
                            String value = fruits[i];
                            newCellValue = value;
                            Navigator.pop(context);
                          },
                        );
                      },
                    )));
          });
    }
  }

https://user-images.githubusercontent.com/93904422/228541005-a338dcc9-fafd-462d-91ad-56fc182e203f.mp4

sample.zip

abdulrehmananwar commented 1 year ago

thanks i was waiting for your reply its working fine. butt need something more i am creating multiple grids and want to reset and submit function requirement 1- on top reset button i want to clear all grids data. 2- on submit button i want to get all grid data expect last.

below is sample

class _MainPageState extends State { List firstgridflieds = []; Map<String, dynamic> datalists =new Map<String,dynamic>(); List listsnames = ['fruit','vegetables','animals'];

@override void initState() { firstgridflieds = [ GridFields(FieldName: 'Name', InputType: 'search', ReadOnly: false), GridFields(FieldName: 'Quantity', InputType: 'number', ReadOnly: false), GridFields(FieldName: 'Price', InputType: 'decimal', ReadOnly: false), GridFields(FieldName: 'Amount', InputType: 'number', ReadOnly: true), ]; super.initState(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Syncfusion DataGrid Demo')), body: SingleChildScrollView( child: Column(children: [ Row(children: [ MaterialButton( color: Colors.amber, child: Text('Reset'), onPressed: (){ datalists.clear(); setState(() {

            });
            }),
              MaterialButton(
                  color: Colors.green,
                  child: Text('Submit'),
                  onPressed: (){
                    print(datalists);

                  }),
            ],),
            ListView.builder(
                shrinkWrap: true,
                itemCount: listsnames.length,
                itemBuilder: (BuildContext context, int index) {

                  String listkey = listsnames[index].toString();

                  if(!datalists.containsKey(listsnames[index].toString()))
                  {
                    datalists[listkey]= [];
                  }
                  var gridlist = List<Map<String,dynamic>>.from(datalists[listkey]);
                  return
                    Container(
                      padding: EdgeInsets.all(20),
                      height: 200,child:
                    DataGridView(
                      gridfields: firstgridflieds,
                      datalist: gridlist),);
                })
          ],)

    ));

} }

abdulrehmananwar commented 1 year ago

One More issue in your sample code if user dismiss dialog without choose any value cell submitted with wrong value

abdulrehmananwar commented 1 year ago

waiting please update on last two issue

Tamilarasan-Paranthaman commented 1 year ago

@abdulrehmananwar,

Regarding: requirement 1- on top reset button I want to clear all grids data. 2- on submit button i want to get all grid data expect last.

Based on the requirements and sample you provided, it appears that you need to create three separate DataGridSource instances for the three DataGrids. With the appropriate instance for each grid, you can easily retrieve or clear the relevant data. We have made some modifications to the sample code to better align with your specifications. To review the changes, please refer to the provided sample and code snippet.

late EmployeeDataSource _employeeDataSource1;
late EmployeeDataSource _employeeDataSource2;
late EmployeeDataSource _employeeDataSource3;

class _MainPageState extends State {
  List<GridFields> firstgridflieds = [];
  Map<String, dynamic> datalists = <String, dynamic>{};
  List listsnames = ['fruit', 'vegetables', 'animals'];
  List<Map<String, dynamic>> gridlist = [];

  @override
  void initState() {
    firstgridflieds = [
      GridFields(FieldName: 'Name', InputType: 'search', ReadOnly: false),
      GridFields(FieldName: 'Quantity', InputType: 'number', ReadOnly: false),
      GridFields(FieldName: 'Price', InputType: 'decimal', ReadOnly: false),
      GridFields(FieldName: 'Amount', InputType: 'number', ReadOnly: true),
    ];
    super.initState();
    for (int index = 0; index < listsnames.length; index++) {
      String listkey = listsnames[index].toString();

      if (!datalists.containsKey(listsnames[index].toString())) {
        datalists[listkey] = [];
      }
      gridlist = List<Map<String, dynamic>>.from(datalists[listkey]);

      //Create the data source for the grids only once
      if (index == 0) {
        _employeeDataSource1 =
            EmployeeDataSource(gridlist, firstgridflieds, context);
      } else if (index == 1) {
        _employeeDataSource2 =
            EmployeeDataSource(gridlist, firstgridflieds, context);
      } else if (index == 2) {
        _employeeDataSource3 =
            EmployeeDataSource(gridlist, firstgridflieds, context);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: const Text('Syncfusion DataGrid Demo')),
        body: SingleChildScrollView(
            child: Column(
          children: [
            Row(
              children: [
                MaterialButton(
                    color: Colors.amber,
                    child: const Text('Reset'),
                    onPressed: () {
                      //Clear the values of the first grid
                      _employeeDataSource1.dataGridRows.clear();
                      _employeeDataSource1.EmpList.clear();
                      _employeeDataSource1.updateDataSource();

                      //Clear the values of the second grid
                      _employeeDataSource2.dataGridRows.clear();
                      _employeeDataSource2.EmpList.clear();
                      _employeeDataSource2.updateDataSource();

                      //Clear the values of the third grid
                      _employeeDataSource3.dataGridRows.clear();
                      _employeeDataSource3.EmpList.clear();
                      _employeeDataSource3.updateDataSource();

                      setState(() {});
                    }),
                MaterialButton(
                    color: Colors.green,
                    child: const Text('Submit'),
                    onPressed: () {
                      //Get the values of the first grid
                      for (var details in _employeeDataSource1.dataGridRows) {
                        print(details.getCells()[0].value);
                      }

                      //Get the values of the second grid
                      for (var details in _employeeDataSource2.dataGridRows) {
                        print(details.getCells()[0].value);
                      }
                    }),
              ],
            ),
            ListView.builder(
                shrinkWrap: true,
                itemCount: listsnames.length,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    padding: const EdgeInsets.all(20),
                    height: 200,
                    child: DataGridView(
                        gridfields: firstgridflieds,
                        datalist: gridlist,
                        source: index == 0
                            ? _employeeDataSource1
                            : index == 1
                                ? _employeeDataSource2
                                : _employeeDataSource3),
                  );
                })
          ],
        )));
  }
}

Regarding: One More issue in your sample code if user dismiss dialog without choose any value cell submitted with wrong value.

In our previous modification, we updated the sample to meet your specified requirements. If you also wish to prevent cell submission when a value is entered that is not selected from the dialog, you can return 'false' in that scenario as well. For a better understanding and more information, please refer to the following code snippet.

  @override
  Future<bool> canSubmitCell(DataGridRow dataGridRow,
      RowColumnIndex rowColumnIndex, GridColumn column) async {
    GridFields fieldmodel = GridColumnList.where(
        (element) => element.FieldName == column.columnName).single;
    if (fieldmodel.InputType == "search" &&
        newCellValue != null &&
        newCellValue != '') {
      fruits = fruitlist
          .where((food) => food.toLowerCase().contains(newCellValue))
          .toList();

      // Check if a dialog is not already open and fruits list is not empty
      if (!isDialogOpen && fruits.isNotEmpty) {
        // Set isDialogOpen to true to indicate a dialog is being opened
        isDialogOpen = true;
        // Open the dialog box and wait for it to be dismissed
        await dialogbox(rowColumnIndex);
        // Set isDialogOpen to false to indicate the dialog has been closed
        isDialogOpen = false;

        // Check if the new value is available in the list.
        // If not available means the value is not selected from the dialog box, 
       // then return false to avoid the cell submission.
        if (fruits.contains(newCellValue)) {
          return true;
        } else {
          return false;
        }
      } else if (isDialogOpen) {
        // To allow the focus to the Dialog box.
        return true;
      } else {
        // To avoid the cell submission when the typed value is not available in the list.
        return false;
      }
    }
    // return true to allow the cell submission for other column.
    return true;
  }

sample.zip

abdulrehmananwar commented 1 year ago

Dialog open up again on dismiss. if i dismiss dialog it open up again please resolve this

abdulrehmananwar commented 1 year ago

please resolve this matter thanks

Tamilarasan-Paranthaman commented 1 year ago

@abdulrehmananwar,

We are unable to determine the exact issue you are currently facing. We have reviewed your sample and requirements from previous queries and have tested the shared sample provided in our last response. Upon testing, we found that if the dialog is dismissed by tapping outside without selecting a value, it will not open again. Please refer to the output reference video provided below. If you are still experiencing issues, please provide additional details such as how you are closing the dialog and any other relevant information. Additionally, please review the sample we shared in our last response.

https://user-images.githubusercontent.com/93904422/232501917-fba7a686-c38b-491d-b31d-f97c36b297e9.mp4

abdulrehmananwar commented 1 year ago

sir please recheck as per your last sample code dialog open twice when i input text and press tab key dialog is opened when i click on side to dismiss firstly it dismissed and open up again so again i click side to dismiss then it dismiss fine.

https://user-images.githubusercontent.com/62530396/233308295-8c9432af-fe8f-413d-98b8-735713e26fa8.mp4

Tamilarasan-Paranthaman commented 1 year ago

@abdulrehmananwar,

Thank you for providing the details. We have observed that the dialog is opening when the tab key is pressed. However, it is working properly when the cell is tapped using the mouse. To avoid opening the popup twice, you can call the beginEdit method from the controller only when the current cell is not in edit mode. Please refer to the following code snippet for more information.

class CustomSelectionManager extends RowSelectionManager {
  CustomSelectionManager(this.dataGridController);
  DataGridController dataGridController;
  bool istabPressed = false;
  @override
  Future<void> handleKeyEvent(RawKeyEvent keyEvent) async {
    istabPressed = true;
    if (keyEvent.logicalKey == LogicalKeyboardKey.tab) {
      super.handleKeyEvent(keyEvent).then((value) =>
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {

            // Check if the current cell is in editing mode. 
            // If not, execute the code block inside the if statement.
            if (!dataGridController.isCurrentCellInEditing) { 
              await dataGridController
                  .beginEdit(dataGridController.currentCell);
            }
          }));

      return;
    }
    super.handleKeyEvent(keyEvent);
  }
}
abdulrehmananwar commented 1 year ago

Click on 2nd DataGrid and Input Value in Cell then click on fist DataGrid Search Cell Type Some Value press tabkey then Dialog will be open dismiss dialog and click in 2nd DataGrid Cell then against dialog will be open. till now its working perfect. now i click on first DataGrid Search Cell clear value by backspace key and press TabKey butt at this stage focus remain in search cell which should be move to the next cell similarly Focus also moving inside 2nd DataGrid by pressing tabkey.

one more thing now when i press tab key in 2nd DataGrid focus moving by cell beganedit not start by pressing tabkey

https://github.com/syncfusion/flutter-widgets/assets/62530396/c6694c8e-7952-4883-835c-4f0e3108ab46

abdulrehmananwar commented 1 year ago

please update on this

abdulrehmananwar commented 1 year ago

please update on it thanks

abdulrehmananwar commented 1 year ago

waiting for you please update on this

abdulrehmananwar commented 1 year ago

please reply on it thanks

Tamilarasan-Paranthaman commented 1 year ago

@abdulrehmananwar,

We will thoroughly investigate and verify the information provided. Once we have completed our validation process, we will promptly update the details and provide you with accurate information. Your patience and understanding are greatly appreciated.

abdulrehmananwar commented 9 months ago

waiting for it

Tamilarasan-Paranthaman commented 8 months ago

Based on your requirements, you've already implemented workarounds that initiate moving the next cell into edit mode within the post-framework callback. Additionally, you've devised custom logic to submit the cell using the canSubmitCell method.

In the context of DataGrid implementation, key navigation, including tapping and other key-related interactions, is typically initiated when the DataGrid has focus. In the provided videos, it's evident that focus was retained by the second DataGrid, and the dialog was simultaneously opened. Subsequently, you closed the dialogue and cleared the value in the first DataGrid cell, which was already in edit mode. Consequently, the focus remained on the second DataGrid, resulting in navigation actions taking place within the second DataGrid.

Given this workaround and logic, we recommend that you conclude the edit process for the cell before switching between DataGrids. This ensures a smoother and more intuitive navigation experience.

ashok-kuvaraja commented 3 months ago

Hi @abdulrehmananwar,

It appears that the workaround we've suggested may fulfill your needs. We are closing this issue. If you have any additional needs or questions, please don't hesitate to reopen it. We're here to support you.

Regards, Ashok K